On 8/7/2026 11:16 AM, Andrea Pinski wrote:
On Fri, Aug 7, 2026 at 9:52 AM Jeffrey Law <[email protected]> wrote:
On 8/5/2026 5:40 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>
Neither an inclusive nor an exclusive or can carry, so an operand whose set
bits all lie below the shift count contributes nothing to the result:
int f (int a, int b) { return (a ^ (b & 1)) >> 1; }
aarch64 -O2 before:
and w1, w1, 1
eor w0, w1, w0
asr w0, w0, 1
after:
asr w0, w0, 1
The set bits are read from tree_nonzero_bits, so the rule also fires when
the operand is a boolean, a narrow value or anything else whose range the
middle end already knows. Found by mining the optimized dumps of real code,
where the shape comes from flag bits packed into the low bits of a word.
Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?
Thanks,
Kyrill
gcc/ChangeLog:
* match.pd ((X | Y) >> C, (X ^ Y) >> C): New simplification.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/shift-drops-bitop-1.c: New test.
GIven this can fire for !GIMPLE and we totally drop the Y term, don't we
need to either verify Y has no side effects or guard the transformation
on GIMPLE?
In the case of generic, genmatch already adds the needed code to deal
with the dropping and/or side effects.
The genmatch code which does this starts with the following comment:
```
/* Search for captures not used in the result expression and
dependent
on TREE_SIDE_EFFECTS emit omit_one_operand. */
```
The only case where a match pattern needs to do something manual is if
you make a conditional expression unconditional; usually inside a
COND_EXPR (but might be also from THRUTH_*IF_EXPR too). There is
expr_no_side_effects_p for that check.
Yes there are some match patterns that check TREE_SIDE_EFFECTS
explicitly but that is not needed; I noticed the majority of them were
added by Roger so it might have been out of habit or not realizing
gnematch handles that case already.
Thanks for the clarification. In that case, OK for the trunk.
jeff