Skip to content

Commit 07bb9ce

Browse files
committed
Add optimizations for leading / trailing zeros
1 parent 3a13642 commit 07bb9ce

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

cranelift/codegen/src/isle_prelude.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ macro_rules! isle_common_prelude_methods {
2727
self.checked_add_with_type(ty, a, b).is_none()
2828
}
2929

30+
#[inline]
31+
fn imm64_clz(&mut self, ty: Type, a: Imm64) -> Imm64 {
32+
let bits = ty.bits();
33+
assert!(bits <= 64);
34+
let clz_offset = 64 - bits;
35+
let a_v: u64 = a.bits().cast_unsigned();
36+
let lz = a_v.leading_zeros() - clz_offset;
37+
Imm64::new(lz as i64)
38+
}
39+
3040
#[inline]
3141
fn imm64_sdiv(&mut self, ty: Type, x: Imm64, y: Imm64) -> Option<Imm64> {
3242
// Sign extend `x` and `y`.

cranelift/codegen/src/opts/cprop.isle

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
;; Constant propagation.
22

3+
(rule (simplify
4+
(clz (fits_in_64 ty)
5+
(iconst ty kx)))
6+
(subsume (iconst ty (imm64_clz ty kx))))
7+
8+
9+
(rule (simplify
10+
(ctz (fits_in_64 ty)
11+
(iconst ty (u64_from_imm64 kx))))
12+
(subsume (iconst ty (imm64_masked ty (u64_trailing_zeros kx)))))
13+
314
(rule (simplify
415
(iadd (fits_in_64 ty)
516
(iconst ty (u64_from_imm64 k1))

cranelift/codegen/src/prelude.isle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@
9696
(decl pure imm64_icmp (Type IntCC Imm64 Imm64) Imm64)
9797
(extern constructor imm64_icmp imm64_icmp)
9898

99+
(decl pure imm64_clz (Type Imm64) Imm64)
100+
(extern constructor imm64_clz imm64_clz)
101+
102+
99103
;; Each of these extractors tests whether the upper half of the input equals the
100104
;; lower half of the input
101105
(decl u128_replicated_u64 (u64) u128)

cranelift/filetests/filetests/egraph/cprop.clif

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,33 @@ block0:
2222
; check: v3 = iconst.i16 -2
2323
; nextln: return v3
2424

25+
function %f0() -> i8 {
26+
block0:
27+
v1 = iconst.i8 51
28+
v2 = clz.i8 v1
29+
return v2
30+
}
31+
32+
function %f0() -> i16 {
33+
block0:
34+
v1 = iconst.i16 51
35+
v2 = clz.i16 v1
36+
return v2
37+
}
38+
39+
; check: v3 = iconst.i16 10
40+
; nextln: return v3
41+
42+
function %f0() -> i16 {
43+
block0:
44+
v1 = iconst.i16 48
45+
v2 = ctz.i16 v1
46+
return v2
47+
}
48+
49+
; check: v3 = iconst.i16 4
50+
; nextln: return v3
51+
2552
function %ishl() -> i8 {
2653
block0:
2754
v0 = iconst.i8 1

0 commit comments

Comments
 (0)