tree-optimization/101028 - fix endless SLP reassoc discovery
authorRichard Biener <rguenther@suse.de>
Fri, 11 Jun 2021 11:36:26 +0000 (13:36 +0200)
committerRichard Biener <rguenther@suse.de>
Fri, 11 Jun 2021 11:43:18 +0000 (13:43 +0200)
This fixes a missing clearing of mismatched lanes from the
fatal fail path in SLP reassoc discovery in the most conservative
way.

2021-06-11  Richard Biener  <rguenther@suse.de>

PR tree-optimization/101028
* tree-vect-slp.c (vect_build_slp_tree_2): When SLP
reassoc discovery fails fatally, mark appropriate lanes
in matches[] so.

* gcc.dg/pr101028.c: New testcase.

gcc/testsuite/gcc.dg/pr101028.c [new file with mode: 0644]
gcc/tree-vect-slp.c

diff --git a/gcc/testsuite/gcc.dg/pr101028.c b/gcc/testsuite/gcc.dg/pr101028.c
new file mode 100644 (file)
index 0000000..501e6af
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+
+typedef struct {
+  double x, y;
+} PointInfo;
+
+typedef struct {
+  PointInfo point;
+} PrimitiveInfo;
+
+int TraceBezier_alpha, TraceBezier_i;
+double TraceBezier_weight;
+PointInfo *TraceBezier_points;
+PrimitiveInfo *TraceBezier_primitive_info;
+
+void TracePath() {
+  double *coefficients;
+  PointInfo point;
+  long j;
+  for (; TraceBezier_i; TraceBezier_i++) {
+    point.x = point.y = TraceBezier_alpha = 1.0;
+    j = 0;
+    for (; j < 4; j++) {
+      point.x += TraceBezier_alpha * coefficients[j] *
+                 TraceBezier_primitive_info->point.x;
+      point.y += TraceBezier_alpha * TraceBezier_primitive_info->point.y;
+      TraceBezier_alpha *= TraceBezier_weight;
+      TraceBezier_primitive_info++;
+    }
+    TraceBezier_points[TraceBezier_i] = point;
+    TraceBezier_weight += 1.0;
+  }
+}
index 897bd6f..9ded585 100644 (file)
@@ -1849,14 +1849,28 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
                 mismatch still hard-FAIL.  */
              if (chain_len == 0)
                hard_fail = false;
+             else
+               {
+                 matches[lane] = false;
+                 /* ???  We might want to process the other lanes, but
+                    make sure to not give false matching hints to the
+                    caller for lanes we did not process.  */
+                 if (lane != group_size - 1)
+                   matches[0] = false;
+               }
              break;
            }
          else if (chain_len == 0)
            chain_len = chain.length ();
          else if (chain.length () != chain_len)
-           /* ???  Here we could slip in magic to compensate with
-              neutral operands.  */
-           break;
+           {
+             /* ???  Here we could slip in magic to compensate with
+                neutral operands.  */
+             matches[lane] = false;
+             if (lane != group_size - 1)
+               matches[0] = false;
+             break;
+           }
          chains.quick_push (chain.copy ());
          chain.truncate (0);
        }
@@ -1905,6 +1919,9 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
                    dump_printf_loc (MSG_NOTE, vect_location,
                                     "giving up on chain due to mismatched "
                                     "def types\n");
+                 matches[lane] = false;
+                 if (lane != group_size - 1)
+                   matches[0] = false;
                  goto out;
                }
              if (dt == vect_constant_def
@@ -1983,6 +2000,9 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
                        dump_printf_loc (MSG_NOTE, vect_location,
                                         "failed to match up op %d\n", n);
                      op_stmts.release ();
+                     matches[lane] = false;
+                     if (lane != group_size - 1)
+                       matches[0] = false;
                      goto out;
                    }
                  if (dump_enabled_p ())