On 1/6/2026 3:13 PM, Andrew Pinski wrote:
On Tue, Jan 6, 2026 at 1:46 PM Daniel Barboza
<[email protected]> wrote:
Add a transformation for a nested lshift/rshift inside a plus that compares for
equality with the same operand of the plus. In other words:
((a OP b) + c EQ|NE c) ? x : y
becomes, for OP = (lshift, rshift) and in a scenario without overflows:
a !=/== 0 ? x : y
I think we want the transformation even if it is used outside of a cond_expr.
Also the above is valid even for types that wrap; just not valid for
types that trap on overflow.
As we already have a pattern for `a + C == C`:
```
/* For equality, this is also true with wrapping overflow. */
(for op (eq ne)
(simplify
(op:c (nop_convert?@3 (plus:c@2 @0 (convert1? @1))) (convert2? @1))
(if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
&& (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
|| TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
&& (CONSTANT_CLASS_P (@0) || (single_use (@2) && single_use (@3)))
&& tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@2))
&& tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@1)))
(op @0 { build_zero_cst (TREE_TYPE (@0)); })))
```
The problem is the above does not work as there is an single_use check
on the plus. The single use check was there since the original match
pattern was added.
I am not sure if we should add a special case where in the above
pattern @0 is a shift.
Though changing that will have to wait for GCC 17 I think.
Jeff/Richard,
What are your thoughts on this? I know Richard had thoughts on some
of the single_use in the match patterns before but I have not tracked
them that well.
I had no idea we had that match.pd pattern; clearly what Daniel is doing
is closely related.
The single_use in those patterns comes up here:
https://gcc.gnu.org/pipermail/gcc-patches/2017-October/484606.html
Looks like single use is in there because of interactions with another
pattern.
jeff