On Fri, 15 Nov 2019, Richard Biener wrote:

> 
> The following fixes PR92512, we were failing to disqualify
> _2 < 1 ? _2 : 2 with _2 being part of the reduction chain.
> 
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

And the following is what I committed.

Richard.

2019-11-15  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/92512
        * tree-vect-loop.c (check_reduction_path): Fix operand index
        computability check.  Add check for second use in COND_EXPRs.

        * gcc.dg/torture/pr92512.c: New testcase.

Index: gcc/testsuite/gcc.dg/torture/pr92512.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr92512.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr92512.c      (working copy)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize" } */
+
+long int
+nl (long int fy, int k3, int zr)
+{
+  while (k3 < 1)
+    {
+      if (zr == 0)
+        fy = 0;
+
+      fy *= fy < zr;
+      ++k3;
+    }
+
+  return fy;
+}
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c        (revision 278280)
+++ gcc/tree-vect-loop.c        (working copy)
@@ -2813,9 +2813,11 @@ pop:
          /* The following make sure we can compute the operand index
             easily plus it mostly disallows chaining via COND_EXPR condition
             operands.  */
-         || (gimple_assign_rhs1 (use_stmt) != op
-             && gimple_assign_rhs2 (use_stmt) != op
-             && gimple_assign_rhs3 (use_stmt) != op))
+         || (gimple_assign_rhs1_ptr (use_stmt) != path[i].second->use
+             && (gimple_num_ops (use_stmt) <= 2
+                 || gimple_assign_rhs2_ptr (use_stmt) != path[i].second->use)
+             && (gimple_num_ops (use_stmt) <= 3
+                 || gimple_assign_rhs3_ptr (use_stmt) != path[i].second->use)))
        {
          fail = true;
          break;
@@ -2828,7 +2830,18 @@ pop:
       FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op)
        if (!is_gimple_debug (op_use_stmt)
            && flow_bb_inside_loop_p (loop, gimple_bb (op_use_stmt)))
-         cnt++;
+         {
+           /* We want to allow x + x but not x < 1 ? x : 2.  */
+           if (is_gimple_assign (op_use_stmt)
+               && gimple_assign_rhs_code (op_use_stmt) == COND_EXPR)
+             {
+               use_operand_p use_p;
+               FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
+                 cnt++;
+             }
+           else
+             cnt++;
+         }
       if (cnt != 1)
        {
          fail = true;

Reply via email to