Use vec_perm_builder::series_p in shift_amt_for_vec_perm_mask
This patch makes shift_amt_for_vec_perm_mask use series_p to check for the simple case of a natural linear series before falling back to testing each element individually. The series_p test works with variable-length vectors but testing every individual element doesn't. 2018-01-02 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * optabs.c (shift_amt_for_vec_perm_mask): Try using series_p before testing each element individually. * tree-vect-generic.c (lower_vec_perm): Likewise. From-SVN: r256099
This commit is contained in:
parent
1a1c441dbe
commit
d386748304
@ -1,3 +1,9 @@
|
||||
2018-01-02 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* optabs.c (shift_amt_for_vec_perm_mask): Try using series_p
|
||||
before testing each element individually.
|
||||
* tree-vect-generic.c (lower_vec_perm): Likewise.
|
||||
|
||||
2018-01-02 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* selftest.h (selftest::vec_perm_indices_c_tests): Declare.
|
||||
|
22
gcc/optabs.c
22
gcc/optabs.c
@ -5395,20 +5395,20 @@ vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
|
||||
static rtx
|
||||
shift_amt_for_vec_perm_mask (machine_mode mode, const vec_perm_indices &sel)
|
||||
{
|
||||
unsigned int i, first, nelt = GET_MODE_NUNITS (mode);
|
||||
unsigned int nelt = GET_MODE_NUNITS (mode);
|
||||
unsigned int bitsize = GET_MODE_UNIT_BITSIZE (mode);
|
||||
|
||||
first = sel[0];
|
||||
unsigned int first = sel[0];
|
||||
if (first >= nelt)
|
||||
return NULL_RTX;
|
||||
for (i = 1; i < nelt; i++)
|
||||
{
|
||||
int idx = sel[i];
|
||||
unsigned int expected = i + first;
|
||||
/* Indices into the second vector are all equivalent. */
|
||||
if (idx < 0 || (MIN (nelt, (unsigned) idx) != MIN (nelt, expected)))
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
if (!sel.series_p (0, 1, first, 1))
|
||||
for (unsigned int i = 1; i < nelt; i++)
|
||||
{
|
||||
unsigned int expected = i + first;
|
||||
/* Indices into the second vector are all equivalent. */
|
||||
if (MIN (nelt, sel[i]) != MIN (nelt, expected))
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
return gen_int_shift_amount (mode, first * bitsize);
|
||||
}
|
||||
|
@ -1320,15 +1320,20 @@ lower_vec_perm (gimple_stmt_iterator *gsi)
|
||||
&& indices[0]
|
||||
&& indices[0] < elements)
|
||||
{
|
||||
for (i = 1; i < elements; ++i)
|
||||
bool ok_p = indices.series_p (0, 1, indices[0], 1);
|
||||
if (!ok_p)
|
||||
{
|
||||
unsigned int expected = i + indices[0];
|
||||
/* Indices into the second vector are all equivalent. */
|
||||
if (MIN (elements, (unsigned) indices[i])
|
||||
!= MIN (elements, expected))
|
||||
break;
|
||||
for (i = 1; i < elements; ++i)
|
||||
{
|
||||
unsigned int expected = i + indices[0];
|
||||
/* Indices into the second vector are all equivalent. */
|
||||
if (MIN (elements, (unsigned) indices[i])
|
||||
!= MIN (elements, expected))
|
||||
break;
|
||||
}
|
||||
ok_p = i == elements;
|
||||
}
|
||||
if (i == elements)
|
||||
if (ok_p)
|
||||
{
|
||||
gimple_assign_set_rhs3 (stmt, mask);
|
||||
update_stmt (stmt);
|
||||
|
Loading…
x
Reference in New Issue
Block a user