Skip to content

Commit 7526a78

Browse files
committed
Fix inverted conditions in count_(leading|trailing)_zeros for 64-bit integers
Selecting between lower and upper 32-bit parts were swapped.
1 parent e4375b1 commit 7526a78

File tree

5 files changed

+99
-142
lines changed

5 files changed

+99
-142
lines changed

crates/rustc_codegen_spirv/src/builder/intrinsics.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -531,18 +531,19 @@ impl Builder<'_, '_> {
531531
let higher = self.emit().u_convert(u32, None, higher).unwrap();
532532

533533
if trailing {
534-
let use_lower = self.emit().i_equal(bool, None, higher, u32_0).unwrap();
534+
let use_lower = self.emit().i_equal(bool, None, lower, u32_0).unwrap();
535535
let lower_bits = find_xsb(lower, 32);
536536
let higher_bits = find_xsb(higher, 0);
537537
self.emit()
538-
.select(u32, None, use_lower, lower_bits, higher_bits)
538+
.select(u32, None, use_lower, higher_bits, lower_bits)
539539
.unwrap()
540540
} else {
541-
let use_higher = self.emit().i_equal(bool, None, lower, u32_0).unwrap();
541+
let use_higher =
542+
self.emit().i_equal(bool, None, higher, u32_0).unwrap();
542543
let lower_bits = find_xsb(lower, 0);
543544
let higher_bits = find_xsb(higher, 32);
544545
self.emit()
545-
.select(u32, None, use_higher, higher_bits, lower_bits)
546+
.select(u32, None, use_higher, lower_bits, higher_bits)
546547
.unwrap()
547548
}
548549
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// build-pass
2+
3+
use spirv_std::spirv;
4+
5+
#[spirv(fragment)]
6+
pub fn main() {
7+
// 8-bit tests
8+
assert!(0b00000000_u8.leading_zeros() == 8);
9+
assert!(0b00000001_u8.leading_zeros() == 7);
10+
assert!(0b00010000_u8.leading_zeros() == 3);
11+
assert!(0b10000000_u8.leading_zeros() == 0);
12+
assert!(0b11111111_u8.leading_zeros() == 0);
13+
14+
// 16-bit tests
15+
assert!(0x0000_u16.leading_zeros() == 16);
16+
assert!(0x0001_u16.leading_zeros() == 15);
17+
assert!(0x0100_u16.leading_zeros() == 7);
18+
assert!(0x8000_u16.leading_zeros() == 0);
19+
assert!(0xFFFF_u16.leading_zeros() == 0);
20+
21+
// 32-bit tests
22+
assert!(0x00000000_u32.leading_zeros() == 32);
23+
assert!(0x00000001_u32.leading_zeros() == 31);
24+
assert!(0x00010000_u32.leading_zeros() == 15);
25+
assert!(0x80000000_u32.leading_zeros() == 0);
26+
assert!(0xFFFFFFFF_u32.leading_zeros() == 0);
27+
28+
// 64-bit tests
29+
assert!(0x0000000000000000_u64.leading_zeros() == 64);
30+
assert!(0x0000000000000001_u64.leading_zeros() == 63);
31+
assert!(0x8000000000000000_u64.leading_zeros() == 0);
32+
assert!(0xFFFFFFFFFFFFFFFF_u64.leading_zeros() == 0);
33+
assert!(0x00000000_12345678_u64.leading_zeros() == 32);
34+
assert!(0x00000000_80000000_u64.leading_zeros() == 32);
35+
assert!(0x00100000_00000000_u64.leading_zeros() == 11);
36+
assert!(0x12345678_00000000_u64.leading_zeros() == 3);
37+
38+
// Signed integers (should behave the same as unsigned)
39+
assert!(0i8.leading_zeros() == 8);
40+
assert!((-1i8).leading_zeros() == 0);
41+
assert!(0i16.leading_zeros() == 16);
42+
assert!((-1i16).leading_zeros() == 0);
43+
assert!(0i32.leading_zeros() == 32);
44+
assert!((-1i32).leading_zeros() == 0);
45+
assert!(0i64.leading_zeros() == 64);
46+
assert!((-1i64).leading_zeros() == 0);
47+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// build-pass
2+
3+
use spirv_std::spirv;
4+
5+
#[spirv(fragment)]
6+
pub fn main() {
7+
// 8-bit tests
8+
assert!(0b00000000_u8.trailing_zeros() == 8);
9+
assert!(0b00000001_u8.trailing_zeros() == 0);
10+
assert!(0b00010000_u8.trailing_zeros() == 4);
11+
assert!(0b10000000_u8.trailing_zeros() == 7);
12+
assert!(0b11111110_u8.trailing_zeros() == 1);
13+
14+
// 16-bit tests
15+
assert!(0x0000_u16.trailing_zeros() == 16);
16+
assert!(0x0001_u16.trailing_zeros() == 0);
17+
assert!(0x0100_u16.trailing_zeros() == 8);
18+
assert!(0x8000_u16.trailing_zeros() == 15);
19+
assert!(0xFFFE_u16.trailing_zeros() == 1);
20+
21+
// 32-bit tests
22+
assert!(0x00000000_u32.trailing_zeros() == 32);
23+
assert!(0x00000001_u32.trailing_zeros() == 0);
24+
assert!(0x00010000_u32.trailing_zeros() == 16);
25+
assert!(0x80000000_u32.trailing_zeros() == 31);
26+
assert!(0xFFFFFFFE_u32.trailing_zeros() == 1);
27+
28+
// 64-bit tests
29+
assert!(0x0000000000000000_u64.trailing_zeros() == 64);
30+
assert!(0x0000000000000001_u64.trailing_zeros() == 0);
31+
assert!(0x8000000000000000_u64.trailing_zeros() == 63);
32+
assert!(0xFFFFFFFFFFFFFFFE_u64.trailing_zeros() == 1);
33+
assert!(0x12340000_00000000_u64.trailing_zeros() == 32);
34+
assert!(0x00000001_00000000_u64.trailing_zeros() == 32);
35+
assert!(0x00000000_00001000_u64.trailing_zeros() == 12);
36+
assert!(0x00000000_80000000_u64.trailing_zeros() == 31);
37+
38+
// Signed integers (should behave the same as unsigned)
39+
assert!(0i8.trailing_zeros() == 8);
40+
assert!((-1i8).trailing_zeros() == 0);
41+
assert!(0i16.trailing_zeros() == 16);
42+
assert!((-1i16).trailing_zeros() == 0);
43+
assert!(0i32.trailing_zeros() == 32);
44+
assert!((-1i32).trailing_zeros() == 0);
45+
assert!(0i64.trailing_zeros() == 64);
46+
assert!((-1i64).trailing_zeros() == 0);
47+
}

tests/ui/lang/u32/leading_zeros.rs

Lines changed: 0 additions & 69 deletions
This file was deleted.

tests/ui/lang/u32/trailing_zeros.rs

Lines changed: 0 additions & 69 deletions
This file was deleted.

0 commit comments

Comments
 (0)