mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-22 06:45:13 +00:00
Fail unimplemented intrinsics instead of incorrect behavior (#114)
This commit is contained in:
parent
3f5244dd3e
commit
9dc6c61c4c
@ -547,9 +547,12 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
simple_op! {fmul, f_mul}
|
||||
simple_op! {fmul_fast, f_mul} // fast=normal
|
||||
simple_op! {udiv, u_div}
|
||||
simple_op! {exactudiv, u_div} // ignore
|
||||
// Note: exactudiv is UB when there's a remainder, so it's valid to implement as a normal div.
|
||||
// TODO: Can we take advantage of the UB and emit something else?
|
||||
simple_op! {exactudiv, u_div}
|
||||
simple_op! {sdiv, s_div}
|
||||
simple_op! {exactsdiv, s_div} // ignore
|
||||
// Same note and TODO as exactudiv
|
||||
simple_op! {exactsdiv, s_div}
|
||||
simple_op! {fdiv, f_div}
|
||||
simple_op! {fdiv_fast, f_div} // fast=normal
|
||||
simple_op! {urem, u_mod}
|
||||
@ -636,11 +639,20 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
rhs: Self::Value,
|
||||
) -> (Self::Value, Self::Value) {
|
||||
let fals = self.constant_bool(false);
|
||||
match oop {
|
||||
let result = match oop {
|
||||
OverflowOp::Add => (self.add(lhs, rhs), fals),
|
||||
OverflowOp::Sub => (self.sub(lhs, rhs), fals),
|
||||
OverflowOp::Mul => (self.mul(lhs, rhs), fals),
|
||||
}
|
||||
};
|
||||
self.zombie(
|
||||
result.1.def,
|
||||
match oop {
|
||||
OverflowOp::Add => "checked add is not supported yet",
|
||||
OverflowOp::Sub => "checked sub is not supported yet",
|
||||
OverflowOp::Mul => "checked mul is not supported yet",
|
||||
},
|
||||
);
|
||||
result
|
||||
}
|
||||
|
||||
fn from_immediate(&mut self, val: Self::Value) -> Self::Value {
|
||||
@ -698,11 +710,13 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value {
|
||||
self.alloca(ty, align)
|
||||
let result = self.alloca(ty, align);
|
||||
self.err("dynamic alloca is not supported yet");
|
||||
result
|
||||
}
|
||||
|
||||
fn array_alloca(&mut self, _ty: Self::Type, _len: Self::Value, _align: Align) -> Self::Value {
|
||||
self.fatal("TODO: array_alloca not supported yet")
|
||||
self.fatal("array alloca not supported yet")
|
||||
}
|
||||
|
||||
fn load(&mut self, ptr: Self::Value, _align: Align) -> Self::Value {
|
||||
@ -727,8 +741,10 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn volatile_load(&mut self, ptr: Self::Value) -> Self::Value {
|
||||
// TODO: Can we do something here?
|
||||
self.load(ptr, Align::from_bytes(0).unwrap())
|
||||
// TODO: Implement this
|
||||
let result = self.load(ptr, Align::from_bytes(0).unwrap());
|
||||
self.zombie(result.def, "volatile load is not supported yet");
|
||||
result
|
||||
}
|
||||
|
||||
fn atomic_load(&mut self, ptr: Self::Value, order: AtomicOrdering, _size: Size) -> Self::Value {
|
||||
@ -818,36 +834,6 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
self
|
||||
/*
|
||||
let zero = self.const_usize(0);
|
||||
let count = self.const_usize(count);
|
||||
let start = dest.project_index(&mut self, zero).llval;
|
||||
let end = dest.project_index(&mut self, count).llval;
|
||||
|
||||
let mut header_bx = self.build_sibling_block("repeat_loop_header");
|
||||
let mut body_bx = self.build_sibling_block("repeat_loop_body");
|
||||
let next_bx = self.build_sibling_block("repeat_loop_next");
|
||||
|
||||
self.br(header_bx.llbb());
|
||||
let current = header_bx.phi(start.ty, &[start], &[self.llbb()]);
|
||||
|
||||
let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end);
|
||||
header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());
|
||||
|
||||
let align = dest
|
||||
.align
|
||||
.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
|
||||
cg_elem.val.store(
|
||||
&mut body_bx,
|
||||
PlaceRef::new_sized_aligned(current, cg_elem.layout, align),
|
||||
);
|
||||
|
||||
let next = body_bx.inbounds_gep(current, &[self.const_usize(1)]);
|
||||
body_bx.br(header_bx.llbb());
|
||||
header_bx.add_incoming_to_phi(current, next, body_bx.llbb());
|
||||
|
||||
next_bx
|
||||
*/
|
||||
}
|
||||
|
||||
fn range_metadata(&mut self, _load: Self::Value, _range: Range<u128>) {
|
||||
@ -879,8 +865,14 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
val: Self::Value,
|
||||
ptr: Self::Value,
|
||||
align: Align,
|
||||
_flags: MemFlags,
|
||||
flags: MemFlags,
|
||||
) -> Self::Value {
|
||||
if flags != MemFlags::empty() {
|
||||
self.err(&format!(
|
||||
"store_with_flags is not supported yet: {:?}",
|
||||
flags
|
||||
));
|
||||
}
|
||||
self.store(val, ptr, align)
|
||||
}
|
||||
|
||||
@ -1369,8 +1361,14 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
src: Self::Value,
|
||||
_src_align: Align,
|
||||
size: Self::Value,
|
||||
_flags: MemFlags,
|
||||
flags: MemFlags,
|
||||
) {
|
||||
if flags != MemFlags::empty() {
|
||||
self.err(&format!(
|
||||
"memcpy with mem flags is not supported yet: {:?}",
|
||||
flags
|
||||
));
|
||||
}
|
||||
let const_size = self.builder.lookup_const_u64(size);
|
||||
if const_size == Some(0) {
|
||||
// Nothing to do!
|
||||
@ -1417,8 +1415,14 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
fill_byte: Self::Value,
|
||||
size: Self::Value,
|
||||
_align: Align,
|
||||
_flags: MemFlags,
|
||||
flags: MemFlags,
|
||||
) {
|
||||
if flags != MemFlags::empty() {
|
||||
self.err(&format!(
|
||||
"memset with mem flags is not supported yet: {:?}",
|
||||
flags
|
||||
));
|
||||
}
|
||||
let elem_ty = match self.lookup_type(ptr.ty) {
|
||||
SpirvType::Pointer { pointee, .. } => pointee,
|
||||
_ => self.fatal(&format!(
|
||||
|
@ -87,23 +87,35 @@ impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> {
|
||||
|
||||
sym::saturating_add => {
|
||||
assert_eq!(arg_tys[0], arg_tys[1]);
|
||||
match &arg_tys[0].kind() {
|
||||
let result = match &arg_tys[0].kind() {
|
||||
TyKind::Int(_) | TyKind::Uint(_) => {
|
||||
self.add(args[0].immediate(), args[1].immediate())
|
||||
}
|
||||
TyKind::Float(_) => self.fadd(args[0].immediate(), args[1].immediate()),
|
||||
other => self.fatal(&format!("Unimplemented intrinsic type: {:#?}", other)),
|
||||
}
|
||||
other => self.fatal(&format!(
|
||||
"Unimplemented saturating_add intrinsic type: {:#?}",
|
||||
other
|
||||
)),
|
||||
};
|
||||
// TODO: Implement this
|
||||
self.zombie(result.def, "saturating_add is not implemented yet");
|
||||
result
|
||||
}
|
||||
sym::saturating_sub => {
|
||||
assert_eq!(arg_tys[0], arg_tys[1]);
|
||||
match &arg_tys[0].kind() {
|
||||
let result = match &arg_tys[0].kind() {
|
||||
TyKind::Int(_) | TyKind::Uint(_) => {
|
||||
self.sub(args[0].immediate(), args[1].immediate())
|
||||
}
|
||||
TyKind::Float(_) => self.fsub(args[0].immediate(), args[1].immediate()),
|
||||
other => self.fatal(&format!("Unimplemented intrinsic type: {:#?}", other)),
|
||||
}
|
||||
other => self.fatal(&format!(
|
||||
"Unimplemented saturating_sub intrinsic type: {:#?}",
|
||||
other
|
||||
)),
|
||||
};
|
||||
// TODO: Implement this
|
||||
self.zombie(result.def, "saturating_sub is not implemented yet");
|
||||
result
|
||||
}
|
||||
|
||||
// TODO: Configure these to be ocl vs. gl ext instructions, etc.
|
||||
|
@ -71,6 +71,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
self.tcx.sess.struct_err(msg)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn err(&self, msg: &str) {
|
||||
if let Some(current_span) = self.current_span {
|
||||
@ -79,7 +80,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
self.tcx.sess.err(msg)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn fatal(&self, msg: &str) -> ! {
|
||||
if let Some(current_span) = self.current_span {
|
||||
@ -347,7 +347,8 @@ impl<'a, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'tcx> {
|
||||
_inputs: Vec<Self::Value>,
|
||||
_span: Span,
|
||||
) -> bool {
|
||||
todo!()
|
||||
self.err("LLVM asm not supported");
|
||||
true
|
||||
}
|
||||
|
||||
fn codegen_inline_asm(
|
||||
@ -357,7 +358,7 @@ impl<'a, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'tcx> {
|
||||
_options: InlineAsmOptions,
|
||||
_line_spans: &[Span],
|
||||
) {
|
||||
todo!()
|
||||
self.err("asm not supported")
|
||||
}
|
||||
}
|
||||
impl<'a, 'tcx> StaticBuilderMethods for Builder<'a, 'tcx> {
|
||||
|
Loading…
Reference in New Issue
Block a user