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

A lane of A | B is zero exactly when the corresponding lanes of A and of B
are both zero, so

   (A == 0) & (B == 0)  ->  (A | B) == 0

and the De Morgan dual for inequality.  The existing scalar rule already
implements this identity.  Extend it to vector integers and use a view
conversion when the operands differ only in element signedness.  Extend the
related all-ones rule in the same way.

   typedef int v4si __attribute__((vector_size (16)));
   v4si f (v4si a, v4si b) { return (a == 0) & (b == 0); }

aarch64 -O3 before:

        cmeq    v0.4s, v0.4s, #0
        cmeq    v1.4s, v1.4s, #0
        and     v0.16b, v0.16b, v1.16b

after:

        orr     v0.16b, v0.16b, v1.16b
        cmeq    v0.4s, v0.4s, #0

Add vector_nop_conversion_p for the element-wise property shared by these
rules and the existing nop_convert matcher.

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

gcc/ChangeLog:

        * match.pd (nop_convert): Use vector_nop_conversion_p.
        ((A == 0) & (B == 0), (A != 0) | (B != 0)): Extend the
        existing simplifications to vector operands.
        ((A == -1) & (B == -1), (A != -1) | (B != -1)): Likewise.
        * tree.cc (vector_nop_conversion_p): New function.
        * tree.h (vector_nop_conversion_p): Declare.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/vec-mask-zero-1.c: New test.

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

Reply via email to