re PR tree-optimization/92512 (ICE in gimple_op, at gimple.h:2436)
authorRichard Biener <rguenther@suse.de>
Fri, 15 Nov 2019 13:52:09 +0000 (13:52 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 15 Nov 2019 13:52:09 +0000 (13:52 +0000)
2019-11-15  Richard Biener  <rguenther@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.

From-SVN: r278293

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

index c2d33558cd112c80e0812f685096e02b01bffed9..22fe571eec62220963402d8fd083deb7a110c804 100644 (file)
@@ -1,3 +1,9 @@
+2019-11-15  Richard Biener  <rguenther@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.
+
 2019-11-15  Richard Sandiford  <richard.sandiford@arm.com>
 
        PR target/92515
index 4377c4c38c1ca45b65652b8aa9d3fe9784eeaa1f..82f559bd04f7d10277d62586f9f5571aa7099b7e 100644 (file)
@@ -1,3 +1,8 @@
+2019-11-15  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/92512
+       * gcc.dg/torture/pr92512.c: New testcase.
+
 2019-11-15  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/92324
diff --git a/gcc/testsuite/gcc.dg/torture/pr92512.c b/gcc/testsuite/gcc.dg/torture/pr92512.c
new file mode 100644 (file)
index 0000000..2d873ad
--- /dev/null
@@ -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 389ef1706070298bf490eed8e138b1cec8aa0ba4..e6ba91c858bb3f124b3c64f0d49ee10de0f09119 100644 (file)
@@ -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;