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





Reply via email to