summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-22 13:36:46 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-22 13:36:46 +0000
commitba257f0b6fcf6e0afc18fbec95b0e2b5b70812dd (patch)
tree0c7f7637d1a8957491ab525f81731c05eee52b6f
parent71de77d8ba195e98400cd3fd2498e1c2c82a7ed1 (diff)
downloadgcc-ba257f0b6fcf6e0afc18fbec95b0e2b5b70812dd.tar.gz
2015-10-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/58497 * tree-vect-generic.c (ssa_uniform_vector_p): New helper. (expand_vector_operations_1): Use it. Lower operations on all uniform vectors to scalar operations if the HW supports it. * gcc.dg/tree-ssa/vector-5.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229173 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vector-5.c15
-rw-r--r--gcc/tree-vect-generic.c51
4 files changed, 69 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1e06d1a46ae..9383e1c1c92 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2015-10-22 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/58497
+ * tree-vect-generic.c (ssa_uniform_vector_p): New helper.
+ (expand_vector_operations_1): Use it. Lower operations on
+ all uniform vectors to scalar operations if the HW supports it.
+
+2015-10-22 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/19049
PR tree-optimization/65962
* tree-vect-data-refs.c (vect_analyze_group_access_1): Fall back
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 39260d6611c..2ea3d941331 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2015-10-22 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/58497
+ * gcc.dg/tree-ssa/vector-5.c: New testcase.
+
+2015-10-22 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/19049
PR tree-optimization/65962
* gcc.dg/vect/vect-strided-store-pr65962.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-5.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-5.c
new file mode 100644
index 00000000000..33350cbfe8f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-5.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+typedef int v4si __attribute__((vector_size(4*sizeof (int))));
+
+v4si v;
+int foo (int i)
+{
+ v4si v1 = (v4si) { i, i, i, i };
+ v4si v2 = (v4si) { 3, 3, 3, 3 };
+ v = v1 * v2;
+}
+
+/* The operation should be carried out as scalar op. */
+/* { dg-final { scan-tree-dump-times " \* 3;" 1 "optimized" } } */
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index a20b9afedba..20053839d2b 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -1339,6 +1339,23 @@ lower_vec_perm (gimple_stmt_iterator *gsi)
update_stmt (gsi_stmt (*gsi));
}
+/* If OP is a uniform vector return the element it is a splat from. */
+
+static tree
+ssa_uniform_vector_p (tree op)
+{
+ if (TREE_CODE (op) == VECTOR_CST
+ || TREE_CODE (op) == CONSTRUCTOR)
+ return uniform_vector_p (op);
+ if (TREE_CODE (op) == SSA_NAME)
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (op);
+ if (gimple_assign_single_p (def_stmt))
+ return uniform_vector_p (gimple_assign_rhs1 (def_stmt));
+ }
+ return NULL_TREE;
+}
+
/* Return type in which CODE operation with optab OP can be
computed. */
@@ -1505,6 +1522,29 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
if (TREE_CODE (type) != VECTOR_TYPE)
return;
+ /* If the vector operation is operating on all same vector elements
+ implement it with a scalar operation and a splat if the target
+ supports the scalar operation. */
+ tree srhs1, srhs2 = NULL_TREE;
+ if ((srhs1 = ssa_uniform_vector_p (rhs1)) != NULL_TREE
+ && (rhs2 == NULL_TREE
+ || (srhs2 = ssa_uniform_vector_p (rhs2)) != NULL_TREE)
+ /* As we query direct optabs restrict to non-convert operations. */
+ && TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (TREE_TYPE (srhs1)))
+ {
+ op = optab_for_tree_code (code, TREE_TYPE (type), optab_scalar);
+ if (optab_handler (op, TYPE_MODE (TREE_TYPE (type))) != CODE_FOR_nothing)
+ {
+ tree slhs = make_ssa_name (TREE_TYPE (srhs1));
+ gimple *repl = gimple_build_assign (slhs, code, srhs1, srhs2);
+ gsi_insert_before (gsi, repl, GSI_SAME_STMT);
+ gimple_assign_set_rhs_from_tree (gsi,
+ build_vector_from_val (type, slhs));
+ update_stmt (stmt);
+ return;
+ }
+ }
+
/* A scalar operation pretending to be a vector one. */
if (VECTOR_BOOLEAN_TYPE_P (type)
&& !VECTOR_MODE_P (TYPE_MODE (type))
@@ -1554,15 +1594,8 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (rhs2)))
{
tree first;
- gimple *def_stmt;
-
- if ((TREE_CODE (rhs2) == VECTOR_CST
- && (first = uniform_vector_p (rhs2)) != NULL_TREE)
- || (TREE_CODE (rhs2) == SSA_NAME
- && (def_stmt = SSA_NAME_DEF_STMT (rhs2))
- && gimple_assign_single_p (def_stmt)
- && (first = uniform_vector_p
- (gimple_assign_rhs1 (def_stmt))) != NULL_TREE))
+
+ if ((first = ssa_uniform_vector_p (rhs2)) != NULL_TREE)
{
gimple_assign_set_rhs2 (stmt, first);
update_stmt (stmt);