Canonicalize vec_perm index to make the first index come from the first vector.

Fix unexpected non-canon form from gimple vector selector.

gcc/ChangeLog:

	PR target/107271
	* config/i386/i386-expand.cc (ix86_vec_perm_index_canon): New.
	(expand_vec_perm_shufps_shufps): Call
	ix86_vec_perm_index_canon

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr107271.c: New test.
This commit is contained in:
liuhongt 2022-10-18 16:58:52 +08:00
parent 21de009f74
commit 1442e2031e
2 changed files with 33 additions and 0 deletions

View file

@ -19604,6 +19604,22 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
return false;
}
/* Canonicalize vec_perm index to make the first index
always comes from the first vector. */
static void
ix86_vec_perm_index_canon (struct expand_vec_perm_d *d)
{
unsigned nelt = d->nelt;
if (d->perm[0] < nelt)
return;
for (unsigned i = 0; i != nelt; i++)
d->perm[i] = (d->perm[i] + nelt) % (2 * nelt);
std::swap (d->op0, d->op1);
return;
}
/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D
in terms of a pair of shufps+ shufps/pshufd instructions. */
static bool
@ -19621,6 +19637,7 @@ expand_vec_perm_shufps_shufps (struct expand_vec_perm_d *d)
if (d->testing_p)
return true;
ix86_vec_perm_index_canon (d);
for (i = 0; i < 4; ++i)
count += d->perm[i] > 3 ? 1 : 0;

View file

@ -0,0 +1,16 @@
/* { dg-do compile } */
/* { dg-options "-O0" } */
typedef int __attribute__((__vector_size__ (16))) V;
static inline __attribute__((__always_inline__)) V
bar (V v128u32_0)
{
return __builtin_shuffle ((V){}, v128u32_0, v128u32_0);
}
V
foo (void)
{
return bar ((V){7, 4, 4});
}