Browse Source
Add some minor souper-harvested optimizations (#5735 )
I was playing around with souper recently on some wasms I had lying
around and these are some optimization opportunities that popped out
which seemed easy-enough to add to the egraph-based optimizations.
pull/5738/head
Alex Crichton
2 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with
134 additions and
0 deletions
cranelift/codegen/src/opts/algebraic.isle
cranelift/codegen/src/opts/cprop.isle
cranelift/filetests/filetests/egraph/algebraic.clif
@ -289,3 +289,47 @@
(rule (simplify (bxor ty x (iconst ty k)))
(if-let -1 (i64_sextend_imm64 ty k))
(bnot ty x))
;; Masking the result of a comparison with 1 always results in the comparison
;; itself. Note that comparisons in wasm may sometimes be hidden behind
;; extensions.
(rule (simplify
(band (ty_int _)
cmp @ (icmp _ _ _ _)
(iconst _ (u64_from_imm64 1))))
cmp)
(rule (simplify
(band (ty_int _)
extend @ (uextend _ (icmp _ _ _ _))
(iconst _ (u64_from_imm64 1))))
extend)
;; `x < 0` is always false for unsigned integers, and `x >= 0` is always true
;; for unsigned integers, along with their reversals.
(rule (simplify
(icmp (fits_in_64 (ty_int ty))
(IntCC.UnsignedLessThan)
_
(iconst _ (u64_from_imm64 0))))
(iconst ty (imm64 0)))
(rule (simplify
(icmp (fits_in_64 (ty_int ty))
(IntCC.UnsignedGreaterThanOrEqual)
_
(iconst _ (u64_from_imm64 0))))
(iconst ty (imm64 1)))
;; 32-bit integers zero-extended to 64-bit integers are never negative
(rule (simplify
(icmp (ty_int ty)
(IntCC.SignedLessThan)
(uextend $I64 x @ (value_type $I32))
(iconst _ (u64_from_imm64 0))))
(iconst ty (imm64 0)))
(rule (simplify
(icmp (ty_int ty)
(IntCC.SignedGreaterThanOrEqual)
(uextend $I64 x @ (value_type $I32))
(iconst _ (u64_from_imm64 0))))
(iconst ty (imm64 1)))
@ -110,6 +110,10 @@
(bxor ty k @ (iconst ty _) x))
(bxor ty x k))
(rule (simplify
(icmp ty cc k @ (iconst _ _) x))
(icmp ty (intcc_reverse cc) x k))
;; Canonicalize via associativity: reassociate to a right-heavy tree
;; for constants.
;;
@ -251,3 +251,89 @@ block0(v1: i64):
; check: v5 = bnot v1
; check: return v5
function %mask_icmp_result(i64, i64) -> i8 {
block0(v1: i64, v2: i64):
v3 = icmp ult v1, v2
v4 = iconst.i8 1
v5 = band v3, v4
return v5
}
; check: v3 = icmp ult v1, v2
; check: return v3
function %mask_icmp_extend_result(i64, i64) -> i64 {
block0(v1: i64, v2: i64):
v3 = icmp ult v1, v2
v4 = uextend.i64 v3
v5 = iconst.i64 1
v6 = band v4, v5
return v6
}
; check: v3 = icmp ult v1, v2
; check: v4 = uextend.i64 v3
; check: return v4
function %ult_zero_always_false(i64) -> i8 {
block0(v1: i64):
v2 = iconst.i64 0
v3 = icmp ult v1, v2
return v3
}
; check: v4 = iconst.i8 0
; check: return v4
function %ugt_zero_always_false(i64) -> i8 {
block0(v1: i64):
v2 = iconst.i64 0
v3 = icmp ugt v2, v1
return v3
}
; check: v5 = iconst.i8 0
; check: return v5
function %uge_zero_always_false(i64) -> i8 {
block0(v1: i64):
v2 = iconst.i64 0
v3 = icmp uge v1, v2
return v3
}
; check: v4 = iconst.i8 1
; check: return v4
function %ule_zero_always_false(i64) -> i8 {
block0(v1: i64):
v2 = iconst.i64 0
v3 = icmp ule v2, v1
return v3
}
; check: v5 = iconst.i8 1
; check: return v5
function %extend_always_above_zero(i32) -> i8 {
block0(v1: i32):
v2 = uextend.i64 v1
v3 = iconst.i64 0
v4 = icmp slt v2, v3
return v4
}
; check: v5 = iconst.i8 0
; check: return v5
function %extend_always_above_zero2(i32) -> i8 {
block0(v1: i32):
v2 = uextend.i64 v1
v3 = iconst.i64 0
v4 = icmp sge v2, v3
return v4
}
; check: v5 = iconst.i8 1
; check: return v5