diff --git a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs index ef5857de52..5b4d3680af 100644 --- a/crates/rustc_codegen_spirv/src/builder/intrinsics.rs +++ b/crates/rustc_codegen_spirv/src/builder/intrinsics.rs @@ -531,18 +531,19 @@ impl Builder<'_, '_> { let higher = self.emit().u_convert(u32, None, higher).unwrap(); if trailing { - let use_lower = self.emit().i_equal(bool, None, higher, u32_0).unwrap(); + let use_lower = self.emit().i_equal(bool, None, lower, u32_0).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) + .select(u32, None, use_lower, higher_bits, lower_bits) .unwrap() } else { - let use_higher = self.emit().i_equal(bool, None, lower, u32_0).unwrap(); + let use_higher = + self.emit().i_equal(bool, None, higher, u32_0).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) + .select(u32, None, use_higher, lower_bits, higher_bits) .unwrap() } } diff --git a/tests/ui/lang/core/intrinsics/leading_zeros.rs b/tests/ui/lang/core/intrinsics/leading_zeros.rs new file mode 100644 index 0000000000..d0009ffd1c --- /dev/null +++ b/tests/ui/lang/core/intrinsics/leading_zeros.rs @@ -0,0 +1,47 @@ +// build-pass + +use spirv_std::spirv; + +#[spirv(fragment)] +pub fn main() { + // 8-bit tests + assert!(0b00000000_u8.leading_zeros() == 8); + assert!(0b00000001_u8.leading_zeros() == 7); + assert!(0b00010000_u8.leading_zeros() == 3); + assert!(0b10000000_u8.leading_zeros() == 0); + assert!(0b11111111_u8.leading_zeros() == 0); + + // 16-bit tests + assert!(0x0000_u16.leading_zeros() == 16); + assert!(0x0001_u16.leading_zeros() == 15); + assert!(0x0100_u16.leading_zeros() == 7); + assert!(0x8000_u16.leading_zeros() == 0); + assert!(0xFFFF_u16.leading_zeros() == 0); + + // 32-bit tests + assert!(0x00000000_u32.leading_zeros() == 32); + assert!(0x00000001_u32.leading_zeros() == 31); + assert!(0x00010000_u32.leading_zeros() == 15); + assert!(0x80000000_u32.leading_zeros() == 0); + assert!(0xFFFFFFFF_u32.leading_zeros() == 0); + + // 64-bit tests + assert!(0x0000000000000000_u64.leading_zeros() == 64); + assert!(0x0000000000000001_u64.leading_zeros() == 63); + assert!(0x8000000000000000_u64.leading_zeros() == 0); + assert!(0xFFFFFFFFFFFFFFFF_u64.leading_zeros() == 0); + assert!(0x00000000_12345678_u64.leading_zeros() == 32); + assert!(0x00000000_80000000_u64.leading_zeros() == 32); + assert!(0x00100000_00000000_u64.leading_zeros() == 11); + assert!(0x12345678_00000000_u64.leading_zeros() == 3); + + // Signed integers (should behave the same as unsigned) + assert!(0i8.leading_zeros() == 8); + assert!((-1i8).leading_zeros() == 0); + assert!(0i16.leading_zeros() == 16); + assert!((-1i16).leading_zeros() == 0); + assert!(0i32.leading_zeros() == 32); + assert!((-1i32).leading_zeros() == 0); + assert!(0i64.leading_zeros() == 64); + assert!((-1i64).leading_zeros() == 0); +} diff --git a/tests/ui/lang/core/intrinsics/trailing_zeros.rs b/tests/ui/lang/core/intrinsics/trailing_zeros.rs new file mode 100644 index 0000000000..a5de0cf946 --- /dev/null +++ b/tests/ui/lang/core/intrinsics/trailing_zeros.rs @@ -0,0 +1,47 @@ +// build-pass + +use spirv_std::spirv; + +#[spirv(fragment)] +pub fn main() { + // 8-bit tests + assert!(0b00000000_u8.trailing_zeros() == 8); + assert!(0b00000001_u8.trailing_zeros() == 0); + assert!(0b00010000_u8.trailing_zeros() == 4); + assert!(0b10000000_u8.trailing_zeros() == 7); + assert!(0b11111110_u8.trailing_zeros() == 1); + + // 16-bit tests + assert!(0x0000_u16.trailing_zeros() == 16); + assert!(0x0001_u16.trailing_zeros() == 0); + assert!(0x0100_u16.trailing_zeros() == 8); + assert!(0x8000_u16.trailing_zeros() == 15); + assert!(0xFFFE_u16.trailing_zeros() == 1); + + // 32-bit tests + assert!(0x00000000_u32.trailing_zeros() == 32); + assert!(0x00000001_u32.trailing_zeros() == 0); + assert!(0x00010000_u32.trailing_zeros() == 16); + assert!(0x80000000_u32.trailing_zeros() == 31); + assert!(0xFFFFFFFE_u32.trailing_zeros() == 1); + + // 64-bit tests + assert!(0x0000000000000000_u64.trailing_zeros() == 64); + assert!(0x0000000000000001_u64.trailing_zeros() == 0); + assert!(0x8000000000000000_u64.trailing_zeros() == 63); + assert!(0xFFFFFFFFFFFFFFFE_u64.trailing_zeros() == 1); + assert!(0x12340000_00000000_u64.trailing_zeros() == 32); + assert!(0x00000001_00000000_u64.trailing_zeros() == 32); + assert!(0x00000000_00001000_u64.trailing_zeros() == 12); + assert!(0x00000000_80000000_u64.trailing_zeros() == 31); + + // Signed integers (should behave the same as unsigned) + assert!(0i8.trailing_zeros() == 8); + assert!((-1i8).trailing_zeros() == 0); + assert!(0i16.trailing_zeros() == 16); + assert!((-1i16).trailing_zeros() == 0); + assert!(0i32.trailing_zeros() == 32); + assert!((-1i32).trailing_zeros() == 0); + assert!(0i64.trailing_zeros() == 64); + assert!((-1i64).trailing_zeros() == 0); +} diff --git a/tests/ui/lang/u32/leading_zeros.rs b/tests/ui/lang/u32/leading_zeros.rs deleted file mode 100644 index d157dfe73f..0000000000 --- a/tests/ui/lang/u32/leading_zeros.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Test all trailing and leading zeros. No need to test ones, they just call the zero variant with !value - -// build-pass - -use spirv_std::spirv; - -#[spirv(fragment)] -pub fn leading_zeros_u8( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &u8, - out: &mut u32, -) { - *out = u8::leading_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn leading_zeros_u16( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &u16, - out: &mut u32, -) { - *out = u16::leading_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn leading_zeros_u32( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &u32, - out: &mut u32, -) { - *out = u32::leading_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn leading_zeros_u64( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &u64, - out: &mut u32, -) { - *out = u64::leading_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn leading_zeros_i8( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &i8, - out: &mut u32, -) { - *out = i8::leading_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn leading_zeros_i16( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &i16, - out: &mut u32, -) { - *out = i16::leading_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn leading_zeros_i32( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &i32, - out: &mut u32, -) { - *out = i32::leading_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn leading_zeros_i64( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &i64, - out: &mut u32, -) { - *out = i64::leading_zeros(*buffer); -} diff --git a/tests/ui/lang/u32/trailing_zeros.rs b/tests/ui/lang/u32/trailing_zeros.rs deleted file mode 100644 index 314d60d323..0000000000 --- a/tests/ui/lang/u32/trailing_zeros.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Test all trailing and leading zeros. No need to test ones, they just call the zero variant with !value - -// build-pass - -use spirv_std::spirv; - -#[spirv(fragment)] -pub fn trailing_zeros_u8( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &u8, - out: &mut u32, -) { - *out = u8::trailing_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn trailing_zeros_u16( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &u16, - out: &mut u32, -) { - *out = u16::trailing_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn trailing_zeros_u32( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &u32, - out: &mut u32, -) { - *out = u32::trailing_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn trailing_zeros_u64( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &u64, - out: &mut u32, -) { - *out = u64::trailing_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn trailing_zeros_i8( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &i8, - out: &mut u32, -) { - *out = i8::trailing_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn trailing_zeros_i16( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &i16, - out: &mut u32, -) { - *out = i16::trailing_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn trailing_zeros_i32( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &i32, - out: &mut u32, -) { - *out = i32::trailing_zeros(*buffer); -} - -#[spirv(fragment)] -pub fn trailing_zeros_i64( - #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &i64, - out: &mut u32, -) { - *out = i64::trailing_zeros(*buffer); -}