On 8/4/2026 4:03 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>

(X & C) == (Y & C) already folds to ((X ^ Y) & C) == 0.  The dual was
missing: two values ored with the same constant agree on the bits that
constant forces, so only the bits outside it can differ.

   int f (unsigned char a, unsigned char b) { return (a | 32) == (b | 32); }

aarch64 -O2 before:

        orr     w1, w1, 32
        orr     w0, w0, 32
        cmp     w1, w0
        cset    w0, eq

after:

        eor     w0, w0, w1
        tst     w0, 223
        cset    w0, eq

This is the case insensitive ASCII comparison, and any equality of two
values on a masked field.  The rule sits directly beside its bit_and dual,
inside the same eq and ne iterator.

Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?
Thanks,
Kyrill

gcc/ChangeLog:

        * match.pd ((X | C) ==/!= (Y | C)): New simplification.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/ior-cmp-xor-1.c: New test.

Signed-off-by: Kyrylo Tkachov <[email protected]>
OK.

Jeff

Reply via email to