diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/i386/i386-expand.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr100887.c | 13 |
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); +} |