aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-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);
+}