On Mon, Jul 6, 2026 at 11:15 AM Jeffrey Law <[email protected]> wrote:
>
>
>
>
> On 7/4/2026 9:44 AM, Andrew Pinski wrote:
> > Turns out it was easy to fix these patterns for
> > `--param=logical-op-non-short-circuit=0` case after all.
> > Just add support for `((a ^ b) & c) cmp d && a == b`
> > which is the same as `!(((a ^ b) & c) cmp d || a != b)`.
> > So this adds the bit_and case to support exactly that.
> > Also fixes up some of the `:c` on the operands.
> > `:c` needs to be on the outer bitop and does not need to be
> > on the inner one for bit_xor as it will be the same order as ne/eq.
> >
> > gcc/ChangeLog:
> >
> >       * match.pd (`((a ^ b) & c) cmp d || a != b`): Expand
> >       to support bit_and and fix up the :c.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       * gcc.dg/tree-ssa/fold-xor-and-or-1.c: New test.
> >       * gcc.dg/tree-ssa/fold-xor-or-1.c: New test.
> >       * gcc.dg/tree-ssa/pr102793-1.c: Update for the optimization
> >       happening in pre.
> But for
>
>   `((a ^ b) & c) cmp d && a == b`
>
> When that "a == b" term is true, then the "a ^ b" term will be 0, thus
> (a ^ b) & 0 is also zero.  So isn't the simplification to
>
> 0 cmp d && a == b?
>
> Or did I miss something?

That is exactly what the match pattern does:
```
   (bitop
       (cmp
        { build_zero_cst (TREE_TYPE (@0)); }
        @3)
      @4))
```

@4 here is:
(neeq@4 @0 @1)

Looks like I didn't explain the patch correctly.
I was trying say:
`((a ^ b) & c) cmp d && a == b` and `((a ^ b) & c) icmp d || a != b`
are inverse of each other. (where icmp is the inverse of cmp).
Which allows us to handle them similarly.
Your reasoning is why it works in the first place.

I tried to explain the `:c` changes more in depth as that is something
I noticed first. and then updated the patch to support `bit_and/eq`; I
went for the explanation on why expanding it would be ok rather than
why implementing it in the first place is a good idea.

Sorry for all of the confusion.

Thanks,
Andrea



>
> jeff
>

Reply via email to