Cranelift: Rewrite or(and(x, y), not(y)) => or(x, not(y)) again (#5684)

This rewrite was introduced in #5676 and then reverted in #5682 due to a footgun
where we accidentally weren't actually checking the `y == !z` precondition. This
commit fixes the precondition check. It also fixes the arithmetic to be
correctly masked to the value type's width.

This reverts commit 268f6bfc1d.
This commit is contained in:
Nick Fitzgerald
2023-02-01 12:53:22 -08:00
committed by GitHub
parent 91b8a2c527
commit ffbbfbffce
5 changed files with 177 additions and 1 deletions

View File

@@ -40,7 +40,7 @@ block0(v0: i32):
return v3
; check: v4 = iconst.i32 0xffff_ffe0
; check: v5 = band v0, v4
; return v5
; check: return v5
}
function %unsigned_shift_right_shift_left_i64(i64) -> i64 {
@@ -86,3 +86,109 @@ block0(v0: i64):
; check: v5 = band v0, v4
; return v5
}
function %or_and_y_with_not_y_i8(i8, i8) -> i8 {
block0(v0: i8, v1: i8):
v2 = band v0, v1
v3 = bnot v1
v4 = bor v2, v3
return v4
; check: v5 = bor v0, v3
; check: return v5
}
function %or_and_constant_with_not_constant_i8(i8) -> i8 {
block0(v0: i8):
v1 = iconst.i8 -4
v2 = band v0, v1
v3 = iconst.i8 3
v4 = bor v2, v3
return v4
; check: v5 = bor v0, v3
; check: return v5
}
function %or_and_y_with_not_y_i8(i8, i8) -> i8 {
block0(v0: i8, v1: i8):
v2 = band v0, v1
v3 = bnot v1
v4 = bor v3, v2
return v4
; check: v5 = bor v0, v3
; check: return v5
}
function %or_and_constant_with_not_constant_i8(i8) -> i8 {
block0(v0: i8):
v1 = iconst.i8 -4
v2 = band v0, v1
v3 = iconst.i8 3
v4 = bor v3, v2
return v4
; check: v6 = bor v0, v3
; check: return v6
}
function %or_and_constant_with_any_constant_should_not_apply_rule_i8(i8) -> i8 {
block0(v0: i8):
v1 = iconst.i8 -4
v2 = band v0, v1
;; `v3` is not `bnot(v1)` so the rewrite should not apply.
v3 = iconst.i8 -5
v4 = bor v2, v3
return v4
; check: return v4
}
function %or_and_y_with_not_y_i64(i64, i64) -> i64 {
block0(v0: i64, v1: i64):
v2 = band v0, v1
v3 = bnot v1
v4 = bor v2, v3
return v4
; check: v5 = bor v0, v3
; check: return v5
}
function %or_and_constant_with_not_constant_i64(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 -4
v2 = band v0, v1
v3 = iconst.i64 3
v4 = bor v2, v3
return v4
; check: v5 = bor v0, v3
; check: return v5
}
function %or_and_y_with_not_y_i64(i64, i64) -> i64 {
block0(v0: i64, v1: i64):
v2 = band v0, v1
v3 = bnot v1
v4 = bor v3, v2
return v4
; check: v5 = bor v0, v3
; check: return v5
}
function %or_and_constant_with_not_constant_i64(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 -4
v2 = band v0, v1
v3 = iconst.i64 3
v4 = bor v3, v2
return v4
; check: v6 = bor v0, v3
; check: return v6
}
function %or_and_constant_with_any_constant_should_not_apply_rule_i64(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 -4
v2 = band v0, v1
;; `v3` is not `bnot(v1)` so the rewrite should not apply.
v3 = iconst.i64 -5
v4 = bor v2, v3
return v4
; check: return v4
}