aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-05-05 11:33:47 +0200
committerJakub Jelinek <jakub@redhat.com>2020-05-05 11:34:45 +0200
commit7f916201ac390a5e1c88562bb91b1b4ab2852f22 (patch)
tree218478458e80d07e1710f98fb7d615addd288030 /gcc
parent6d938a5d770d0e94ecd923d20006b05126659235 (diff)
downloadgcc-7f916201ac390a5e1c88562bb91b1b4ab2852f22.zip
gcc-7f916201ac390a5e1c88562bb91b1b4ab2852f22.tar.gz
gcc-7f916201ac390a5e1c88562bb91b1b4ab2852f22.tar.bz2
x86: Fix *vec_dupv4hi constraints [PR94942]
This insn and split splits into HI->V?HImode broadcast for avx2 and later, but either the operands need to be %xmm0-%xmm15 (i.e. VEX encoded insn), or the insn needs both AVX512BW and AVX512VL. Now, Yv constraint is v for AVX512VL and x otherwise, so for -mavx512vl -mno-avx512bw we ICE if we end up with a %xmm16+ register from RA. Yw constraint is v for AVX512VL and AVX512BW and nothing otherwise, so in this pattern we actually need xYw. 2020-05-05 Jakub Jelinek <jakub@redhat.com> PR target/94942 * config/i386/mmx.md (*vec_dupv4hi): Use xYw constraints instead of Yv. * gcc.target/i386/pr94942.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog3
-rw-r--r--gcc/config/i386/mmx.md4
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr94942.c24
4 files changed, 32 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e51c0e0..b796203 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,8 @@
2020-05-05 Jakub Jelinek <jakub@redhat.com>
+ PR target/94942
+ * config/i386/mmx.md (*vec_dupv4hi): Use xYw constraints instead of Yv.
+
PR tree-optimization/94914
* match.pd ((((type)A * B) >> prec) != 0 to .MUL_OVERFLOW(A, B) != 0):
New simplification.
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index c3f195bb..472f90f 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -1613,10 +1613,10 @@
(set_attr "mode" "DI")])
(define_insn_and_split "*vec_dupv4hi"
- [(set (match_operand:V4HI 0 "register_operand" "=y,Yv,Yw")
+ [(set (match_operand:V4HI 0 "register_operand" "=y,xYw,Yw")
(vec_duplicate:V4HI
(truncate:HI
- (match_operand:SI 1 "register_operand" "0,Yv,r"))))]
+ (match_operand:SI 1 "register_operand" "0,xYw,r"))))]
"(TARGET_MMX || TARGET_MMX_WITH_SSE)
&& (TARGET_SSE || TARGET_3DNOW_A)"
"@
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2a44c70..6475b7d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2020-05-05 Jakub Jelinek <jakub@redhat.com>
+ PR target/94942
+ * gcc.target/i386/pr94942.c: New test.
+
PR tree-optimization/94914
* gcc.target/i386/pr94914.c: New test.
diff --git a/gcc/testsuite/gcc.target/i386/pr94942.c b/gcc/testsuite/gcc.target/i386/pr94942.c
new file mode 100644
index 0000000..b20f7a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr94942.c
@@ -0,0 +1,24 @@
+/* PR target/94942 */
+/* { dg-do compile } */
+/* { dg-options "-O -flive-range-shrinkage -ftree-vrp -mavx512vl -mno-avx512bw -Wno-div-by-zero" } */
+
+typedef unsigned __attribute__((__vector_size__(8))) U;
+typedef short __attribute__((__vector_size__(8))) V;
+typedef char __attribute__((__vector_size__(16))) W;
+typedef int __attribute__((__vector_size__(16))) Z;
+int i, j, n, o;
+W k;
+Z l;
+char m;
+
+U
+foo (U q, long long r, V s)
+{
+ Z t = (i & i - (Z){10} & 4) - (0 != j);
+ Z u = o * (j * l);
+ s -= (char)__builtin_clrsbll (n);
+ W v = (k | k >> m + (W){4}) % 0;
+ W w = v + (W)t + (W)u;
+ U x = ((union { W a; U b; })w).b + q + (U)s + (U)r;
+ return x;
+}