aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr86991.c20
-rw-r--r--gcc/tree-vect-loop.c45
4 files changed, 49 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2389f1c..396991d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2018-11-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/86991
+ * tree-vect-loop.c (vect_is_slp_reduction): Delay reduction
+ group building until we have successfully detected the SLP
+ reduction.
+ (vect_is_simple_reduction): Remove fixup code here.
+
2018-11-13 David Malcolm <dmalcolm@redhat.com>
* dumpfile.c (VERIFY_DUMP_ENABLED_P): New macro.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9afb5f2..b57b28c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/86991
+ * gcc.dg/pr86991.c: New testcase.
+
2018-11-13 David Malcolm <dmalcolm@redhat.com>
* gimple-loop-interchange.cc (tree_loop_interchange::interchange):
diff --git a/gcc/testsuite/gcc.dg/pr86991.c b/gcc/testsuite/gcc.dg/pr86991.c
new file mode 100644
index 0000000..5cd16e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr86991.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int b;
+extern unsigned c[];
+unsigned d;
+long e;
+
+void f()
+{
+ unsigned g, h;
+ for (; d; d += 2) {
+ g = 1;
+ for (; g; g += 3) {
+ h = 2;
+ for (; h < 6; h++)
+ c[h] = c[h] - b - ~e;
+ }
+ }
+}
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 5baf87b..dccddee 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2468,7 +2468,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi,
struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
enum tree_code code;
gimple *loop_use_stmt = NULL;
- stmt_vec_info use_stmt_info, current_stmt_info = NULL;
+ stmt_vec_info use_stmt_info;
tree lhs;
imm_use_iterator imm_iter;
use_operand_p use_p;
@@ -2478,6 +2478,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi,
if (loop != vect_loop)
return false;
+ auto_vec<stmt_vec_info, 8> reduc_chain;
lhs = PHI_RESULT (phi);
code = gimple_assign_rhs_code (first_stmt);
while (1)
@@ -2530,17 +2531,9 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi,
/* Insert USE_STMT into reduction chain. */
use_stmt_info = loop_info->lookup_stmt (loop_use_stmt);
- if (current_stmt_info)
- {
- REDUC_GROUP_NEXT_ELEMENT (current_stmt_info) = use_stmt_info;
- REDUC_GROUP_FIRST_ELEMENT (use_stmt_info)
- = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info);
- }
- else
- REDUC_GROUP_FIRST_ELEMENT (use_stmt_info) = use_stmt_info;
+ reduc_chain.safe_push (use_stmt_info);
lhs = gimple_assign_lhs (loop_use_stmt);
- current_stmt_info = use_stmt_info;
size++;
}
@@ -2550,10 +2543,9 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi,
/* Swap the operands, if needed, to make the reduction operand be the second
operand. */
lhs = PHI_RESULT (phi);
- stmt_vec_info next_stmt_info = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info);
- while (next_stmt_info)
+ for (unsigned i = 0; i < reduc_chain.length (); ++i)
{
- gassign *next_stmt = as_a <gassign *> (next_stmt_info->stmt);
+ gassign *next_stmt = as_a <gassign *> (reduc_chain[i]->stmt);
if (gimple_assign_rhs2 (next_stmt) == lhs)
{
tree op = gimple_assign_rhs1 (next_stmt);
@@ -2567,7 +2559,6 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi,
&& vect_valid_reduction_input_p (def_stmt_info))
{
lhs = gimple_assign_lhs (next_stmt);
- next_stmt_info = REDUC_GROUP_NEXT_ELEMENT (next_stmt_info);
continue;
}
@@ -2602,14 +2593,20 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi,
}
lhs = gimple_assign_lhs (next_stmt);
- next_stmt_info = REDUC_GROUP_NEXT_ELEMENT (next_stmt_info);
}
+ /* Build up the actual chain. */
+ for (unsigned i = 0; i < reduc_chain.length () - 1; ++i)
+ {
+ REDUC_GROUP_FIRST_ELEMENT (reduc_chain[i]) = reduc_chain[0];
+ REDUC_GROUP_NEXT_ELEMENT (reduc_chain[i]) = reduc_chain[i+1];
+ }
+ REDUC_GROUP_FIRST_ELEMENT (reduc_chain.last ()) = reduc_chain[0];
+ REDUC_GROUP_NEXT_ELEMENT (reduc_chain.last ()) = NULL;
+
/* Save the chain for further analysis in SLP detection. */
- stmt_vec_info first_stmt_info
- = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info);
- LOOP_VINFO_REDUCTION_CHAINS (loop_info).safe_push (first_stmt_info);
- REDUC_GROUP_SIZE (first_stmt_info) = size;
+ LOOP_VINFO_REDUCTION_CHAINS (loop_info).safe_push (reduc_chain[0]);
+ REDUC_GROUP_SIZE (reduc_chain[0]) = size;
return true;
}
@@ -3200,16 +3197,6 @@ vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info,
return def_stmt_info;
}
- /* Dissolve group eventually half-built by vect_is_slp_reduction. */
- stmt_vec_info first = REDUC_GROUP_FIRST_ELEMENT (def_stmt_info);
- while (first)
- {
- stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (first);
- REDUC_GROUP_FIRST_ELEMENT (first) = NULL;
- REDUC_GROUP_NEXT_ELEMENT (first) = NULL;
- first = next;
- }
-
/* Look for the expression computing loop_arg from loop PHI result. */
if (check_reduction_path (vect_location, loop, phi, loop_arg, code))
return def_stmt_info;