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
