aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-03-19 14:26:22 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-03-19 14:26:22 +0100
commit9030c54d3ff983cf07752173737f627a2e458426 (patch)
treee9b082179a3d80e2d9c878e8d1c037012bfd34ab
parent28a5efd15695250003534abf91af3210e7a88921 (diff)
downloadgcc-9030c54d3ff983cf07752173737f627a2e458426.zip
gcc-9030c54d3ff983cf07752173737f627a2e458426.tar.gz
gcc-9030c54d3ff983cf07752173737f627a2e458426.tar.bz2
i386: Fix up splitters into vptest [PR119357]
The following testcase ICEs, because the splitters into vptest create an invalid instruction. The operands of all the UNSPEC_PTEST using instructions use register_operand and vector_operand predicate, these splitters use vector_operand predicate but create vptest instruction which has the same argument twice, so one of them needs to be in a register. The following patch keeps vector_operand predicate on the splitters but uses force_reg to force it into a REG if it was a MEM, that results in better code generation e.g. on the included testcase, as combine can match those even with MEM. The difference on the testcase is - vpxor %xmm0, %xmm0, %xmm0 - vpcmpeqb (%rdi), %xmm0, %xmm0 - vpmovmskb %xmm0, %eax - cmpl $65535, %eax + vmovdqa (%rdi), %xmm0 + vptest %xmm0, %xmm0 (- for patch which changes the splitters to s/vector_operand/register_operand/ and + for this patch). 2025-03-19 Jakub Jelinek <jakub@redhat.com> PR target/119357 * config/i386/sse.md (pmovmskb 0xffff to ptest splitter, *pmovsk_ptest_<mode>_avx512): Force operands[0] into a REG. * gcc.target/i386/avx512vlbw-pr119357.c: New test.
-rw-r--r--gcc/config/i386/sse.md6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vlbw-pr119357.c14
2 files changed, 18 insertions, 2 deletions
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 7b39103..70c2cf3 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -22414,7 +22414,8 @@
[(set (reg:CCZ FLAGS_REG)
(unspec:CCZ [(match_dup 0)
(match_dup 0)]
- UNSPEC_PTEST))])
+ UNSPEC_PTEST))]
+ "operands[0] = force_reg (<MODE>mode, operands[0]);")
(define_insn_and_split "*pmovsk_mask_cmp_<mode>_avx512"
[(set (reg:CCZ FLAGS_REG)
@@ -22455,7 +22456,8 @@
[(set (reg:CCZ FLAGS_REG)
(unspec:CCZ [(match_dup 0)
(match_dup 0)]
- UNSPEC_PTEST))])
+ UNSPEC_PTEST))]
+ "operands[0] = force_reg (<MODE>mode, operands[0]);")
(define_expand "sse2_maskmovdqu"
[(set (match_operand:V16QI 0 "memory_operand")
diff --git a/gcc/testsuite/gcc.target/i386/avx512vlbw-pr119357.c b/gcc/testsuite/gcc.target/i386/avx512vlbw-pr119357.c
new file mode 100644
index 0000000..61afe22
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vlbw-pr119357.c
@@ -0,0 +1,14 @@
+/* PR target/119357 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512bw -mavx512vl" } */
+
+#include <x86intrin.h>
+
+typedef char V __attribute__((vector_size (16)));
+
+void
+foo (V *p)
+{
+ if (_mm_movemask_epi8 ((__m128i) (*p == 0)) != 65535)
+ __builtin_abort ();
+}