PR81815: Invalid conditional reduction
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 16 Aug 2017 07:51:13 +0000 (07:51 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 16 Aug 2017 07:51:13 +0000 (07:51 +0000)
We weren't checking whether the phi in a conditional reduction was
used by the condition itself (which isn't a case we handle).

2017-08-11  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
PR tree-optimization/81835
* tree-vect-loop.c (vect_is_simple_reduction): Simply checks for
the phi SSA_NAME.  Check that the condition in a COND_EXPR does
not depend on the phi.

gcc/testsuite/
PR tree-optimization/81835
* gcc.dg/vect/pr81815.c: New test.

From-SVN: r251117

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr81815.c [new file with mode: 0644]
gcc/tree-vect-loop.c

index 14768398af8990843c3470e4ff266847fdd74115..d86b59f36716ece915a23d2f0fb2e635d8dc4514 100644 (file)
@@ -1,3 +1,10 @@
+2017-08-16  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       PR tree-optimization/81835
+       * tree-vect-loop.c (vect_is_simple_reduction): Simply checks for
+       the phi SSA_NAME.  Check that the condition in a COND_EXPR does
+       not depend on the phi.
+
 2017-08-16  Alan Modra  <amodra@gmail.com>
 
        * config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): Delete
index 835a8f4af81ea4404ec982320209de2a58e74d68..fe2ea0221f8502afb55f3a2bacbea84b5bfbc91c 100644 (file)
@@ -1,3 +1,8 @@
+2017-08-16  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       PR tree-optimization/81835
+       * gcc.dg/vect/pr81815.c: New test.
+
 2017-08-15  Joseph Myers  <joseph@codesourcery.com>
 
        PR target/78460
diff --git a/gcc/testsuite/gcc.dg/vect/pr81815.c b/gcc/testsuite/gcc.dg/vect/pr81815.c
new file mode 100644 (file)
index 0000000..1eb7c59
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+
+int __attribute__ ((noinline, noclone))
+f (int *x, int n)
+{
+  int b = 13;
+  for (int i = 0; i < n; ++i)
+    {
+      int next = x[i];
+      b = b < 100 ? next : 200;
+    }
+  return b;
+}
+
+static int res[32];
+
+int
+main (void)
+{
+  for (int i = 0; i < 32; ++i)
+    res[i] = i;
+  res[15] = 100;
+  if (f (res, 32) != 200)
+    __builtin_abort ();
+  return 0;
+}
index 8b2a61e733be4134ecbdfca77b7cd86f1f35318f..906323b4d765421279b480551669c90422aa0dd4 100644 (file)
@@ -2690,15 +2690,15 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
   *double_reduc = false;
   *v_reduc_type = TREE_CODE_REDUCTION;
 
-  name = PHI_RESULT (phi);
+  tree phi_name = PHI_RESULT (phi);
   /* ???  If there are no uses of the PHI result the inner loop reduction
      won't be detected as possibly double-reduction by vectorizable_reduction
      because that tries to walk the PHI arg from the preheader edge which
      can be constant.  See PR60382.  */
-  if (has_zero_uses (name))
+  if (has_zero_uses (phi_name))
     return NULL;
   nloop_uses = 0;
-  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
+  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, phi_name)
     {
       gimple *use_stmt = USE_STMT (use_p);
       if (is_gimple_debug (use_stmt))
@@ -2847,10 +2847,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
      simply rewriting this into "res += -x[i]".  Avoid changing
      gimple instruction for the first simple tests and only do this
      if we're allowed to change code at all.  */
-  if (code == MINUS_EXPR
-      && ! ((op1 = gimple_assign_rhs2 (def_stmt))
-           && TREE_CODE (op1) == SSA_NAME
-           && SSA_NAME_DEF_STMT (op1) == phi))
+  if (code == MINUS_EXPR && gimple_assign_rhs2 (def_stmt) != phi_name)
     code = PLUS_EXPR;
 
   if (code == COND_EXPR)
@@ -2864,6 +2861,14 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
           op4 = TREE_OPERAND (op3, 1);
           op3 = TREE_OPERAND (op3, 0);
         }
+      if (op3 == phi_name || op4 == phi_name)
+       {
+         if (dump_enabled_p ())
+           report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
+                           "reduction: condition depends on previous"
+                           " iteration: ");
+         return NULL;
+       }
 
       op1 = gimple_assign_rhs2 (def_stmt);
       op2 = gimple_assign_rhs3 (def_stmt);