Skip to content
Merged
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
9 changes: 9 additions & 0 deletions cranelift/codegen/src/opts/arithmetic.isle
Original file line number Diff line number Diff line change
Expand Up @@ -585,3 +585,12 @@
;; -(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))))

;; x - (-y << z) = x + (y << z)
(rule (simplify (isub ty x (ishl ty (ineg ty y) z))) (iadd ty x (ishl ty y z)))

;; (x << y) | (z << y) = (x | z) << y, and variants
(rule (simplify (bxor ty (ishl ty x y) (ishl ty z y))) (ishl ty (bxor ty x z) y))
(rule (simplify (bxor ty (sshr ty x y) (sshr ty z y))) (sshr ty (bxor ty x z) y))
(rule (simplify (bxor ty (ushr ty x y) (ushr ty z y))) (ushr ty (bxor ty x z) y))

7 changes: 7 additions & 0 deletions cranelift/codegen/src/opts/bitops.isle
Original file line number Diff line number Diff line change
Expand Up @@ -741,3 +741,10 @@
(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)))

;; (x & y) & (x & z) --> (x & y) & z
(rule (simplify (band ty (band ty x y) (band ty x z))) (band ty (band ty x y) z))
(rule (simplify (band ty (band ty x y) (band ty y z))) (band ty (band ty y x) z))
(rule (simplify (band ty (band ty x y) (band ty z x))) (band ty (band ty x y) z))
(rule (simplify (band ty (band ty x y) (band ty z y))) (band ty (band ty y x) z))

1 change: 1 addition & 0 deletions cranelift/codegen/src/opts/shifts.isle
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@
(rule (simplify (iadd ty (ishl ty x z) (ishl ty y z))) (ishl ty (iadd ty x y) z))

(rule (simplify (ushr ty (band ty (ishl ty x y) z) y)) (band ty x (ushr ty z y)))
(rule (simplify (ushr ty (band ty x (ishl ty y z)) z)) (band ty y (ushr ty x z)))

;; Zero remains zero for any shift or rotate amount.
(rule (simplify (ishl ty (iconst_u ty 0) x)) (subsume (iconst_u ty 0)))
Expand Down
48 changes: 48 additions & 0 deletions cranelift/filetests/filetests/egraph/arithmetic.clif
Original file line number Diff line number Diff line change
Expand Up @@ -505,3 +505,51 @@ block0(v0: i32):
; check: v5 = imul v0, v4
; check: return v5
}

;; x - ((-y) << z) --> x + (y << z)
function %isub_ishl_ineg(i32, i32, i32) -> i32 {
block0(v0: i32, v1: i32, v2: i32):
v3 = ineg v1
v4 = ishl v3, v2
v5 = isub v0, v4
return v5
; check: v6 = ishl v1, v2
; check: v7 = iadd v0, v6
; check: return v7
}

;; (x << z) ^ (y << z) --> (x ^ y) << z
function %bxor_ishl(i32, i32, i32) -> i32 {
block0(v0: i32, v1: i32, v2: i32):
v3 = ishl v0, v2
v4 = ishl v1, v2
v5 = bxor v3, v4
return v5
; check: v6 = bxor v0, v1
; check: v7 = ishl v6, v2
; check: return v7
}

;; (x >>s z) ^ (y >>s z) --> (x ^ y) >>s z
function %bxor_sshr(i32, i32, i32) -> i32 {
block0(v0: i32, v1: i32, v2: i32):
v3 = sshr v0, v2
v4 = sshr v1, v2
v5 = bxor v3, v4
return v5
; check: v6 = bxor v0, v1
; check: v7 = sshr v6, v2
; check: return v7
}

;; (x >>u z) ^ (y >>u z) --> (x ^ y) >>u z
function %bxor_ushr(i32, i32, i32) -> i32 {
block0(v0: i32, v1: i32, v2: i32):
v3 = ushr v0, v2
v4 = ushr v1, v2
v5 = bxor v3, v4
return v5
; check: v6 = bxor v0, v1
; check: v7 = ushr v6, v2
; check: return v7
}
16 changes: 8 additions & 8 deletions cranelift/filetests/filetests/egraph/cprop.clif
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,10 @@ block0(v0: i32, v1: i32):
return v7
}

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

function %icmp_subs_const_addends(i32, i32) -> i8 {
block0(v0: i32, v1: i32):
Expand All @@ -364,10 +364,10 @@ block0(v0: i32, v1: i32):
return v7
}

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

function %ireduce_iconst() -> i8 {
block0:
Expand Down
64 changes: 64 additions & 0 deletions cranelift/filetests/filetests/egraph/fold-bitops.clif
Original file line number Diff line number Diff line change
Expand Up @@ -662,3 +662,67 @@ block0(v0: i32x4, v1: i32x4):
; v4 = vconst.i32x4 const0
; return v4 ; v4 = const0
; }

;; (x & y) & (x & z) --> (x & y) & z
function %band_band_common_first(i32, i32, i32) -> i32 {
block0(v0: i32, v1: i32, v2: i32):
v3 = band v0, v1
v4 = band v0, v2
v5 = band v3, v4
return v5
}

; function %band_band_common_first(i32, i32, i32) -> i32 fast {
; block0(v0: i32, v1: i32, v2: i32):
; v3 = band v0, v1
; v6 = band v3, v2
; return v6
; }

;; (x & y) & (y & z) --> (y & x) & z
function %band_band_common_second(i32, i32, i32) -> i32 {
block0(v0: i32, v1: i32, v2: i32):
v3 = band v0, v1
v4 = band v1, v2
v5 = band v3, v4
return v5
}

; function %band_band_common_second(i32, i32, i32) -> i32 fast {
; block0(v0: i32, v1: i32, v2: i32):
; v6 = band v1, v0
; v7 = band v6, v2
; return v7
; }

;; (x & y) & (z & x) --> (x & y) & z
function %band_band_common_third(i32, i32, i32) -> i32 {
block0(v0: i32, v1: i32, v2: i32):
v3 = band v0, v1
v4 = band v2, v0
v5 = band v3, v4
return v5
}

; function %band_band_common_third(i32, i32, i32) -> i32 fast {
; block0(v0: i32, v1: i32, v2: i32):
; v3 = band v0, v1
; v6 = band v3, v2
; return v6
; }

;; (x & y) & (z & y) --> (y & x) & z
function %band_band_common_fourth(i32, i32, i32) -> i32 {
block0(v0: i32, v1: i32, v2: i32):
v3 = band v0, v1
v4 = band v2, v1
v5 = band v3, v4
return v5
}

; function %band_band_common_fourth(i32, i32, i32) -> i32 fast {
; block0(v0: i32, v1: i32, v2: i32):
; v6 = band v1, v0
; v7 = band v6, v2
; return v7
; }
12 changes: 12 additions & 0 deletions cranelift/filetests/filetests/egraph/shifts.clif
Original file line number Diff line number Diff line change
Expand Up @@ -669,3 +669,15 @@ block0(v0: i64):
return v2
; check: return v1
}

;; (x & (y << z)) >>u z --> y & (x >>u z)
function %ushr_band_ishl(i32, i32, i32) -> i32 {
block0(v0: i32, v1: i32, v2: i32):
v3 = ishl v1, v2
v4 = band v0, v3
v5 = ushr v4, v2
return v5
; check: v6 = ushr v0, v2
; check: v7 = band v1, v6
; check: return v7
}
14 changes: 14 additions & 0 deletions cranelift/filetests/filetests/runtests/arithmetic.clif
Original file line number Diff line number Diff line change
Expand Up @@ -1077,3 +1077,17 @@ block0(v0: i32):
; run: %fold_isub_minus_one_lhs_to_bnot_i32_rt(1) == -2
; run: %fold_isub_minus_one_lhs_to_bnot_i32_rt(-1) == 0
; run: %fold_isub_minus_one_lhs_to_bnot_i32_rt(0x7fffffff) == 0x80000000

function %isub_ishl_ineg_rt(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
v3 = ineg v1
v4 = ishl v3, v2
v5 = isub v0, v4
return v5
}

; run: %isub_ishl_ineg_rt(0, 0, 0) == 0
; run: %isub_ishl_ineg_rt(5, 3, 1) == 11
; run: %isub_ishl_ineg_rt(10, -2, 4) == -22
; run: %isub_ishl_ineg_rt(0x80000000, 1, 31) == 0
; run: %isub_ishl_ineg_rt(7, 1, 32) == 8
44 changes: 44 additions & 0 deletions cranelift/filetests/filetests/runtests/bitops.clif
Original file line number Diff line number Diff line change
Expand Up @@ -845,3 +845,47 @@ block0(v0: i32, v1: i32):
; run: %test_band_bnot_bor_x_y_x(0, 0) == 0
; run: %test_band_bnot_bor_x_y_x(0x12345678, 0x87654321) == 0
; run: %test_band_bnot_bor_x_y_x(-1, 0x55555555) == 0

function %band_band_common_first_rt(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
v3 = band v0, v1
v4 = band v0, v2
v5 = band v3, v4
return v5
}

; run: %band_band_common_first_rt(0, -1, 0xaaaaaaaa) == 0
; run: %band_band_common_first_rt(0xf0f0f0f0, 0xcccccccc, 0xaaaaaaaa) == 0x80808080

function %band_band_common_second_rt(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
v3 = band v0, v1
v4 = band v1, v2
v5 = band v3, v4
return v5
}

; run: %band_band_common_second_rt(0, -1, 0xaaaaaaaa) == 0
; run: %band_band_common_second_rt(0xf0f0f0f0, 0xcccccccc, 0xaaaaaaaa) == 0x80808080

function %band_band_common_third_rt(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
v3 = band v0, v1
v4 = band v2, v0
v5 = band v3, v4
return v5
}

; run: %band_band_common_third_rt(0, -1, 0xaaaaaaaa) == 0
; run: %band_band_common_third_rt(0xf0f0f0f0, 0xcccccccc, 0xaaaaaaaa) == 0x80808080

function %band_band_common_fourth_rt(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
v3 = band v0, v1
v4 = band v2, v1
v5 = band v3, v4
return v5
}

; run: %band_band_common_fourth_rt(0, -1, 0xaaaaaaaa) == 0
; run: %band_band_common_fourth_rt(0xf0f0f0f0, 0xcccccccc, 0xaaaaaaaa) == 0x80808080
49 changes: 49 additions & 0 deletions cranelift/filetests/filetests/runtests/shifts.clif
Original file line number Diff line number Diff line change
Expand Up @@ -1121,3 +1121,52 @@ block0(v0: i64):
; run: %sshr_zero_left_operand(1) == 0
; run: %sshr_zero_left_operand(63) == 0
; run: %sshr_zero_left_operand(64) == 0

function %ushr_band_ishl_rt(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
v3 = ishl v1, v2
v4 = band v0, v3
v5 = ushr v4, v2
return v5
}

; run: %ushr_band_ishl_rt(0, 0, 0) == 0
; run: %ushr_band_ishl_rt(0xf0, 0xcc, 4) == 12
; run: %ushr_band_ishl_rt(0x80000000, -1, 31) == 1
; run: %ushr_band_ishl_rt(0x12345678, 0xaa, 32) == 0x28

function %bxor_ishl_rt(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
v3 = ishl v0, v2
v4 = ishl v1, v2
v5 = bxor v3, v4
return v5
}

; run: %bxor_ishl_rt(0, 0, 0) == 0
; run: %bxor_ishl_rt(0x12345678, 0x9abcdef0, 4) == 0x88888880
; run: %bxor_ishl_rt(0x12345678, 0x9abcdef0, 32) == 0x88888888

function %bxor_sshr_rt(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
v3 = sshr v0, v2
v4 = sshr v1, v2
v5 = bxor v3, v4
return v5
}

; run: %bxor_sshr_rt(0, 0, 0) == 0
; run: %bxor_sshr_rt(0x87654321, 0x12345678, 4) == 0xf9551155
; run: %bxor_sshr_rt(0x87654321, 0x12345678, 32) == 0x95511559

function %bxor_ushr_rt(i32, i32, i32) -> i32 fast {
block0(v0: i32, v1: i32, v2: i32):
v3 = ushr v0, v2
v4 = ushr v1, v2
v5 = bxor v3, v4
return v5
}

; run: %bxor_ushr_rt(0, 0, 0) == 0
; run: %bxor_ushr_rt(0x12345678, 0x9abcdef0, 4) == 0x08888888
; run: %bxor_ushr_rt(0x12345678, 0x9abcdef0, 32) == 0x88888888
Loading
Loading