diff --git a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs index 9fbbf4106e..ef5857de52 100644 --- a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs +++ b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs @@ -292,14 +292,10 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> { let res3 = self.or(res3, res4); self.or(res1, res3) } - other => { - let undef = self.undef(ret_ty); - self.zombie( - undef.def(self), - &format!("bswap not implemented for int width {other}"), - ); - undef - } + other => self.undef_zombie( + ret_ty, + &format!("bswap not implemented for int width {other}"), + ), }; // Cast back to the original signed type if necessary @@ -310,11 +306,7 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> { } } - sym::compare_bytes => { - let undef = self.undef(ret_ty); - self.zombie(undef.def(self), "memcmp not implemented"); - undef - } + sym::compare_bytes => self.undef_zombie(ret_ty, "memcmp not implemented"), _ => { // Call the fallback body instead of generating the intrinsic code @@ -397,12 +389,10 @@ impl Builder<'_, '_> { .unwrap() } _ => { - let undef = self.undef(ty).def(self); - self.zombie( - undef, + return self.undef_zombie( + ty, &format!("count_ones() on unsupported {ty:?} bit integer type"), ); - undef } } .with_type(u32) @@ -461,12 +451,10 @@ impl Builder<'_, '_> { .unwrap() } _ => { - let undef = self.undef(ty).def(self); - self.zombie( - undef, + return self.undef_zombie( + ty, &format!("bit_reverse() on unsupported {ty:?} bit integer type"), ); - undef } } .with_type(ty) @@ -491,13 +479,20 @@ impl Builder<'_, '_> { let u32 = SpirvType::Integer(32, false).def(self.span(), self); let glsl = self.ext_inst.borrow_mut().import_glsl(self); - let find_xsb = |arg| { + let find_xsb = |arg, offset: i32| { if trailing { - self.emit() + let lsb = self + .emit() .ext_inst(u32, None, glsl, GLOp::FindILsb as u32, [Operand::IdRef( arg, )]) - .unwrap() + .unwrap(); + if offset == 0 { + lsb + } else { + let const_offset = self.constant_i32(self.span(), offset).def(self); + self.emit().i_add(u32, None, const_offset, lsb).unwrap() + } } else { // rust is always unsigned, so FindUMsb let msb_bit = self @@ -508,25 +503,21 @@ impl Builder<'_, '_> { .unwrap(); // the glsl op returns the Msb bit, not the amount of leading zeros of this u32 // leading zeros = 31 - Msb bit - let u32_31 = self.constant_u32(self.span(), 31).def(self); - self.emit().i_sub(u32, None, u32_31, msb_bit).unwrap() + let const_offset = self.constant_i32(self.span(), 31 - offset).def(self); + self.emit().i_sub(u32, None, const_offset, msb_bit).unwrap() } }; let converted = match bits { 8 | 16 => { + let arg = self.emit().u_convert(u32, None, arg.def(self)).unwrap(); if trailing { - let arg = self.emit().u_convert(u32, None, arg.def(self)).unwrap(); - find_xsb(arg) + find_xsb(arg, 0) } else { - let arg = arg.def(self); - let arg = self.emit().u_convert(u32, None, arg).unwrap(); - let xsb = find_xsb(arg); - let subtrahend = self.constant_u32(self.span(), 32 - bits).def(self); - self.emit().i_sub(u32, None, xsb, subtrahend).unwrap() + find_xsb(arg, bits as i32 - 32) } } - 32 => find_xsb(arg.def(self)), + 32 => find_xsb(arg.def(self), 0), 64 => { let u32_0 = self.constant_int(u32, 0).def(self); let u32_32 = self.constant_u32(self.span(), 32).def(self); @@ -539,31 +530,26 @@ impl Builder<'_, '_> { .unwrap(); let higher = self.emit().u_convert(u32, None, higher).unwrap(); - let lower_bits = find_xsb(lower); - let higher_bits = find_xsb(higher); - if trailing { let use_lower = self.emit().i_equal(bool, None, higher, u32_0).unwrap(); - let lower_bits = - self.emit().i_add(u32, None, lower_bits, u32_32).unwrap(); + let lower_bits = find_xsb(lower, 32); + let higher_bits = find_xsb(higher, 0); self.emit() .select(u32, None, use_lower, lower_bits, higher_bits) .unwrap() } else { let use_higher = self.emit().i_equal(bool, None, lower, u32_0).unwrap(); - let higher_bits = - self.emit().i_add(u32, None, higher_bits, u32_32).unwrap(); + let lower_bits = find_xsb(lower, 0); + let higher_bits = find_xsb(higher, 32); self.emit() .select(u32, None, use_higher, higher_bits, lower_bits) .unwrap() } } _ => { - let undef = self.undef(ty).def(self); - self.zombie(undef, &format!( + return self.undef_zombie(ty, &format!( "count_leading_trailing_zeros() on unsupported {ty:?} bit integer type" )); - undef } }; diff --git a/crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs b/crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs index 54cb4e7584..9ac081d161 100644 --- a/crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs +++ b/crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs @@ -261,94 +261,58 @@ impl Builder<'_, '_> { self.sub(exp, one) } LibmIntrinsic::Custom(LibmCustomIntrinsic::Erf) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Erf not supported yet"); - undef + self.undef_zombie(result_type, "Erf not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Erfc) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Erfc not supported yet"); - undef + self.undef_zombie(result_type, "Erfc not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Fdim) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Fdim not supported yet"); - undef + self.undef_zombie(result_type, "Fdim not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Hypot) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Hypot not supported yet"); - undef + self.undef_zombie(result_type, "Hypot not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Ilogb) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Ilogb not supported yet"); - undef + self.undef_zombie(result_type, "Ilogb not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::J0) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "J0 not supported yet"); - undef + self.undef_zombie(result_type, "J0 not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Y0) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Y0 not supported yet"); - undef + self.undef_zombie(result_type, "Y0 not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::J1) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "J1 not supported yet"); - undef + self.undef_zombie(result_type, "J1 not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Y1) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Y1 not supported yet"); - undef + self.undef_zombie(result_type, "Y1 not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Jn) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Jn not supported yet"); - undef + self.undef_zombie(result_type, "Jn not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Yn) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Yn not supported yet"); - undef + self.undef_zombie(result_type, "Yn not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Lgamma) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Lgamma not supported yet"); - undef + self.undef_zombie(result_type, "Lgamma not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::LgammaR) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "LgammaR not supported yet"); - undef + self.undef_zombie(result_type, "LgammaR not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Tgamma) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Tgamma not supported yet"); - undef + self.undef_zombie(result_type, "Tgamma not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::NextAfter) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "NextAfter not supported yet"); - undef + self.undef_zombie(result_type, "NextAfter not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Remainder) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Remainder not supported yet"); - undef + self.undef_zombie(result_type, "Remainder not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::RemQuo) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "RemQuo not supported yet"); - undef + self.undef_zombie(result_type, "RemQuo not supported yet") } LibmIntrinsic::Custom(LibmCustomIntrinsic::Scalbn) => { - let undef = self.undef(result_type); - self.zombie(undef.def(self), "Scalbn not supported yet"); - undef + self.undef_zombie(result_type, "Scalbn not supported yet") } } } diff --git a/crates/rustc_codegen_spirv/src/builder/mod.rs b/crates/rustc_codegen_spirv/src/builder/mod.rs index 972432267e..044a9a13e6 100644 --- a/crates/rustc_codegen_spirv/src/builder/mod.rs +++ b/crates/rustc_codegen_spirv/src/builder/mod.rs @@ -60,6 +60,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + pub fn undef_zombie(&self, word: Word, reason: &str) -> SpirvValue { + if let Some(current_span) = self.current_span { + self.undef_zombie_with_span(word, current_span, reason) + } else { + self.undef_zombie_no_span(word, reason) + } + } + pub fn undef_zombie_with_span(&self, ty: Word, span: Span, reason: &str) -> SpirvValue { + let undef = self.undef(ty); + self.zombie_with_span(undef.def(self), span, reason); + undef + } + pub fn undef_zombie_no_span(&self, ty: Word, reason: &str) -> SpirvValue { + let undef = self.undef(ty); + self.zombie_no_span(undef.def(self), reason); + undef + } + pub fn validate_atomic(&self, ty: Word, to_zombie: Word) { if !self.i8_i16_atomics_allowed { match self.lookup_type(ty) { diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs index 162eb9dc8c..a53e1e0de6 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs @@ -54,7 +54,7 @@ impl<'tcx> CodegenCx<'tcx> { fn constant_int_from_native_signed(&self, span: Span, val: impl Into) -> SpirvValue { let size = Size::from_bytes(std::mem::size_of_val(&val)); - let ty = SpirvType::Integer(size.bits() as u32, false).def(span, self); + let ty = SpirvType::Integer(size.bits() as u32, true).def(span, self); self.constant_int(ty, val.into() as u128) }