Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undef zombie and some other code cleanups #221

Merged
merged 3 commits into from
Mar 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 30 additions & 44 deletions crates/rustc_codegen_spirv/src/builder/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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
}
};

Expand Down
72 changes: 18 additions & 54 deletions crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions crates/rustc_codegen_spirv/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_codegen_spirv/src/codegen_cx/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl<'tcx> CodegenCx<'tcx> {

fn constant_int_from_native_signed(&self, span: Span, val: impl Into<i128>) -> 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)
}

Expand Down