gnu/gcc/9d59dcff40a4f39ee82f9c59a67f9466d7a8bc66 match.pd: Simplify (~A & 1) == (~B & 1) at -O1 [PR112533]
At -O1, GCC lowers (~a & 1) == (~b & 1) into two different GIMPLE
forms depending on whether the boolean values come from a function
return boundary or an inline expression:
1. Via function return (e.g. inlined is_even), GCC preserves the
eq/ne form because the function boundary hides the internal
structure from the gimplifier:
((a&1)==0) == ((b&1)==0) outer node is eq/ne
2. Via inline expression (directly written), GCC sees the full
boolean expression tree at once and folds to bit_xor during
gimplification:
((a&1)!=0) ^ ((b&1)==0) outer node is bit_xor
Add a generalized match.pd rule handling:
1. ((x & c) == 0) OP ((y & c) == 0)
2. ((x & c) != 0) OP ((y & c) == 0)
for OP in { ==, !=, ^ } and pow2 masks.
Fold these directly into the canonical xor-mask form:
((x ^ y) & c) == 0
((x ^ y) & c) != 0
Bootstrapped and tested on aarch64-linux-gnu with
RUNTESTFLAGS="tree-ssa.exp".
Changes since v1:
* v5: Add :s to the inner comparisons and bit_and expressions.
Simplify the innersame check to compare icmp0 and icmp1
directly.
* v4: Removed the ((x & c) == 0) OP (y & c) simplify rule and
mark the corresponding test case as XFAIL.
* v3: Collapse both previous simplify rules into one generalized
matcher covering all combinations of outer {eq, ne, bit_xor}
and inner {eq, ne} comparisons.
Add missing mixed-polarity test cases.
* v2: Generalize mask from integer_onep to integer_pow2p.
Combine both patterns into single one.
Split test into bool-eq-evenness.c, bool-eq-bitxor.c,
bool-eq-pow2.c.
PR tree-optimization/112533
gcc/ChangeLog:
* match.pd: Canonicalize boolean comparisons of masked pow2
bits into xor-mask tests.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/bool-eq-bitxor.c: New test.
* gcc.dg/tree-ssa/bool-eq-evenness.c: New test.
* gcc.dg/tree-ssa/bool-eq-pow2.c: New test.
Signed-off-by: Shivam Gupta <shivam98.tkg@gmail.com>
4 files changed