diff --git a/cranelift/codegen/src/opts/bitops.isle b/cranelift/codegen/src/opts/bitops.isle index e3d5d6ead986..2bc48608baea 100644 --- a/cranelift/codegen/src/opts/bitops.isle +++ b/cranelift/codegen/src/opts/bitops.isle @@ -545,3 +545,9 @@ (rule (simplify (bor ty y (band ty x (bnot ty y)))) (bor ty y x)) (rule (simplify (bor ty (band ty x (bnot ty y)) y)) (bor ty y x)) + +;; (x & ~y) ^ ~x --> ~(x & y) +(rule (simplify (bxor ty (band ty x (bnot ty y)) (bnot ty x))) (bnot ty (band ty x y))) +(rule (simplify (bxor ty (bnot ty x) (band ty x (bnot ty y)))) (bnot ty (band ty x y))) +(rule (simplify (bxor ty (band ty (bnot ty y) x) (bnot ty x))) (bnot ty (band ty x y))) +(rule (simplify (bxor ty (bnot ty x) (band ty (bnot ty y) x))) (bnot ty (band ty x y))) \ No newline at end of file diff --git a/cranelift/filetests/filetests/egraph/arithmetic-precise.clif b/cranelift/filetests/filetests/egraph/arithmetic-precise.clif index f48b56854842..de839befa116 100644 --- a/cranelift/filetests/filetests/egraph/arithmetic-precise.clif +++ b/cranelift/filetests/filetests/egraph/arithmetic-precise.clif @@ -83,4 +83,169 @@ block0(v0: i128): ; v3 = iconst.i64 -1 ; v4 = sextend.i128 v3 ; v3 = -1 ; return v4 -; } \ No newline at end of file +; } + +;; ((x + y) - (x + z)) --> (y - z) +function %test_isub_iadd_iadd_cancel(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = iadd v0, v1 + v4 = iadd v0, v2 + v5 = isub v3, v4 + return v5 +} + +; function %test_isub_iadd_iadd_cancel(i32, i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32, v2: i32): +; v3 = iadd v0, v1 +; v4 = iadd v0, v2 +; v5 = isub v3, v4 +; return v5 +; } + +;; ((x - z) - (y - z)) --> (x - y) +function %test_isub_isub_isub_cancel(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = isub v0, v2 + v4 = isub v1, v2 + v5 = isub v3, v4 + return v5 +} + +; function %test_isub_isub_isub_cancel(i32, i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32, v2: i32): +; v3 = isub v0, v2 +; v4 = isub v1, v2 +; v5 = isub v3, v4 +; return v5 +; } + +;; ((x - y) - (x - z)) --> (z - y) +function %test_isub_isub_isub_swap_cancel(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = isub v0, v1 + v4 = isub v0, v2 + v5 = isub v3, v4 + return v5 +} + +; function %test_isub_isub_isub_swap_cancel(i32, i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32, v2: i32): +; v3 = isub v0, v1 +; v4 = isub v0, v2 +; v5 = isub v3, v4 +; return v5 +; } + +;; umin(x, y) + umax(x, y) --> x + y +function %test_iadd_umin_umax(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = umin v0, v1 + v3 = umax v0, v1 + v4 = iadd v2, v3 + return v4 +} + +; function %test_iadd_umin_umax(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = umin v0, v1 +; v3 = umax v0, v1 +; v4 = iadd v2, v3 +; return v4 +; } + +;; smin(x, y) + smax(x, y) --> x + y +function %test_iadd_smin_smax(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = smin v0, v1 + v3 = smax v0, v1 + v4 = iadd v2, v3 + return v4 +} + +; function %test_iadd_smin_smax(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = smin v0, v1 +; v3 = smax v0, v1 +; v4 = iadd v2, v3 +; return v4 +; } + +;; ((x - y) + (y + z)) --> (x + z) +function %test_iadd_isub_iadd_cancel(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = isub v0, v1 + v4 = iadd v1, v2 + v5 = iadd v3, v4 + return v5 +} + +; function %test_iadd_isub_iadd_cancel(i32, i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32, v2: i32): +; v3 = isub v0, v1 +; v4 = iadd v1, v2 +; v5 = iadd v3, v4 +; return v5 +; } + +;; (x - (x + y)) --> -y +function %test_isub_iadd_to_ineg(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = iadd v0, v1 + v3 = isub v0, v2 + return v3 +} + +; function %test_isub_iadd_to_ineg(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = iadd v0, v1 +; v3 = isub v0, v2 +; return v3 +; } + +;; (x + (y + (z - x))) --> (y + z) +function %test_iadd_iadd_isub_cancel(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = isub v2, v0 + v4 = iadd v1, v3 + v5 = iadd v0, v4 + return v5 +} + +; function %test_iadd_iadd_isub_cancel(i32, i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32, v2: i32): +; v3 = isub v2, v0 +; v4 = iadd v1, v3 +; v5 = iadd v0, v4 +; return v5 +; } + +;; (eq ty (iadd cty x y) (iadd cty y x)) -> 1 +function %simplify_icmp_eq_iadd_commute(i32, i32) -> i8 fast { +block0(v0: i32, v1: i32): + v2 = iadd v0, v1 + v3 = iadd v1, v0 + v4 = icmp eq v2, v3 + return v4 +} + +; function %simplify_icmp_eq_iadd_commute(i32, i32) -> i8 fast { +; block0(v0: i32, v1: i32): +; v6 = iconst.i8 1 +; return v6 ; v6 = 1 +; } + +;; (x - y) != x --> y != 0 +function %simplify_icmp_ne_isub_x(i32, i32) -> i8 fast { +block0(v0: i32, v1: i32): + v2 = isub v0, v1 + v3 = icmp ne v2, v0 + return v3 +} + +; function %simplify_icmp_ne_isub_x(i32, i32) -> i8 fast { +; block0(v0: i32, v1: i32): +; v2 = isub v0, v1 +; v3 = icmp ne v2, v0 +; return v3 +; } + diff --git a/cranelift/filetests/filetests/egraph/bitops.clif b/cranelift/filetests/filetests/egraph/bitops.clif index 1ffd6dec748d..20eb6a4b3218 100644 --- a/cranelift/filetests/filetests/egraph/bitops.clif +++ b/cranelift/filetests/filetests/egraph/bitops.clif @@ -957,4 +957,298 @@ block0(v0: i32, v1: i32): ; block0(v0: i32, v1: i32): ; v5 = bor v1, v0 ; return v5 -; } \ No newline at end of file +; } + +;; ((x & ~y) - (x & y)) --> ((x ^ y) - y) +function %test_isub_band_band_bnot(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v1 + v3 = band v0, v2 + v4 = band v0, v1 + v5 = isub v3, v4 + return v5 +} + +; function %test_isub_band_band_bnot(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v6 = bxor v0, v1 +; v7 = isub v6, v1 +; return v7 +; } + +;; (x & ~y) | (~x & y) --> (x ^ y) +function %test_bor_band_bnot_to_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v1 + v3 = band v0, v2 + v4 = bnot v0 + v5 = band v4, v1 + v6 = bor v3, v5 + return v6 +} + +; function %test_bor_band_bnot_to_bxor(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v7 = bxor v0, v1 +; return v7 +; } + +;; (x & ~y) | (x ^ y) --> (x ^ y) +function %test_bor_band_bnot_bxor_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v1 + v3 = band v0, v2 + v4 = bxor v0, v1 + v5 = bor v3, v4 + return v5 +} + +; function %test_bor_band_bnot_bxor_absorb(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v4 = bxor v0, v1 +; return v4 +; } + +;; (x & ~y) ^ ~x --> ~(x & y) +function %test_bxor_band_bnot_to_bnot_band(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v1 + v3 = band v0, v2 + v4 = bnot v0 + v5 = bxor v3, v4 + return v5 +} + +; function %test_bxor_band_bnot_to_bnot_band(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v6 = band v0, v1 +; v7 = bnot v6 +; return v7 +; } + +;; (~x & y) ^ x --> x | y +function %test_bxor_band_bnot_x(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = band v2, v1 + v4 = bxor v3, v0 + return v4 +} + +; function %test_bxor_band_bnot_x(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v5 = bor v0, v1 +; return v5 +; } + +;; (x | y) & ~(x ^ y) --> x & y +function %test_band_bor_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bor v0, v1 + v3 = bxor v0, v1 + v4 = bnot v3 + v5 = band v2, v4 + return v5 +} + +; function %test_band_bor_bnot_bxor(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v6 = band v0, v1 +; return v6 +; } + +;; x | ~(x ^ y) --> x | ~y +function %test_bor_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bxor v0, v1 + v3 = bnot v2 + v4 = bor v0, v3 + return v4 +} + +; function %test_bor_bnot_bxor(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v5 = bnot v1 +; v6 = bor v0, v5 +; return v6 +; } + +;; x | ((~x) ^ y) --> x | ~y +function %test_bor_bxor_bnot_x(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bxor v2, v1 + v4 = bor v0, v3 + return v4 +} + +; function %test_bor_bxor_bnot_x(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v5 = bnot v1 +; v6 = bor v0, v5 +; return v6 +; } + +;; x & ~(x ^ y) --> x & y +function %test_band_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bxor v0, v1 + v3 = bnot v2 + v4 = band v0, v3 + return v4 +} + +; function %test_band_bnot_bxor(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v5 = band v0, v1 +; return v5 +; } + +;; x & ((~x) ^ y) --> x & y +function %test_band_bxor_bnot_x(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bxor v2, v1 + v4 = band v0, v3 + return v4 +} + +; function %test_band_bxor_bnot_x(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v5 = band v0, v1 +; return v5 +; } + +;; (x | y) | (x ^ y) --> (x | y) +function %test_bor_bor_bxor_same(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bor v0, v1 + v3 = bxor v0, v1 + v4 = bor v2, v3 + return v4 +} + +; function %test_bor_bor_bxor_same(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = bor v0, v1 +; return v2 +; } + +;; (x ^ y) & ((y ^ z) ^ x) --> (x ^ y) & ~z +function %test_band_bxor_bxor_bnot(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = bxor v0, v1 + v4 = bxor v1, v2 + v5 = bxor v4, v0 + v6 = band v3, v5 + return v6 +} + +; function %test_band_bxor_bxor_bnot(i32, i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32, v2: i32): +; v3 = bxor v0, v1 +; v4 = bnot v2 +; v5 = band v3, v4 +; return v5 +; } + +;; (~x & y) ^ z --> (x & y) ^ (z ^ y) +function %test_bxor_band_bnot_general(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = bnot v0 + v4 = band v3, v1 + v5 = bxor v4, v2 + return v5 +} + +; function %test_bxor_band_bnot_general(i32, i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32, v2: i32): +; v3 = band v0, v1 +; v4 = bxor v2, v1 +; v5 = bxor v3, v4 +; return v5 +; } + +;; ~x - ~y --> y - x +function %test_isub_bnot_bnot(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bnot v1 + v4 = isub v2, v3 + return v4 +} + +; function %test_isub_bnot_bnot(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = isub v1, v0 +; return v2 +; } + +;; (~x & y) | ~(x | y) --> ~x +function %test_bor_band_bnot_bor_to_bnot(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = band v2, v1 + v4 = bor v0, v1 + v5 = bnot v4 + v6 = bor v3, v5 + return v6 +} + +; function %test_bor_band_bnot_bor_to_bnot(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = bnot v0 +; return v2 +; } + +;; (~x | y) & ~(x & y) --> ~x +function %test_band_bor_bnot_band_to_bnot(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bor v2, v1 + v4 = band v0, v1 + v5 = bnot v4 + v6 = band v3, v5 + return v6 +} + +; function %test_band_bor_bnot_band_to_bnot(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = bnot v0 +; return v2 +; } + +;; (x & y) | ~(x | y) --> ~(x ^ y) +function %test_bor_band_bnot_bor_to_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = band v0, v1 + v3 = bor v0, v1 + v4 = bnot v3 + v5 = bor v2, v4 + return v5 +} + +; function %test_bor_band_bnot_bor_to_bnot_bxor(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = bxor v0, v1 +; v3 = bnot v2 +; return v3 +; } + +;; (~x | y) ^ (x ^ y) --> x | ~y +function %test_bxor_bor_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bor v2, v1 + v4 = bxor v0, v1 + v5 = bxor v3, v4 + return v5 +} + +; function %test_bxor_bor_bnot_bxor(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v2 = bnot v1 +; v3 = bor v0, v2 +; return v3 +; } + diff --git a/cranelift/filetests/filetests/runtests/arithmetic.clif b/cranelift/filetests/filetests/runtests/arithmetic.clif index 44fef5780b34..07cdc78a6b6d 100644 --- a/cranelift/filetests/filetests/runtests/arithmetic.clif +++ b/cranelift/filetests/filetests/runtests/arithmetic.clif @@ -687,3 +687,126 @@ block0(v0: i32): ; run: %fold_iadd_bnot_x_to_allones_i32_rt(1) == -1 ; run: %fold_iadd_bnot_x_to_allones_i32_rt(0x12345678) == -1 +function %test_isub_iadd_iadd_cancel_rt(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = iadd v0, v1 + v4 = iadd v0, v2 + v5 = isub v3, v4 + return v5 +} + +; run: %test_isub_iadd_iadd_cancel_rt(0, 0, 0) == 0 +; run: %test_isub_iadd_iadd_cancel_rt(5, 7, 3) == 4 +; run: %test_isub_iadd_iadd_cancel_rt(10, 1, 9) == -8 + +function %test_isub_isub_isub_cancel_rt(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = isub v0, v2 + v4 = isub v1, v2 + v5 = isub v3, v4 + return v5 +} + +; run: %test_isub_isub_isub_cancel_rt(0, 0, 0) == 0 +; run: %test_isub_isub_isub_cancel_rt(7, 3, 1) == 4 +; run: %test_isub_isub_isub_cancel_rt(3, 7, 1) == -4 + +function %test_isub_isub_isub_swap_cancel_rt(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = isub v0, v1 + v4 = isub v0, v2 + v5 = isub v3, v4 + return v5 +} + +; run: %test_isub_isub_isub_swap_cancel_rt(0, 0, 0) == 0 +; run: %test_isub_isub_isub_swap_cancel_rt(7, 3, 1) == -2 +; run: %test_isub_isub_isub_swap_cancel_rt(7, 1, 3) == 2 + +function %test_iadd_umin_umax(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = umin v0, v1 + v3 = umax v0, v1 + v4 = iadd v2, v3 + return v4 +} + +; run: %test_iadd_umin_umax(1, 2) == 3 +; run: %test_iadd_umin_umax(2, 1) == 3 +; run: %test_iadd_umin_umax(7, 7) == 14 +; run: %test_iadd_umin_umax(-1, 1) == 0 + +function %test_iadd_smin_smax(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = smin v0, v1 + v3 = smax v0, v1 + v4 = iadd v2, v3 + return v4 +} + +; run: %test_iadd_smin_smax(1, 2) == 3 +; run: %test_iadd_smin_smax(2, 1) == 3 +; run: %test_iadd_smin_smax(7, 7) == 14 +; run: %test_iadd_smin_smax(-1, 1) == 0 + +function %test_iadd_isub_iadd_cancel_rt(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = isub v0, v1 + v4 = iadd v1, v2 + v5 = iadd v3, v4 + return v5 +} + +; run: %test_iadd_isub_iadd_cancel_rt(0, 0, 0) == 0 +; run: %test_iadd_isub_iadd_cancel_rt(7, 3, 1) == 8 +; run: %test_iadd_isub_iadd_cancel_rt(7, 1, 3) == 10 + +function %test_isub_iadd_to_ineg_rt(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = iadd v0, v1 + v3 = isub v0, v2 + return v3 +} + +; run: %test_isub_iadd_to_ineg_rt(0, 0) == 0 +; run: %test_isub_iadd_to_ineg_rt(7, 3) == -3 +; run: %test_isub_iadd_to_ineg_rt(7, -3) == 3 + +function %test_iadd_iadd_isub_cancel_rt(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = isub v2, v0 + v4 = iadd v1, v3 + v5 = iadd v0, v4 + return v5 +} + +; run: %test_iadd_iadd_isub_cancel_rt(0, 0, 0) == 0 +; run: %test_iadd_iadd_isub_cancel_rt(7, 3, 1) == 4 +; run: %test_iadd_iadd_isub_cancel_rt(7, 1, 3) == 4 +; run: %test_iadd_iadd_isub_cancel_rt(-4, 6, 2) == 8 +; run: %test_iadd_iadd_isub_cancel_rt(0x1234, 0x34, 0x10) == 0x44 + +;; (eq ty (iadd cty x y) (iadd cty y x)) -> 1 +function %simplify_icmp_eq_iadd_commute(i32, i32) -> i8 fast { +block0(v0: i32, v1: i32): + v2 = iadd v0, v1 + v3 = iadd v1, v0 + v4 = icmp eq v2, v3 + return v4 +} + +; run: %simplify_icmp_eq_iadd_commute(0, 0) == 1 +; run: %simplify_icmp_eq_iadd_commute(1, 2) == 1 +; run: %simplify_icmp_eq_iadd_commute(-1, 1) == 1 + +;; (x - y) != x --> y != 0 +function %simplify_icmp_ne_isub_x(i32, i32) -> i8 fast { +block0(v0: i32, v1: i32): + v2 = isub v0, v1 + v3 = icmp ne v2, v0 + return v3 +} + +; run: %simplify_icmp_ne_isub_x(0, 0) == 0 +; run: %simplify_icmp_ne_isub_x(1, 0) == 0 +; run: %simplify_icmp_ne_isub_x(1, 1) == 1 \ No newline at end of file diff --git a/cranelift/filetests/filetests/runtests/bitops.clif b/cranelift/filetests/filetests/runtests/bitops.clif index 7c4aa2ec4ff5..c0d063852cec 100644 --- a/cranelift/filetests/filetests/runtests/bitops.clif +++ b/cranelift/filetests/filetests/runtests/bitops.clif @@ -731,4 +731,229 @@ block0(v0: i32, v1: i32): ; run: %test_bor_band_bnot(0, 0) == 0 ; run: %test_bor_band_bnot(1, 0) == 1 -; run: %test_bor_band_bnot(0xf0, 0x0f) == 0xff \ No newline at end of file +; run: %test_bor_band_bnot(0xf0, 0x0f) == 0xff + +function %test_isub_band_band_bnot_rt(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v1 + v3 = band v0, v2 + v4 = band v0, v1 + v5 = isub v3, v4 + return v5 +} + +; run: %test_isub_band_band_bnot_rt(0, 0) == 0 +; run: %test_isub_band_band_bnot_rt(1, 0) == 1 +; run: %test_isub_band_band_bnot_rt(1, 1) == -1 + +function %test_bor_band_bnot_to_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v1 + v3 = band v0, v2 + v4 = bnot v0 + v5 = band v4, v1 + v6 = bor v3, v5 + return v6 +} + +; run: %test_bor_band_bnot_to_bxor(0, 0) == 0 +; run: %test_bor_band_bnot_to_bxor(1, 0) == 1 +; run: %test_bor_band_bnot_to_bxor(0, 1) == 1 + +function %test_bor_band_bnot_bxor_absorb(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v1 + v3 = band v0, v2 + v4 = bxor v0, v1 + v5 = bor v3, v4 + return v5 +} + +; run: %test_bor_band_bnot_bxor_absorb(0, 0) == 0 +; run: %test_bor_band_bnot_bxor_absorb(1, 0) == 1 +; run: %test_bor_band_bnot_bxor_absorb(0, 1) == 1 + +function %test_bxor_band_bnot_to_bnot_band(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v1 + v3 = band v0, v2 + v4 = bnot v0 + v5 = bxor v3, v4 + return v5 +} + +; run: %test_bxor_band_bnot_to_bnot_band(0, 0) == 0xffffffff +; run: %test_bxor_band_bnot_to_bnot_band(1, 0) == 0xffffffff +; run: %test_bxor_band_bnot_to_bnot_band(1, 1) == 0xfffffffe + +function %test_bxor_band_bnot_x(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = band v2, v1 + v4 = bxor v3, v0 + return v4 +} + +; run: %test_bxor_band_bnot_x(0, 0) == 0 +; run: %test_bxor_band_bnot_x(1, 0) == 1 +; run: %test_bxor_band_bnot_x(0, 1) == 1 + +function %test_band_bor_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bor v0, v1 + v3 = bxor v0, v1 + v4 = bnot v3 + v5 = band v2, v4 + return v5 +} + +; run: %test_band_bor_bnot_bxor(0, 0) == 0 +; run: %test_band_bor_bnot_bxor(1, 0) == 0 +; run: %test_band_bor_bnot_bxor(0, 1) == 0 +; run: %test_band_bor_bnot_bxor(1, 1) == 1 + +function %test_bor_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bxor v0, v1 + v3 = bnot v2 + v4 = bor v0, v3 + return v4 +} + +; run: %test_bor_bnot_bxor(0, 0) == 0xffffffff +; run: %test_bor_bnot_bxor(1, 0) == 0xffffffff + +function %test_bor_bxor_bnot_x(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bxor v2, v1 + v4 = bor v0, v3 + return v4 +} + +; run: %test_bor_bxor_bnot_x(0, 0) == 0xffffffff +; run: %test_bor_bxor_bnot_x(1, 0) == 0xffffffff +; run: %test_bor_bxor_bnot_x(0, 1) == 0xfffffffe + +function %test_band_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bxor v0, v1 + v3 = bnot v2 + v4 = band v0, v3 + return v4 +} + +; run: %test_band_bnot_bxor(0, 0) == 0 +; run: %test_band_bnot_bxor(1, 0) == 0 +; run: %test_band_bnot_bxor(0, 1) == 0 + +function %test_band_bxor_bnot_x(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bxor v2, v1 + v4 = band v0, v3 + return v4 +} + +; run: %test_band_bxor_bnot_x(0, 0) == 0 +; run: %test_band_bxor_bnot_x(1, 0) == 0 +; run: %test_band_bxor_bnot_x(0, 1) == 0 + +function %test_bor_bor_bxor_same(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bor v0, v1 + v3 = bxor v0, v1 + v4 = bor v2, v3 + return v4 +} + +; run: %test_bor_bor_bxor_same(0, 0) == 0 +; run: %test_bor_bor_bxor_same(1, 0) == 1 +; run: %test_bor_bor_bxor_same(0, 1) == 1 + +function %test_band_bxor_bxor_bnot(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = bxor v0, v1 + v4 = bxor v1, v2 + v5 = bxor v4, v0 + v6 = band v3, v5 + return v6 +} + +; run: %test_band_bxor_bxor_bnot(0, 0, 0) == 0 +; run: %test_band_bxor_bxor_bnot(1, 0, 0) == 1 +; run: %test_band_bxor_bxor_bnot(1, 0, 1) == 0 + +function %test_bxor_band_bnot_general(i32, i32, i32) -> i32 fast { +block0(v0: i32, v1: i32, v2: i32): + v3 = bnot v0 + v4 = band v3, v1 + v5 = bxor v4, v2 + return v5 +} + +; run: %test_bxor_band_bnot_general(0, 0, 0) == 0 +; run: %test_bxor_band_bnot_general(1, 0, 0) == 0 +; run: %test_bxor_band_bnot_general(0, 1, 0) == 1 + +function %test_isub_bnot_bnot(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bnot v1 + v4 = isub v2, v3 + return v4 +} + +; run: %test_isub_bnot_bnot(0, 0) == 0 +; run: %test_isub_bnot_bnot(1, 0) == -1 +; run: %test_isub_bnot_bnot(0, 1) == 1 + +function %test_bor_band_bnot_bor_to_bnot(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = band v2, v1 + v4 = bor v0, v1 + v5 = bnot v4 + v6 = bor v3, v5 + return v6 +} + +; run: %test_bor_band_bnot_bor_to_bnot(0, 0) == 0xffffffff +; run: %test_bor_band_bnot_bor_to_bnot(1, 0) == 0xfffffffe + +function %test_band_bor_bnot_band_to_bnot(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bor v2, v1 + v4 = band v0, v1 + v5 = bnot v4 + v6 = band v3, v5 + return v6 +} + +; run: %test_band_bor_bnot_band_to_bnot(0, 0) == 0xffffffff +; run: %test_band_bor_bnot_band_to_bnot(1, 0) == 0xfffffffe + +function %test_bor_band_bnot_bor_to_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = band v0, v1 + v3 = bor v0, v1 + v4 = bnot v3 + v5 = bor v2, v4 + return v5 +} + +; run: %test_bor_band_bnot_bor_to_bnot_bxor(0, 0) == 0xffffffff +; run: %test_bor_band_bnot_bor_to_bnot_bxor(1, 0) == 0xfffffffe + +function %test_bxor_bor_bnot_bxor(i32, i32) -> i32 fast { +block0(v0: i32, v1: i32): + v2 = bnot v0 + v3 = bor v2, v1 + v4 = bxor v0, v1 + v5 = bxor v3, v4 + return v5 +} + +; run: %test_bxor_bor_bnot_bxor(0, 0) == 0xffffffff +; run: %test_bxor_bor_bnot_bxor(1, 0) == 0xffffffff \ No newline at end of file