aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-11 13:38:49 +0600
committerJakub Jelinek <jakub@gcc.gnu.org>2018-05-11 09:38:49 +0200
commit5a599c460e3846df80aaabd2b4629544337167ba (patch)
tree6e1b0fef494b7c8af393089dd92554f917016e10 /gcc
parent19916065b7fb26bbb36f7bbe5688ae2c1661dec3 (diff)
downloadgcc-5a599c460e3846df80aaabd2b4629544337167ba.zip
gcc-5a599c460e3846df80aaabd2b4629544337167ba.tar.gz
gcc-5a599c460e3846df80aaabd2b4629544337167ba.tar.bz2
re PR tree-optimization/85692 (Two source permute not used for vector initialization)
PR tree-optimization/85692 * tree-ssa-forwprop.c (simplify_vector_constructor): Try two source permute as well. * gcc.target/i386/pr85692.c: New test. Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r260155
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr85692.c18
-rw-r--r--gcc/tree-ssa-forwprop.c67
4 files changed, 72 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 75ed3b3..01d3b18 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2018-05-11 Allan Sandfeld Jensen <allan.jensen@qt.io>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/85692
+ * tree-ssa-forwprop.c (simplify_vector_constructor): Try two
+ source permute as well.
+
2018-05-11 Martin Liska <mliska@suse.cz>
PR sanitizer/85556
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ee9f633..1591122 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2018-05-11 Allan Sandfeld Jensen <allan.jensen@qt.io>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/85692
+ * gcc.target/i386/pr85692.c: New test.
+
2018-05-11 Martin Liska <mliska@suse.cz>
PR sanitizer/85556
diff --git a/gcc/testsuite/gcc.target/i386/pr85692.c b/gcc/testsuite/gcc.target/i386/pr85692.c
new file mode 100644
index 0000000..45594ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr85692.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.1" } */
+/* { dg-final { scan-assembler "unpcklps" } } */
+/* { dg-final { scan-assembler "blendps" } } */
+/* { dg-final { scan-assembler-not "shufps" } } */
+/* { dg-final { scan-assembler-not "unpckhps" } } */
+
+typedef float v4sf __attribute__ ((vector_size (16)));
+
+v4sf unpcklps(v4sf a, v4sf b)
+{
+ return (v4sf){a[0],b[0],a[1],b[1]};
+}
+
+v4sf blendps(v4sf a, v4sf b)
+{
+ return (v4sf){a[0],b[1],a[2],b[3]};
+}
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 58ec6b4..2efb5ac 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2004,7 +2004,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
{
gimple *stmt = gsi_stmt (*gsi);
gimple *def_stmt;
- tree op, op2, orig, type, elem_type;
+ tree op, op2, orig[2], type, elem_type;
unsigned elem_size, i;
unsigned HOST_WIDE_INT nelts;
enum tree_code code, conv_code;
@@ -2023,7 +2023,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
vec_perm_builder sel (nelts, nelts, 1);
- orig = NULL;
+ orig[0] = NULL;
+ orig[1] = NULL;
conv_code = ERROR_MARK;
maybe_ident = true;
FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
@@ -2063,25 +2064,35 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
return false;
op1 = gimple_assign_rhs1 (def_stmt);
ref = TREE_OPERAND (op1, 0);
- if (orig)
+ unsigned int j;
+ for (j = 0; j < 2; ++j)
{
- if (ref != orig)
- return false;
- }
- else
- {
- if (TREE_CODE (ref) != SSA_NAME)
- return false;
- if (! VECTOR_TYPE_P (TREE_TYPE (ref))
- || ! useless_type_conversion_p (TREE_TYPE (op1),
- TREE_TYPE (TREE_TYPE (ref))))
- return false;
- orig = ref;
+ if (!orig[j])
+ {
+ if (TREE_CODE (ref) != SSA_NAME)
+ return false;
+ if (! VECTOR_TYPE_P (TREE_TYPE (ref))
+ || ! useless_type_conversion_p (TREE_TYPE (op1),
+ TREE_TYPE (TREE_TYPE (ref))))
+ return false;
+ if (j && !useless_type_conversion_p (TREE_TYPE (orig[0]),
+ TREE_TYPE (ref)))
+ return false;
+ orig[j] = ref;
+ break;
+ }
+ else if (ref == orig[j])
+ break;
}
+ if (j == 2)
+ return false;
+
unsigned int elt;
if (maybe_ne (bit_field_size (op1), elem_size)
|| !constant_multiple_p (bit_field_offset (op1), elem_size, &elt))
return false;
+ if (j)
+ elt += nelts;
if (elt != i)
maybe_ident = false;
sel.quick_push (elt);
@@ -2089,14 +2100,15 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
if (i < nelts)
return false;
- if (! VECTOR_TYPE_P (TREE_TYPE (orig))
+ if (! VECTOR_TYPE_P (TREE_TYPE (orig[0]))
|| maybe_ne (TYPE_VECTOR_SUBPARTS (type),
- TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig))))
+ TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig[0]))))
return false;
tree tem;
if (conv_code != ERROR_MARK
- && (! supportable_convert_operation (conv_code, type, TREE_TYPE (orig),
+ && (! supportable_convert_operation (conv_code, type,
+ TREE_TYPE (orig[0]),
&tem, &conv_code)
|| conv_code == CALL_EXPR))
return false;
@@ -2104,16 +2116,16 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
if (maybe_ident)
{
if (conv_code == ERROR_MARK)
- gimple_assign_set_rhs_from_tree (gsi, orig);
+ gimple_assign_set_rhs_from_tree (gsi, orig[0]);
else
- gimple_assign_set_rhs_with_ops (gsi, conv_code, orig,
+ gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0],
NULL_TREE, NULL_TREE);
}
else
{
tree mask_type;
- vec_perm_indices indices (sel, 1, nelts);
+ vec_perm_indices indices (sel, orig[1] ? 2 : 1, nelts);
if (!can_vec_perm_const_p (TYPE_MODE (type), indices))
return false;
mask_type
@@ -2124,16 +2136,19 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
GET_MODE_SIZE (TYPE_MODE (type))))
return false;
op2 = vec_perm_indices_to_tree (mask_type, indices);
+ if (!orig[1])
+ orig[1] = orig[0];
if (conv_code == ERROR_MARK)
- gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2);
+ gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig[0],
+ orig[1], op2);
else
{
gimple *perm
- = gimple_build_assign (make_ssa_name (TREE_TYPE (orig)),
- VEC_PERM_EXPR, orig, orig, op2);
- orig = gimple_assign_lhs (perm);
+ = gimple_build_assign (make_ssa_name (TREE_TYPE (orig[0])),
+ VEC_PERM_EXPR, orig[0], orig[1], op2);
+ orig[0] = gimple_assign_lhs (perm);
gsi_insert_before (gsi, perm, GSI_SAME_STMT);
- gimple_assign_set_rhs_with_ops (gsi, conv_code, orig,
+ gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0],
NULL_TREE, NULL_TREE);
}
}