diff --git a/cranelift/codegen/src/opts/bitops.isle b/cranelift/codegen/src/opts/bitops.isle index a29b2ac337c4..e71b88865000 100644 --- a/cranelift/codegen/src/opts/bitops.isle +++ b/cranelift/codegen/src/opts/bitops.isle @@ -202,3 +202,6 @@ (rule (simplify (band ty (band ty x y) y)) (band ty x y)) (rule (simplify (band ty x (band ty x y))) (band ty x y)) (rule (simplify (band ty y (band ty x y))) (band ty x y)) + +(rule (simplify (iadd ty (bor ty x y) (ineg ty y))) (band ty x (bnot ty y))) + diff --git a/cranelift/filetests/filetests/egraph/fold-add-or-neg.clif b/cranelift/filetests/filetests/egraph/fold-add-or-neg.clif new file mode 100644 index 000000000000..399ef2087fc5 --- /dev/null +++ b/cranelift/filetests/filetests/egraph/fold-add-or-neg.clif @@ -0,0 +1,64 @@ +test optimize precise-output +set opt_level=speed +target x86_64 + +function %test1(i8, i8) -> i8 { +block0(v0: i8, v1: i8): + v2 = bor v0, v1 + v3 = ineg v1 + v4 = iadd v2, v3 + return v4 +} + +; function %test1(i8, i8) -> i8 fast { +; block0(v0: i8, v1: i8): +; v5 = bnot v1 +; v6 = band v0, v5 +; return v6 +; } + +function %test2(i16, i16) -> i16 { +block0(v0: i16, v1: i16): + v2 = bor v0, v1 + v3 = ineg v1 + v4 = iadd v2, v3 + return v4 +} + +; function %test2(i16, i16) -> i16 fast { +; block0(v0: i16, v1: i16): +; v5 = bnot v1 +; v6 = band v0, v5 +; return v6 +; } + +function %test3(i32, i32) -> i32 { +block0(v0: i32, v1: i32): + v2 = bor v0, v1 + v3 = ineg v1 + v4 = iadd v2, v3 + return v4 +} + +; function %test3(i32, i32) -> i32 fast { +; block0(v0: i32, v1: i32): +; v5 = bnot v1 +; v6 = band v0, v5 +; return v6 +; } + +function %test4(i64, i64) -> i64 { +block0(v0: i64, v1: i64): + v2 = bor v0, v1 + v3 = ineg v1 + v4 = iadd v2, v3 + return v4 +} + +; function %test4(i64, i64) -> i64 fast { +; block0(v0: i64, v1: i64): +; v5 = bnot v1 +; v6 = band v0, v5 +; return v6 +; } + diff --git a/cranelift/filetests/filetests/runtests/bitops.clif b/cranelift/filetests/filetests/runtests/bitops.clif index e8c3b3a4b379..93a9d2d3828c 100644 --- a/cranelift/filetests/filetests/runtests/bitops.clif +++ b/cranelift/filetests/filetests/runtests/bitops.clif @@ -164,3 +164,13 @@ block0(v0: i32, v1: i32): ; run: %test_and_and4(4, 3) == 0 +function %fold_add_neg_or(i32, i32) -> i32 { +block0(v0: i32, v1: i32): + v2 = bor v0, v1 + v3 = ineg v1 + v4 = iadd v2, v3 + return v4 +} + +; run: %fold_add_neg_or(0xffffffff, 0) == 0xffffffff +