aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-06-04 11:20:02 +0200
committerJakub Jelinek <jakub@redhat.com>2021-06-04 11:20:02 +0200
commitb7dd2e4eeb44bc8678ecde8a6c7401de85e63561 (patch)
treecf544ef47edabc72f2243d560131be9e1f0fdcdf
parent3011f1046628d5ce5e6e5f8e917a6aea1385fdc3 (diff)
downloadgcc-b7dd2e4eeb44bc8678ecde8a6c7401de85e63561.zip
gcc-b7dd2e4eeb44bc8678ecde8a6c7401de85e63561.tar.gz
gcc-b7dd2e4eeb44bc8678ecde8a6c7401de85e63561.tar.bz2
x86: Fix ix86_expand_vector_init for V*TImode [PR100887]
We have vec_initv4tiv2ti and vec_initv2titi patterns which call ix86_expand_vector_init and assume it works for those modes. For the case of construction from two half-sized vectors, the code assumes it will always succeed, but we have only insn patterns with SImode and DImode element types. QImode and HImode element types are already handled by performing it with same sized vectors with SImode elements and the following patch extends that to V*TImode vectors. 2021-06-04 Jakub Jelinek <jakub@redhat.com> PR target/100887 * config/i386/i386-expand.c (ix86_expand_vector_init): Handle concatenation from half-sized modes with TImode elements. * gcc.target/i386/pr100887.c: New test.
-rw-r--r--gcc/config/i386/i386-expand.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/pr100887.c13
2 files changed, 20 insertions, 3 deletions
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index eb7cdb0..68bb5ab 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -14610,11 +14610,15 @@ ix86_expand_vector_init (bool mmx_ok, rtx target, rtx vals)
if (GET_MODE_NUNITS (GET_MODE (x)) * 2 == n_elts)
{
rtx ops[2] = { XVECEXP (vals, 0, 0), XVECEXP (vals, 0, 1) };
- if (inner_mode == QImode || inner_mode == HImode)
+ if (inner_mode == QImode
+ || inner_mode == HImode
+ || inner_mode == TImode)
{
unsigned int n_bits = n_elts * GET_MODE_SIZE (inner_mode);
- mode = mode_for_vector (SImode, n_bits / 4).require ();
- inner_mode = mode_for_vector (SImode, n_bits / 8).require ();
+ scalar_mode elt_mode = inner_mode == TImode ? DImode : SImode;
+ n_bits /= GET_MODE_SIZE (elt_mode);
+ mode = mode_for_vector (elt_mode, n_bits).require ();
+ inner_mode = mode_for_vector (elt_mode, n_bits / 2).require ();
ops[0] = gen_lowpart (inner_mode, ops[0]);
ops[1] = gen_lowpart (inner_mode, ops[1]);
subtarget = gen_reg_rtx (mode);
diff --git a/gcc/testsuite/gcc.target/i386/pr100887.c b/gcc/testsuite/gcc.target/i386/pr100887.c
new file mode 100644
index 0000000..1bc6d38
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100887.c
@@ -0,0 +1,13 @@
+/* PR target/100887 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-mavx512f" } */
+
+typedef unsigned __int128 U __attribute__((__vector_size__ (64)));
+typedef unsigned __int128 V __attribute__((__vector_size__ (32)));
+typedef unsigned __int128 W __attribute__((__vector_size__ (16)));
+
+W
+foo (U u, V v)
+{
+ return __builtin_shufflevector (u, v, 0);
+}