diff options
author | Richard Biener <rguenther@suse.de> | 2015-10-22 13:36:46 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-10-22 13:36:46 +0000 |
commit | 975b6ff3d722800c911461f3cd9b3408623dff96 (patch) | |
tree | 0c7f7637d1a8957491ab525f81731c05eee52b6f /gcc | |
parent | 90a7a1b5b2c551158ccddbaad17d8b8021faa409 (diff) | |
download | gcc-975b6ff3d722800c911461f3cd9b3408623dff96.zip gcc-975b6ff3d722800c911461f3cd9b3408623dff96.tar.gz gcc-975b6ff3d722800c911461f3cd9b3408623dff96.tar.bz2 |
re PR tree-optimization/58497 (SLP vectorizes identical operations)
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.
From-SVN: r229173
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vector-5.c | 15 | ||||
-rw-r--r-- | gcc/tree-vect-generic.c | 51 |
4 files changed, 69 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1e06d1a..9383e1c 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 39260d6..2ea3d94 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 0000000..33350cbfe --- /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 a20b9af..2005383 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); |