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
8 changes: 8 additions & 0 deletions cranelift/codegen/src/opts/arithmetic.isle
Original file line number Diff line number Diff line change
Expand Up @@ -577,3 +577,11 @@

;; -1 - x --> ~x
(rule (simplify (isub ty (iconst_s ty -1) x)) (bnot ty x))

;; Negate integer constants at compile time.
(rule (simplify (ineg (fits_in_64 ty) (iconst ty x)))
(iconst ty (imm64_neg ty x)))

;; -(X * C) = X * (-C)
(rule (simplify (ineg (fits_in_64 ty) (imul ty x (iconst ty c))))
(imul ty x (iconst ty (imm64_neg ty c))))
32 changes: 20 additions & 12 deletions cranelift/codegen/src/opts/bitops.isle
Original file line number Diff line number Diff line change
Expand Up @@ -702,18 +702,6 @@
(rule (simplify (eq rty (bnot cty y) (band cty (bnot cty y) x))) (eq rty (bor cty y x) (iconst_s cty -1)))
(rule (simplify (eq rty (bnot cty y) (band cty x (bnot cty y)))) (eq rty (bor cty y x) (iconst_s cty -1)))

;; x >=_u (x & y), and (x & y) <=_u x, are always true.
(rule (simplify (uge ty x (band ty x y))) (cmp_true ty))
(rule (simplify (uge ty x (band ty y x))) (cmp_true ty))
(rule (simplify (ule ty (band ty x y) x)) (cmp_true ty))
(rule (simplify (ule ty (band ty y x) x)) (cmp_true ty))

;; (x | y) >=_u x, and x <=_u (x | y), are always true.
(rule (simplify (uge ty (bor ty x y) x)) (cmp_true ty))
(rule (simplify (uge ty (bor ty y x) x)) (cmp_true ty))
(rule (simplify (ule ty x (bor ty x y))) (cmp_true ty))
(rule (simplify (ule ty x (bor ty y x))) (cmp_true ty))

;; (~x & y) & x == (x & ~y) & y == 0.
(rule (simplify (band ty (band ty (bnot ty x) y) x))
(subsume (all_zero ty)))
Expand All @@ -733,3 +721,23 @@
(subsume (all_zero ty)))
(rule (simplify (band ty x (bnot ty (bor ty y x))))
(subsume (all_zero ty)))

;; x >=_u (x & y), and (x & y) <=_u x --> true
(rule (simplify (uge rty x (band ty x y))) (cmp_true rty))
(rule (simplify (uge rty x (band ty y x))) (cmp_true rty))
(rule (simplify (ule rty (band ty x y) x)) (cmp_true rty))
(rule (simplify (ule rty (band ty y x) x)) (cmp_true rty))
(rule (simplify (ugt rty (band ty x y) x)) (subsume (all_zero rty)))
(rule (simplify (ugt rty (band ty y x) x)) (subsume (all_zero rty)))
(rule (simplify (ult rty x (band ty x y))) (subsume (all_zero rty)))
(rule (simplify (ult rty x (band ty y x))) (subsume (all_zero rty)))

;; (x | y) >=_u x, and x <=_u (x | y) --> true
(rule (simplify (uge rty (bor ty x y) x)) (cmp_true rty))
(rule (simplify (uge rty (bor ty y x) x)) (cmp_true rty))
(rule (simplify (ule rty x (bor ty x y))) (cmp_true rty))
(rule (simplify (ule rty x (bor ty y x))) (cmp_true rty))
(rule (simplify (ult rty (bor ty x y) x)) (subsume (all_zero rty)))
(rule (simplify (ult rty (bor ty y x) x)) (subsume (all_zero rty)))
(rule (simplify (ugt rty x (bor ty x y))) (subsume (all_zero rty)))
(rule (simplify (ugt rty x (bor ty y x))) (subsume (all_zero rty)))
10 changes: 10 additions & 0 deletions cranelift/codegen/src/opts/icmp.isle
Original file line number Diff line number Diff line change
Expand Up @@ -480,3 +480,13 @@

;; ~x != x --> 1
(rule (simplify (ne ty (bnot cty x) x)) (subsume (cmp_true ty)))

;; x >=_u (x - y) --> x >=_u y, and the opposites
(rule (simplify (uge rty x (isub ty x y))) (uge rty x y))
(rule (simplify (ult rty x (isub ty x y))) (ult rty x y))

;; x >=_u (x >>_u y) --> true, and the opposites
(rule (simplify (uge rty x (ushr ty x y))) (cmp_true rty))
(rule (simplify (ule rty (ushr ty x y) x)) (cmp_true rty))
(rule (simplify (ugt rty (ushr ty x y) x)) (subsume (all_zero rty)))
(rule (simplify (ult rty x (ushr ty x y))) (subsume (all_zero rty)))
20 changes: 20 additions & 0 deletions cranelift/filetests/filetests/egraph/arithmetic.clif
Original file line number Diff line number Diff line change
Expand Up @@ -485,3 +485,23 @@ block0(v0: i32):
; check: v12 = bnot v0
; check: return v12
}

function %ineg_const() -> i32 {
block0:
v0 = iconst.i32 5
v1 = ineg v0
return v1
; check: v2 = iconst.i32 -5
; check: return v2
}

function %ineg_mul_const(i32) -> i32 {
block0(v0: i32):
v1 = iconst.i32 5
v2 = imul v0, v1
v3 = ineg v2
return v3
; check: v4 = iconst.i32 -5
; check: v5 = imul v0, v4
; check: return v5
}
12 changes: 6 additions & 6 deletions cranelift/filetests/filetests/egraph/cprop.clif
Original file line number Diff line number Diff line change
Expand Up @@ -350,9 +350,9 @@ block0(v0: i32, v1: i32):
}

; check: v16 = iconst.i32 333
; check: v18 = iadd v1, v16
; check: v19 = icmp eq v0, v18
; nextln: return v19
; check: v19 = iadd v1, v16
; check: v20 = icmp eq v0, v19
; nextln: return v20

function %icmp_subs_const_addends(i32, i32) -> i8 {
block0(v0: i32, v1: i32):
Expand All @@ -365,9 +365,9 @@ block0(v0: i32, v1: i32):
}

; check: v40 = iconst.i32 333
; check: v44 = iadd v0, v40
; check: v45 = icmp eq v1, v44
; nextln: return v45
; check: v45 = iadd v0, v40
; check: v46 = icmp eq v1, v45
; nextln: return v46

function %ireduce_iconst() -> i8 {
block0:
Expand Down
115 changes: 103 additions & 12 deletions cranelift/filetests/filetests/egraph/fold-bitops.clif
Original file line number Diff line number Diff line change
Expand Up @@ -521,9 +521,8 @@ block0(v0: i32, v1: i32):

; function %test_uge_x_band(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v2 = band v0, v1
; v3 = icmp uge v0, v2
; return v3
; v4 = iconst.i8 1
; return v4 ; v4 = 1
; }

;; (x & y) <=_u x --> true
Expand All @@ -536,9 +535,8 @@ block0(v0: i32, v1: i32):

; function %test_ule_band_x(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v2 = band v0, v1
; v3 = icmp ule v2, v0
; return v3
; v4 = iconst.i8 1
; return v4 ; v4 = 1
; }

;; (x | y) >=_u x --> true
Expand All @@ -551,9 +549,8 @@ block0(v0: i32, v1: i32):

; function %test_uge_bor_x(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v2 = bor v0, v1
; v3 = icmp uge v2, v0
; return v3
; v4 = iconst.i8 1
; return v4 ; v4 = 1
; }

;; x <=_u (x | y) --> true
Expand All @@ -566,8 +563,102 @@ block0(v0: i32, v1: i32):

; function %test_ule_x_bor(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v2 = bor v0, v1
; v3 = icmp ule v0, v2
; return v3
; v4 = iconst.i8 1
; return v4 ; v4 = 1
; }

;; (x & y) >_u x and x <_u (x & y) --> false
function %test_band_strict_ranges(i32, i32) -> i8, i8 fast {
block0(v0: i32, v1: i32):
v2 = band v0, v1
v3 = icmp ugt v2, v0
v4 = icmp ult v0, v2
return v3, v4
}

; function %test_band_strict_ranges(i32, i32) -> i8, i8 fast {
; block0(v0: i32, v1: i32):
; v5 = iconst.i8 0
; return v5, v5 ; v5 = 0, v5 = 0
; }

;; Unsigned range comparisons for y & x.
function %test_band_ranges_commuted(i32, i32) -> i8, i8, i8, i8 fast {
block0(v0: i32, v1: i32):
v2 = band v1, v0
v3 = icmp uge v0, v2
v4 = icmp ule v2, v0
v5 = icmp ugt v2, v0
v6 = icmp ult v0, v2
return v3, v4, v5, v6
}

; function %test_band_ranges_commuted(i32, i32) -> i8, i8, i8, i8 fast {
; block0(v0: i32, v1: i32):
; v7 = iconst.i8 1
; v10 = iconst.i8 0
; return v7, v7, v10, v10 ; v7 = 1, v7 = 1, v10 = 0, v10 = 0
; }

;; (x | y) <_u x and x >_u (x | y) --> false
function %test_bor_strict_ranges(i32, i32) -> i8, i8 fast {
block0(v0: i32, v1: i32):
v2 = bor v0, v1
v3 = icmp ult v2, v0
v4 = icmp ugt v0, v2
return v3, v4
}

; function %test_bor_strict_ranges(i32, i32) -> i8, i8 fast {
; block0(v0: i32, v1: i32):
; v5 = iconst.i8 0
; return v5, v5 ; v5 = 0, v5 = 0
; }

;; Unsigned range comparisons for y | x.
function %test_bor_ranges_commuted(i32, i32) -> i8, i8, i8, i8 fast {
block0(v0: i32, v1: i32):
v2 = bor v1, v0
v3 = icmp uge v2, v0
v4 = icmp ule v0, v2
v5 = icmp ult v2, v0
v6 = icmp ugt v0, v2
return v3, v4, v5, v6
}

; function %test_bor_ranges_commuted(i32, i32) -> i8, i8, i8, i8 fast {
; block0(v0: i32, v1: i32):
; v7 = iconst.i8 1
; v10 = iconst.i8 0
; return v7, v7, v10, v10 ; v7 = 1, v7 = 1, v10 = 0, v10 = 0
; }

function %test_band_strict_range_i32x2(i32x2, i32x2) -> i32x2 fast {
block0(v0: i32x2, v1: i32x2):
v2 = band v0, v1
v3 = icmp ugt v2, v0
return v3
}

; function %test_band_strict_range_i32x2(i32x2, i32x2) -> i32x2 fast {
; const0 = 0x0000000000000000
;
; block0(v0: i32x2, v1: i32x2):
; v4 = vconst.i32x2 const0
; return v4 ; v4 = const0
; }

function %test_bor_strict_range_i32x4(i32x4, i32x4) -> i32x4 fast {
block0(v0: i32x4, v1: i32x4):
v2 = bor v0, v1
v3 = icmp ult v2, v0
return v3
}

; function %test_bor_strict_range_i32x4(i32x4, i32x4) -> i32x4 fast {
; const0 = 0x00000000000000000000000000000000
;
; block0(v0: i32x4, v1: i32x4):
; v4 = vconst.i32x4 const0
; return v4 ; v4 = const0
; }
99 changes: 99 additions & 0 deletions cranelift/filetests/filetests/egraph/icmp.clif
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,105 @@ block0(v0: i32, v1: i32):
; return v4
; }

;; x >=_u (x - y) --> x >=_u y
function %uge_x_isub_x_y(i32, i32) -> i8 fast {
block0(v0: i32, v1: i32):
v2 = isub v0, v1
v3 = icmp uge v0, v2
return v3
}

; function %uge_x_isub_x_y(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v4 = icmp uge v0, v1
; return v4
; }

;; x <_u (x - y) --> x <_u y
function %ult_x_isub_x_y(i32, i32) -> i8 fast {
block0(v0: i32, v1: i32):
v2 = isub v0, v1
v3 = icmp ult v0, v2
return v3
}

; function %ult_x_isub_x_y(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v4 = icmp ult v0, v1
; return v4
; }

;; x >=_u (x >>_u y) --> true
function %uge_x_ushr_x_y(i32, i32) -> i8 fast {
block0(v0: i32, v1: i32):
v2 = ushr v0, v1
v3 = icmp uge v0, v2
return v3
}

; function %uge_x_ushr_x_y(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v4 = iconst.i8 1
; return v4 ; v4 = 1
; }

;; (x >>_u y) <=_u x --> true
function %ule_ushr_x_y_x(i32, i32) -> i8 fast {
block0(v0: i32, v1: i32):
v2 = ushr v0, v1
v3 = icmp ule v2, v0
return v3
}

; function %ule_ushr_x_y_x(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v4 = iconst.i8 1
; return v4 ; v4 = 1
; }

;; (x >>_u y) >_u x --> false
function %ugt_ushr_x_y_x(i32, i32) -> i8 fast {
block0(v0: i32, v1: i32):
v2 = ushr v0, v1
v3 = icmp ugt v2, v0
return v3
}

; function %ugt_ushr_x_y_x(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v4 = iconst.i8 0
; return v4 ; v4 = 0
; }

;; x <_u (x >>_u y) --> false
function %ult_x_ushr_x_y(i32, i32) -> i8 fast {
block0(v0: i32, v1: i32):
v2 = ushr v0, v1
v3 = icmp ult v0, v2
return v3
}

; function %ult_x_ushr_x_y(i32, i32) -> i8 fast {
; block0(v0: i32, v1: i32):
; v4 = iconst.i8 0
; return v4 ; v4 = 0
; }

function %ugt_ushr_x_y_x_i32x2(i32x2, i32) -> i32x2 fast {
block0(v0: i32x2, v1: i32):
v2 = ushr v0, v1
v3 = icmp ugt v2, v0
return v3
}

; function %ugt_ushr_x_y_x_i32x2(i32x2, i32) -> i32x2 fast {
; const0 = 0x0000000000000000
;
; block0(v0: i32x2, v1: i32):
; v4 = vconst.i32x2 const0
; return v4 ; v4 = const0
; }

;; (ne cty (select ty (slt cty x y) x y) x) -> (sgt cty x y)
function %simplify_select_slt_ne_i32(i32, i32) -> i8 fast {
block0(v0: i32, v1: i32):
Expand Down
Loading
Loading