gnu/gcc/6bbe931ea0e8f412c81fed8a3df4a07df97821f4 match.pd: fold (0/1) * -(0/1) into -((0/1) & (0/1))
For operands known to be in the range [0, 1], multiplying a 0/1 value by a
negated 0/1 value is the negation of their bitwise AND:
x * -y == -(x & y) when x, y are in { 0, 1 }.
This complements the existing "{ 0, 1 } * { 0, 1 } -> { 0, 1 } & { 0, 1 }"
simplification, which does not handle a negated operand. For the
comparison-derived 0/1 masks produced by if-conversion this exposes a plain
bitwise AND of the original conditions to later passes (replacing a
COND_EXPR).
This triggers a few times in astcenc in SPEC2026 where it simplifies the
codegen of one of the hot kernels and gives a ~2.4% improvement on
aarch64, though the real winners for that kernel are described in
PR125750. This is just a small cleanup.
Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
gcc/ChangeLog:
PR tree-optimization/125750
* match.pd (mult of a 0/1 value by a negated 0/1 value): New
simplification.
gcc/testsuite/ChangeLog:
PR tree-optimization/125750
* g++.dg/tree-ssa/mult-negate-zeroone-1.C: New test.
* g++.dg/tree-ssa/mult-negate-zeroone-2.C: New test.
3 files changed