Skip to content

Commit b60f059

Browse files
committed
[Cranelift] add simplification rules
1 parent 260f9d4 commit b60f059

24 files changed

Lines changed: 431 additions & 55 deletions

cranelift/codegen/src/opts/arithmetic.isle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,3 +568,12 @@
568568

569569
;; (-X) * C = X * (-C)
570570
(rule (simplify (imul (fits_in_64 ty) (ineg ty x) (iconst ty y))) (imul ty x (iconst ty (imm64_neg ty y))))
571+
572+
;; -(~x) --> x + 1
573+
(rule (simplify (ineg ty (bnot ty x))) (iadd ty x (iconst_u ty 1)))
574+
575+
;; ~(-x) --> x - 1.
576+
(rule (simplify (bnot ty (ineg ty x))) (isub ty x (iconst_u ty 1)))
577+
578+
;; -1 - x --> ~x
579+
(rule (simplify (isub ty (iconst_s ty -1) x)) (bnot ty x))

cranelift/codegen/src/opts/bitops.isle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
(subsume x))
1616

1717
;; x ^ x == 0.
18-
(rule (simplify (bxor (ty_int ty) x x))
18+
(rule (simplify (bxor ty x x))
1919
(subsume (iconst_u ty 0)))
2020

2121
;; x ^ not(x) == not(x) ^ x == x | not(x) == not(x) | x == -1.

cranelift/codegen/src/opts/extends.isle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,6 @@
9393
;; Try to transform an `iconcat` into an i128 into either an sextend or uextend
9494
(rule (simplify (iconcat $I128 x (iconst_u _ 0))) (uextend $I128 x))
9595
(rule (simplify (iconcat $I128 x (sshr _ x (iconst_u _ 63)))) (sextend $I128 x))
96+
97+
;; Select narrowest type
98+
(rule (simplify (ireduce ty (ireduce cty x))) (ireduce ty x))

cranelift/codegen/src/opts/icmp.isle

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
;; `x == x` is always true for integers; `x != x` is false. Strict
44
;; inequalities are false, and loose inequalities are true.
5-
(rule (simplify (eq (ty_int ty) x x)) (subsume (iconst_u ty 1)))
6-
(rule (simplify (ne (ty_int ty) x x)) (subsume (iconst_u ty 0)))
7-
(rule (simplify (ugt (ty_int ty) x x)) (subsume (iconst_u ty 0)))
8-
(rule (simplify (uge (ty_int ty) x x)) (subsume (iconst_u ty 1)))
9-
(rule (simplify (sgt (ty_int ty) x x)) (subsume (iconst_u ty 0)))
10-
(rule (simplify (sge (ty_int ty) x x)) (subsume (iconst_u ty 1)))
11-
(rule (simplify (ult (ty_int ty) x x)) (subsume (iconst_u ty 0)))
12-
(rule (simplify (ule (ty_int ty) x x)) (subsume (iconst_u ty 1)))
13-
(rule (simplify (slt (ty_int ty) x x)) (subsume (iconst_u ty 0)))
14-
(rule (simplify (sle (ty_int ty) x x)) (subsume (iconst_u ty 1)))
5+
(rule (simplify (eq ty x x)) (subsume (cmp_true ty)))
6+
(rule (simplify (ne ty x x)) (subsume (iconst_u ty 0)))
7+
(rule (simplify (ugt ty x x)) (subsume (iconst_u ty 0)))
8+
(rule (simplify (uge ty x x)) (subsume (cmp_true ty)))
9+
(rule (simplify (sgt ty x x)) (subsume (iconst_u ty 0)))
10+
(rule (simplify (sge ty x x)) (subsume (cmp_true ty)))
11+
(rule (simplify (ult ty x x)) (subsume (iconst_u ty 0)))
12+
(rule (simplify (ule ty x x)) (subsume (cmp_true ty)))
13+
(rule (simplify (slt ty x x)) (subsume (iconst_u ty 0)))
14+
(rule (simplify (sle ty x x)) (subsume (cmp_true ty)))
1515

1616
;; For integers, adding the same thing on both sides of an equality check
1717
;; (or an inequality check) doesn't change the result.
@@ -474,3 +474,9 @@
474474

475475
(rule (simplify_skeleton (brif (ireduce _ (clz x_ty x)) _ _))
476476
(replace_branch_cond (sge $I8 x (iconst_u x_ty 0))))
477+
478+
;; ~x == x --> 0
479+
(rule (simplify (eq ty (bnot cty x) x)) (subsume (iconst_u ty 0)))
480+
481+
;; ~x != x --> 1
482+
(rule (simplify (ne ty (bnot cty x) x)) (subsume (cmp_true ty)))

cranelift/codegen/src/opts/shifts.isle

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,15 @@
315315
(rule (simplify (iadd ty (ishl ty x z) (ishl ty y z))) (ishl ty (iadd ty x y) z))
316316

317317
(rule (simplify (ushr ty (band ty (ishl ty x y) z) y)) (band ty x (ushr ty z y)))
318+
319+
;; Zero remains zero for any shift or rotate amount.
320+
(rule (simplify (ishl ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
321+
(rule (simplify (ushr ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
322+
(rule (simplify (sshr ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
323+
(rule (simplify (rotl ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
324+
(rule (simplify (rotr ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
325+
326+
;; All ones remain all ones for arithmetic right shifts or rotates.
327+
(rule (simplify (sshr ty (iconst_s ty -1) x)) (subsume (iconst_s ty -1)))
328+
(rule (simplify (rotl ty (iconst_s ty -1) x)) (subsume (iconst_s ty -1)))
329+
(rule (simplify (rotr ty (iconst_s ty -1) x)) (subsume (iconst_s ty -1)))

cranelift/filetests/filetests/egraph/arithmetic-precise.clif

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ block0(v0: i32x4, v1: i32x4):
247247
; const0 = 0xffffffffffffffffffffffffffffffff
248248
;
249249
; block0(v0: i32x4, v1: i32x4):
250-
; v9 = icmp eq v0, v0
251-
; return v9
250+
; v7 = vconst.i32x4 const0
251+
; return v7 ; v7 = const0
252252
; }
253253

254254
;; (x - y) != x --> y != 0

cranelift/filetests/filetests/egraph/arithmetic.clif

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,17 @@ block0(v0: i32):
219219
; check: v6 = ineg v0
220220
; check: return v6
221221

222+
function %ineg_bnot_to_iadd_one(i32) -> i32 {
223+
block0(v0: i32):
224+
v1 = bnot v0
225+
v2 = ineg v1
226+
return v2
227+
}
228+
229+
; check: v3 = iconst.i32 1
230+
; check: v4 = iadd v0, v3 ; v3 = 1
231+
; check: return v4
232+
222233
function %byte_sub_smax_twice(i8) -> i8 {
223234
block0(v0: i8):
224235
v1 = iconst.i8 127
@@ -464,3 +475,13 @@ block0(v0: i64):
464475
; check: v6 = iadd v4, v5
465476
; check: return v6
466477
}
478+
479+
;; -1 - x --> ~x
480+
function %isub_minus_one_lhs_to_bnot(i32) -> i32 {
481+
block0(v0: i32):
482+
v1 = iconst.i32 -1
483+
v2 = isub v1, v0
484+
return v2
485+
; check: v12 = bnot v0
486+
; check: return v12
487+
}

cranelift/filetests/filetests/egraph/bitops.clif

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,17 @@ block0(v0: i32x4):
160160
; check: v5 = vconst.i32x4 const0
161161
; check: return v5
162162

163+
function %vector_bxor_bnot_x_bnot_x(i32x4) -> i32x4 {
164+
block0(v0: i32x4):
165+
v1 = bnot v0
166+
v2 = bxor v1, v1
167+
return v2
168+
}
169+
170+
; check: const0 = 0x00000000000000000000000000000000
171+
; check: v5 = vconst.i32x4 const0
172+
; check: return v5
173+
163174
function %vector_bor_x_bnot_x(i32x4) -> i32x4 {
164175
block0(v0: i32x4):
165176
v1 = bnot v0
@@ -803,6 +814,21 @@ block0(v0: i32, v1: i32):
803814
; return v5
804815
; }
805816

817+
;; (bnot ty (ineg ty x)) -> (isub ty x (iconst_u ty 1))
818+
function %test_bnot_ineg_to_isub_one(i32) -> i32 fast {
819+
block0(v0: i32):
820+
v1 = ineg v0
821+
v2 = bnot v1
822+
return v2
823+
}
824+
825+
; function %test_bnot_ineg_to_isub_one(i32) -> i32 fast {
826+
; block0(v0: i32):
827+
; v3 = iconst.i32 1
828+
; v4 = isub v0, v3
829+
; return v4
830+
; }
831+
806832
;; (bor ty (bxor ty x z) (bor ty y x)) -> (bor ty (bor ty y x) z)
807833
function %test_bor_bxor_bor(i32, i32, i32) -> i32 fast {
808834
block0(v0: i32, v1: i32, v2: i32):

cranelift/filetests/filetests/egraph/extends.clif

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,16 @@ block0(v1: i16):
134134
; check: v4 = uextend.i32 v1
135135
; check: return v4
136136

137+
function %nested_ireduce(i64) -> i8 {
138+
block0(v1: i64):
139+
v2 = ireduce.i32 v1
140+
v3 = ireduce.i8 v2
141+
return v3
142+
}
143+
144+
; check: v4 = ireduce.i8 v1
145+
; check: return v4
146+
137147
function %sextend_then_slt_zero(i8) -> i8 {
138148
block0(v0: i8):
139149
v1 = sextend.i16 v0

cranelift/filetests/filetests/egraph/i128-opts.clif

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,18 @@ function %eq_self_v128(i8x16) -> i8x16 {
7474
block0(v0: i8x16):
7575
v1 = icmp eq v0, v0
7676
return v1
77-
; check: v1 = icmp eq v0, v0
78-
; check: return v1
77+
; check: const0 = 0xffffffffffffffffffffffffffffffff
78+
; check: v4 = vconst.i8x16 const0
79+
; check: return v4 ; v4 = const0
7980
}
8081

8182
function %ne_self_v128(i8x16) -> i8x16 {
8283
block0(v0: i8x16):
8384
v1 = icmp ne v0, v0
8485
return v1
85-
; check: v1 = icmp ne v0, v0
86-
; check: return v1
86+
; check: const0 = 0x00000000000000000000000000000000
87+
; check: v4 = vconst.i8x16 const0
88+
; check: return v4 ; v4 = const0
8789
}
8890

8991
function %bor_extended_constants_i128() -> i128 {

0 commit comments

Comments
 (0)