Skip to content

Commit 7bf8968

Browse files
authored
Generalize and/or/xor optimizations (#5744)
* Generalize `n ^ !n` optimization to more types * Generalize `x & -1` optimization to more types Also mark the `x & x` rewrite to `subsume`. * Cranelift: Optimize x|!x and x&!x to constants These cases are much like the existing x^!x rules.
1 parent d71c945 commit 7bf8968

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

cranelift/codegen/src/opts/algebraic.isle

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,28 @@
104104
(rule (simplify (bxor (fits_in_64 (ty_int ty)) x x))
105105
(subsume (iconst ty (imm64 0))))
106106

107-
;; x ^ not(x) == not(x) ^ x == -1.
108-
(rule (simplify (bxor $I32 x (bnot $I32 x))) (subsume (iconst $I32 (imm64 0xffff_ffff))))
109-
(rule (simplify (bxor $I32 (bnot $I32 x) x)) (subsume (iconst $I32 (imm64 0xffff_ffff))))
110-
(rule (simplify (bxor $I64 x (bnot $I64 x))) (subsume (iconst $I64 (imm64 0xffff_ffff_ffff_ffff))))
111-
(rule (simplify (bxor $I64 (bnot $I64 x) x)) (subsume (iconst $I64 (imm64 0xffff_ffff_ffff_ffff))))
107+
;; x ^ not(x) == not(x) ^ x == x | not(x) == not(x) | x == -1.
108+
;; This identity also holds for non-integer types, vectors, and wider types.
109+
;; But `iconst` is only valid for integers up to 64 bits wide.
110+
(rule (simplify (bxor (fits_in_64 (ty_int ty)) x (bnot ty x))) (subsume (iconst ty (imm64 (ty_mask ty)))))
111+
(rule (simplify (bxor (fits_in_64 (ty_int ty)) (bnot ty x) x)) (subsume (iconst ty (imm64 (ty_mask ty)))))
112+
(rule (simplify (bor (fits_in_64 (ty_int ty)) x (bnot ty x))) (subsume (iconst ty (imm64 (ty_mask ty)))))
113+
(rule (simplify (bor (fits_in_64 (ty_int ty)) (bnot ty x) x)) (subsume (iconst ty (imm64 (ty_mask ty)))))
112114

113115
;; x & -1 == -1 & x == x & x == x.
114-
(rule (simplify (band ty x x)) x)
115-
(rule (simplify (band $I32 x (iconst $I32 (u64_from_imm64 0xffff_ffff)))) (subsume x))
116-
(rule (simplify (band $I32 (iconst $I32 (u64_from_imm64 0xffff_ffff)) x)) (subsume x))
117-
(rule (simplify (band $I64 x (iconst $I64 (u64_from_imm64 0xffff_ffff_ffff_ffff)))) (subsume x))
118-
(rule (simplify (band $I64 (iconst $I64 (u64_from_imm64 0xffff_ffff_ffff_ffff)) x)) (subsume x))
116+
(rule (simplify (band ty x x)) (subsume x))
117+
(rule (simplify (band ty x (iconst ty k)))
118+
(if-let -1 (i64_sextend_imm64 ty k))
119+
(subsume x))
120+
(rule (simplify (band ty (iconst ty k) x))
121+
(if-let -1 (i64_sextend_imm64 ty k))
122+
(subsume x))
119123

120-
;; x & 0 == 0 & x == 0.
124+
;; x & 0 == 0 & x == x & not(x) == not(x) & x == 0.
121125
(rule (simplify (band ty _ zero @ (iconst ty (u64_from_imm64 0)))) (subsume zero))
122126
(rule (simplify (band ty zero @ (iconst ty (u64_from_imm64 0)) _)) (subsume zero))
127+
(rule (simplify (band (fits_in_64 (ty_int ty)) x (bnot ty x))) (subsume (iconst ty (imm64 0))))
128+
(rule (simplify (band (fits_in_64 (ty_int ty)) (bnot ty x) x)) (subsume (iconst ty (imm64 0))))
123129

124130
;; not(not(x)) == x.
125131
(rule (simplify (bnot ty (bnot ty x))) (subsume x))

0 commit comments

Comments
 (0)