Skip to content
Open
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
1 change: 1 addition & 0 deletions cranelift/codegen/src/egraph/cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ impl Cost {
// "Simple" arithmetic.
Opcode::Iadd
| Opcode::Isub
| Opcode::Ineg
| Opcode::Band
| Opcode::Bor
| Opcode::Bxor
Expand Down
32 changes: 32 additions & 0 deletions cranelift/codegen/src/opts/arithmetic.isle
Original file line number Diff line number Diff line change
Expand Up @@ -699,3 +699,35 @@
(isub ty (iconst ty x) y)
(iadd ty z (iconst ty p))))
(iadd ty (isub ty z y) (iconst ty (imm64_add ty p x))))

;; -(x & y) + x --> x & ~y
(rule (simplify (iadd ty (ineg ty (band ty x y)) x)) (band ty x (bnot ty y)))
(rule (simplify (iadd ty (ineg ty (band ty x y)) y)) (band ty y (bnot ty x)))
(rule (simplify (iadd ty x (ineg ty (band ty x y)))) (band ty x (bnot ty y)))
(rule (simplify (iadd ty x (ineg ty (band ty y x)))) (band ty x (bnot ty y)))

;; (~x & y) + (~y & x) --> y ^ x
(rule (simplify (iadd ty (band ty (bnot ty x) y) (band ty (bnot ty y) x))) (bxor ty y x))
(rule (simplify (iadd ty (band ty (bnot ty x) y) (band ty x (bnot ty y)))) (bxor ty y x))
(rule (simplify (iadd ty (band ty x (bnot ty y)) (band ty (bnot ty x) y))) (bxor ty x y))
(rule (simplify (iadd ty (band ty x (bnot ty y)) (band ty y (bnot ty x)))) (bxor ty x y))

;; max(~x, ~y) --> ~min(x, y)
(rule (simplify (smax ty (bnot ty x) (bnot ty y))) (bnot ty (smin ty x y)))
(rule (simplify (umax ty (bnot ty x) (bnot ty y))) (bnot ty (umin ty x y)))

;; min(~x, ~y) --> ~max(x, y)
(rule (simplify (smin ty (bnot ty x) (bnot ty y))) (bnot ty (smax ty x y)))
(rule (simplify (umin ty (bnot ty x) (bnot ty y))) (bnot ty (umax ty x y)))

;; (-x) - (~x) --> 1
(rule (simplify (isub (ty_int_vec128 ty) (ineg ty x) (bnot ty x))) (iconst_u ty 1))

;; ~x + C --> (C - 1) - x
(rule (simplify (iadd (fits_in_64 ty) (bnot ty x) (iconst ty y))) (isub ty (iconst ty (imm64_sub ty y (imm64 1))) x))

;; (x | C) - C --> x & ~C
(rule (simplify (isub (fits_in_64 ty) (bor ty x (iconst ty y)) (iconst ty y))) (band ty x (iconst ty (imm64_not ty y))))

;; (x << 1) * C --> x * (2 * C)
(rule (simplify (imul (fits_in_64 ty) (ishl ty x (iconst_u ty 1)) (iconst ty y))) (imul ty x (iconst ty (imm64_mul ty y (imm64 2)))))
79 changes: 79 additions & 0 deletions cranelift/codegen/src/opts/bitops.isle
Original file line number Diff line number Diff line change
Expand Up @@ -846,3 +846,82 @@

;; ~(x & y) | x --> -1
(rule (simplify (bor (ty_int_vec128 ty) (bnot ty (band ty x y)) x)) (subsume (iconst_s ty -1)))

;; (~x | y) ^ x --> ~(x & y)
(rule (simplify (bxor ty (bor ty (bnot ty x) y) x)) (bnot ty (band ty x y)))
(rule (simplify (bxor ty (bor ty x (bnot ty y)) y)) (bnot ty (band ty y x)))
(rule (simplify (bxor ty x (bor ty (bnot ty x) y))) (bnot ty (band ty x y)))
(rule (simplify (bxor ty x (bor ty y (bnot ty x)))) (bnot ty (band ty x y)))

;; max(x, y) & min(x, y) --> x & y
(rule (simplify (band ty (smax ty x y) (smin ty x y))) (band ty x y))
(rule (simplify (band ty (smax ty x y) (smin ty y x))) (band ty x y))
(rule (simplify (band ty (smin ty x y) (smax ty x y))) (band ty x y))
(rule (simplify (band ty (smin ty x y) (smax ty y x))) (band ty x y))
(rule (simplify (band ty (umax ty x y) (umin ty x y))) (band ty x y))
(rule (simplify (band ty (umax ty x y) (umin ty y x))) (band ty x y))
(rule (simplify (band ty (umin ty x y) (umax ty x y))) (band ty x y))
(rule (simplify (band ty (umin ty x y) (umax ty y x))) (band ty x y))

;; max(x, y) | min(x, y) --> x | y
(rule (simplify (bor ty (smax ty x y) (smin ty x y))) (bor ty x y))
(rule (simplify (bor ty (smax ty x y) (smin ty y x))) (bor ty x y))
(rule (simplify (bor ty (smin ty x y) (smax ty x y))) (bor ty x y))
(rule (simplify (bor ty (smin ty x y) (smax ty y x))) (bor ty x y))
(rule (simplify (bor ty (umax ty x y) (umin ty x y))) (bor ty x y))
(rule (simplify (bor ty (umax ty x y) (umin ty y x))) (bor ty x y))
(rule (simplify (bor ty (umin ty x y) (umax ty x y))) (bor ty x y))
(rule (simplify (bor ty (umin ty x y) (umax ty y x))) (bor ty x y))

;; max(x, y) ^ min(x, y) --> x ^ y
(rule (simplify (bxor ty (smax ty x y) (smin ty x y))) (bxor ty x y))
(rule (simplify (bxor ty (smax ty x y) (smin ty y x))) (bxor ty x y))
(rule (simplify (bxor ty (smin ty x y) (smax ty x y))) (bxor ty x y))
(rule (simplify (bxor ty (smin ty x y) (smax ty y x))) (bxor ty x y))
(rule (simplify (bxor ty (umax ty x y) (umin ty x y))) (bxor ty x y))
(rule (simplify (bxor ty (umax ty x y) (umin ty y x))) (bxor ty x y))
(rule (simplify (bxor ty (umin ty x y) (umax ty x y))) (bxor ty x y))
(rule (simplify (bxor ty (umin ty x y) (umax ty y x))) (bxor ty x y))

;; (~x OP y) ^ (~y OP x) --> x ^ y (OP = {&, |})
(rule (simplify (bxor ty (bor ty (bnot ty x) y) (bor ty (bnot ty y) x))) (bxor ty x y))
(rule (simplify (bxor ty (bor ty (bnot ty x) y) (bor ty x (bnot ty y)))) (bxor ty x y))
(rule (simplify (bxor ty (bor ty x (bnot ty y)) (bor ty (bnot ty x) y))) (bxor ty y x))
(rule (simplify (bxor ty (bor ty x (bnot ty y)) (bor ty y (bnot ty x)))) (bxor ty y x))
(rule (simplify (bxor ty (band ty (bnot ty x) y) (band ty (bnot ty y) x))) (bxor ty y x))
(rule (simplify (bxor ty (band ty (bnot ty x) y) (band ty x (bnot ty y)))) (bxor ty y x))
(rule (simplify (bxor ty (band ty x (bnot ty y)) (band ty (bnot ty x) y))) (bxor ty x y))
(rule (simplify (bxor ty (band ty x (bnot ty y)) (band ty y (bnot ty x)))) (bxor ty x y))

;; (~x | y) & (~y | x) --> ~(x ^ y)
(rule (simplify (band ty (bor ty (bnot ty x) y) (bor ty (bnot ty y) x))) (bnot ty (bxor ty x y)))
(rule (simplify (band ty (bor ty (bnot ty x) y) (bor ty x (bnot ty y)))) (bnot ty (bxor ty x y)))
(rule (simplify (band ty (bor ty x (bnot ty y)) (bor ty (bnot ty x) y))) (bnot ty (bxor ty y x)))
(rule (simplify (band ty (bor ty x (bnot ty y)) (bor ty y (bnot ty x)))) (bnot ty (bxor ty y x)))

;; (x + C) ^ -1 --> (-(C + 1)) - x
(rule (simplify (bxor (fits_in_64 ty) (iadd ty x (iconst ty y)) (iconst_s ty -1))) (isub ty (ineg ty (iconst ty (imm64_add ty y (imm64 1)))) x))

;; (x | C) ^ (y | C) --> (x ^ y) & ~C
(rule (simplify (bxor (fits_in_64 (ty_int ty)) (bor ty (iconst ty x) y) (bor ty z (iconst ty x)))) (band ty (bxor ty z y) (iconst ty (imm64_not ty x))))
(rule (simplify (bxor (fits_in_64 (ty_int ty)) (bor ty x (iconst ty y)) (bor ty z (iconst ty y)))) (band ty (bxor ty x z) (iconst ty (imm64_not ty y))))

;; (x | C) ^ (y ^ C) --> (x & ~C) ^ y
(rule (simplify (bxor (fits_in_64 (ty_int ty)) (bor ty x (iconst ty y)) (bxor ty z (iconst ty y)))) (bxor ty (band ty x (iconst ty (imm64_not ty y))) z))
(rule (simplify (bxor (fits_in_64 (ty_int ty)) (bxor ty x (iconst ty y)) (bor ty z (iconst ty y)))) (bxor ty (band ty z (iconst ty (imm64_not ty y))) x))

;; ~smax(~x, y) --> smin(x, ~y)
(rule (simplify (bnot ty (smax ty (bnot ty x) y))) (smin ty x (bnot ty y)))
(rule (simplify (bnot ty (smax ty x (bnot ty y)))) (smin ty y (bnot ty x)))

;; ~umax(~x, y) --> umin(x, ~y)
(rule (simplify (bnot ty (umax ty (bnot ty x) y))) (umin ty x (bnot ty y)))
(rule (simplify (bnot ty (umax ty x (bnot ty y)))) (umin ty y (bnot ty x)))

;; ~smin(~x, y) --> smax(x, ~y)
(rule (simplify (bnot ty (smin ty (bnot ty x) y))) (smax ty x (bnot ty y)))
(rule (simplify (bnot ty (smin ty x (bnot ty y)))) (smax ty y (bnot ty x)))

;; ~umin(~x, y) --> umax(x, ~y)
(rule (simplify (bnot ty (umin ty (bnot ty x) y))) (umax ty x (bnot ty y)))
(rule (simplify (bnot ty (umin ty x (bnot ty y)))) (umax ty y (bnot ty x)))
49 changes: 49 additions & 0 deletions cranelift/codegen/src/opts/icmp.isle
Original file line number Diff line number Diff line change
Expand Up @@ -628,3 +628,52 @@
(rule (simplify (bor _ (ne cty x (iconst_u cty 0)) (ne cty y (iconst_u cty 0)))) (ne cty (bor cty x y) (all_zero cty)))
;; (x == 0) & (y == 0) --> (x | y) == 0
(rule (simplify (band _ (eq cty x (iconst_u cty 0)) (eq cty y (iconst_u cty 0)))) (eq cty (bor cty x y) (all_zero cty)))

;; (x << 1) == x --> x == 0
(rule (simplify (eq ty (ishl cty x (iconst_u _ 1)) x)) (eq ty x (all_zero cty)))
(rule (simplify (eq ty x (ishl cty x (iconst_u _ 1)))) (eq ty x (all_zero cty)))

;; (x >>u 1) == x --> x == 0
(rule (simplify (eq ty (ushr cty x (iconst_u _ 1)) x)) (eq ty x (all_zero cty)))
(rule (simplify (eq ty x (ushr cty x (iconst_u _ 1)))) (eq ty x (all_zero cty)))

;; (~x & y) == y --> (y & x) == 0
(rule (simplify (eq ty (band cty (bnot cty x) y) y)) (eq ty (band cty y x) (all_zero cty)))
(rule (simplify (eq ty (band cty x (bnot cty y)) x)) (eq ty (band cty x y) (all_zero cty)))
(rule (simplify (eq ty x (band cty (bnot cty y) x))) (eq ty (band cty x y) (all_zero cty)))
(rule (simplify (eq ty x (band cty x (bnot cty y)))) (eq ty (band cty x y) (all_zero cty)))

;; umax(x, y) OP 0 --> (x | y) OP 0 (OP = {==, !=})
(rule (simplify (eq ty (umax cty x y) (all_zero cty))) (eq ty (bor cty x y) (all_zero cty)))
(rule (simplify (ne ty (umax cty x y) (all_zero cty))) (ne ty (bor cty x y) (all_zero cty)))

;; umax(x, y) OP umin(x, y) --> x OP y (OP = {==, !=})
(rule (simplify (eq ty (umax cty x y) (umin cty x y))) (eq ty x y))
(rule (simplify (eq ty (umax cty x y) (umin cty y x))) (eq ty x y))
(rule (simplify (eq ty (umin cty x y) (umax cty x y))) (eq ty x y))
(rule (simplify (eq ty (umin cty x y) (umax cty y x))) (eq ty x y))
(rule (simplify (ne ty (umax cty x y) (umin cty x y))) (ne ty x y))
(rule (simplify (ne ty (umax cty x y) (umin cty y x))) (ne ty x y))
(rule (simplify (ne ty (umin cty x y) (umax cty x y))) (ne ty x y))
(rule (simplify (ne ty (umin cty x y) (umax cty y x))) (ne ty x y))

;; ~x == (~x | y) --> (y & x) == 0
(rule (simplify (eq ty (bnot cty x) (bor cty (bnot cty x) y))) (eq ty (band cty y x) (all_zero cty)))
(rule (simplify (eq ty (bnot cty x) (bor cty y (bnot cty x)))) (eq ty (band cty y x) (all_zero cty)))
(rule (simplify (eq ty (bor cty (bnot cty x) y) (bnot cty x))) (eq ty (band cty y x) (all_zero cty)))
(rule (simplify (eq ty (bor cty x (bnot cty y)) (bnot cty y))) (eq ty (band cty x y) (all_zero cty)))

;; (c ? x : y) == (c ? y : x) --> x == y
(rule (simplify (eq ty (select cty x y z) (select cty x z y))) (eq ty y z))

;; (x >=s y) & (y >=s x) --> x == y
(rule (simplify (band _ (sge cty x y) (sge cty y x))) (eq cty x y))
(rule (simplify (band _ (sge cty x y) (sle cty x y))) (eq cty x y))
(rule (simplify (band _ (sle cty x y) (sge cty x y))) (eq cty x y))
(rule (simplify (band _ (sle cty x y) (sle cty y x))) (eq cty x y))

;; (x >=u y) & (y >=u x) --> x == y
(rule (simplify (band _ (uge cty x y) (uge cty y x))) (eq cty x y))
(rule (simplify (band _ (uge cty x y) (ule cty x y))) (eq cty x y))
(rule (simplify (band _ (ule cty x y) (uge cty x y))) (eq cty x y))
(rule (simplify (band _ (ule cty x y) (ule cty y x))) (eq cty x y))
22 changes: 22 additions & 0 deletions cranelift/codegen/src/opts/selects.isle
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,25 @@

;; (c ? C1 : C2) - C --> c ? (C1 - C) : (C2 - C)
(rule (simplify (isub (fits_in_64 ty) (select ty x (iconst ty y) (iconst ty z)) (iconst ty p))) (select ty x (iconst ty (imm64_sub ty y p)) (iconst ty (imm64_sub ty z p))))

;; (x == 0) ? -x : x --> x
(rule (simplify (select ty (eq cty x (all_zero ty)) (ineg ty x) x)) x)
(rule (simplify (select ty (ne cty x (all_zero ty)) x (ineg ty x))) x)

;; ~(c ? C1 : C2) --> c ? ~C1 : ~C2
(rule (simplify (bnot (fits_in_64 ty) (select ty x (iconst ty y) (iconst ty z)))) (select ty x (iconst ty (imm64_not ty y)) (iconst ty (imm64_not ty z))))

;; -(c ? C1 : C2) --> c ? -C1 : -C2
(rule (simplify (ineg (fits_in_64 ty) (select ty x (iconst ty y) (iconst ty z)))) (select ty x (iconst ty (imm64_neg ty y)) (iconst ty (imm64_neg ty z))))

;; (x == 0) ? 0 : (x & y) --> x & y
(rule (simplify (select ty (eq cty x (iconst_u ty 0)) (iconst_u ty 0) (band ty x y))) (band ty x y))
(rule (simplify (select ty (eq cty x (iconst_u ty 0)) (iconst_u ty 0) (band ty y x))) (band ty x y))
(rule (simplify (select ty (ne cty x (iconst_u ty 0)) (band ty x y) (iconst_u ty 0))) (band ty x y))
(rule (simplify (select ty (ne cty x (iconst_u ty 0)) (band ty y x) (iconst_u ty 0))) (band ty x y))

;; (x == 0) ? 0 : (x * y) --> x * y
(rule (simplify (select ty (eq cty x (iconst_u ty 0)) (iconst_u ty 0) (imul ty x y))) (imul ty x y))
(rule (simplify (select ty (eq cty x (iconst_u ty 0)) (iconst_u ty 0) (imul ty y x))) (imul ty x y))
(rule (simplify (select ty (ne cty x (iconst_u ty 0)) (imul ty x y) (iconst_u ty 0))) (imul ty x y))
(rule (simplify (select ty (ne cty x (iconst_u ty 0)) (imul ty y x) (iconst_u ty 0))) (imul ty x y))
6 changes: 6 additions & 0 deletions cranelift/codegen/src/opts/shifts.isle
Original file line number Diff line number Diff line change
Expand Up @@ -368,3 +368,9 @@

;; ((x & M) << k) & M --> (x << k) & M (M = 2^n - 1)
(rule (simplify (band ty (ishl ty (band ty x (iconst_u ty y)) z) (iconst_u ty y))) (if-let true (u64_eq (u64_and y (u64_wrapping_add y 1)) 0)) (band ty (ishl ty x z) (iconst_u ty y)))

;; ~rotl(~x, k) --> rotl(x, k)
(rule (simplify (bnot ty (rotl ty (bnot ty x) y))) (rotl ty x y))

;; ~rotr(~x, k) --> rotr(x, k)
(rule (simplify (bnot ty (rotr ty (bnot ty x) y))) (rotr ty x y))
Loading
Loading