From: liuhongt Date: Fri, 14 Nov 2025 03:59:08 +0000 (-0800) Subject: Also handle vptestnm + and15/and3 to just vptestnm. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=594dc80c8e49cb65f77a13c201a0bea9423329ec;p=thirdparty%2Fgcc.git Also handle vptestnm + and15/and3 to just vptestnm. r16-1298-gcdfa5fe03512f7 optimizes vpcmp + and15/and3 to vpcmp when VF is 2 or 4. vptestnm is a variant of vpcmpeq which accepts nonimm_or_0_operand. The patch handles that. gcc/ChangeLog: PR target/103750 * config/i386/sse.md (*_eq3_and15): New define_insn. (*avx512vl_eqv2di_and3): Ditto. * config/i386/i386.md (*ior_ccz_1): Fix the typo in the comments above. gcc/testsuite/ChangeLog: * gcc.target/i386/avx512vl-pr103750-2.c: New test. --- diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b925a037b2d..6af7dcfcdd3 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -14203,7 +14203,7 @@ (set_attr "isa" "*,apx_ndd") (set_attr "mode" "SI")]) -;; It must be put before *_3, the blow one. +;; It must be put before *_3, the one below. (define_insn "*ior_ccz_1" [(set (reg:CCZ FLAGS_REG) (compare:CCZ diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 7d91585b05d..8b90845260a 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -4653,6 +4653,9 @@ UNSPEC_PCMP))] "operands[4] = GEN_INT (INTVAL (operands[3]) ^ 4);") +(define_int_iterator UNSPEC_PCMP_ITER + [UNSPEC_PCMP UNSPEC_UNSIGNED_PCMP]) + (define_insn "*_cmp3_and15" [(set (match_operand:QI 0 "register_operand" "=k") (and:QI @@ -4685,6 +4688,23 @@ (set_attr "prefix" "evex") (set_attr "mode" "")]) +(define_insn "*_eq3_and15" + [(set (match_operand:QI 0 "register_operand" "=k, k") + (and:QI + (unspec:QI + [(match_operand:VI48_AVX512VL_4 1 "nonimm_or_0_operand" "%v, v") + (match_operand:VI48_AVX512VL_4 2 "nonimm_or_0_operand" "vm, C") + (const_int 0)] + UNSPEC_PCMP_ITER) + (const_int 15)))] + "TARGET_AVX512F && !(MEM_P (operands[1]) && MEM_P (operands[2]))" + "@ + vpcmpeq\t{%2, %1, %0|%0, %1, %2} + vptestnm\t{%1, %1, %0|%0, %1, %1}" + [(set_attr "type" "ssecmp") + (set_attr "prefix" "evex") + (set_attr "mode" "")]) + (define_insn "*_cmp3_and3" [(set (match_operand:QI 0 "register_operand" "=k") (and:QI @@ -4717,6 +4737,23 @@ (set_attr "prefix" "evex") (set_attr "mode" "TI")]) +(define_insn "*avx512vl_eqv2di_and3" + [(set (match_operand:QI 0 "register_operand" "=k, k") + (and:QI + (unspec:QI + [(match_operand:V2DI 1 "nonimm_or_0_operand" "%v, v") + (match_operand:V2DI 2 "nonimm_or_0_operand" "vm, C") + (const_int 0)] + UNSPEC_PCMP_ITER) + (const_int 3)))] + "TARGET_AVX512F && !(MEM_P (operands[1]) && MEM_P (operands[2]))" + "@ + vpcmpeqq\t{%2, %1, %0|%0, %1, %2} + vptestnmq\t{%1, %1, %0|%0, %1, %1}" + [(set_attr "type" "ssecmp") + (set_attr "prefix" "evex") + (set_attr "mode" "TI")]) + (define_insn "_cmp3" [(set (match_operand: 0 "register_operand" "=k") (unspec: @@ -4790,9 +4827,6 @@ (set_attr "prefix" "evex") (set_attr "mode" "")]) -(define_int_iterator UNSPEC_PCMP_ITER - [UNSPEC_PCMP UNSPEC_UNSIGNED_PCMP]) - (define_insn_and_split "*_cmp3" [(set (match_operand: 0 "register_operand") (not: diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-pr103750-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-pr103750-2.c new file mode 100644 index 00000000000..7c6e77b79e3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-pr103750-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -mprefer-vector-width=128 -O3" } */ +/* { dg-final { scan-assembler "kortest" } } */ +/* { dg-final { scan-assembler-not "kmov" } } */ + +int +foo (int *__restrict a) +{ + for (int i = 0; i != 100; i++) + if (a[i] == 0) + return 1; + return 0; +}