]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR tree-optimization/88149 (ICE in vect_transform_stmt since r265959)
authorRichard Biener <rguenther@suse.de>
Wed, 4 Sep 2019 10:51:02 +0000 (10:51 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 4 Sep 2019 10:51:02 +0000 (10:51 +0000)
2019-09-04  Richard Biener  <rguenther@suse.de>

Backport from mainline
2018-11-23  Richard Biener  <rguenther@suse.de>

PR tree-optimization/88149
* tree-vect-slp.c (vect_slp_analyze_node_operations): Detect
the case where there are two different def types for the
same operand at different operand position in the same stmt.

* g++.dg/torture/pr88149.C: New testcase.

From-SVN: r275370

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr88149.C [new file with mode: 0644]
gcc/tree-vect-slp.c

index 774808a66001d3b61d1488132cdf40591c2cda08..f666940c6076ef631d7dba4671ff791e5be4d74d 100644 (file)
@@ -1,3 +1,13 @@
+2019-09-04  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2018-11-23  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/88149
+       * tree-vect-slp.c (vect_slp_analyze_node_operations): Detect
+       the case where there are two different def types for the
+       same operand at different operand position in the same stmt.
+
 2019-09-04  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
index 21443a52fe0e911d258e1493db4e79e5cd1b907c..1e848f2b3b578e86fbc961d9a3031923dfb2b91a 100644 (file)
@@ -1,3 +1,11 @@
+2019-09-04  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2018-11-23  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/88149
+       * g++.dg/torture/pr88149.C: New testcase.
+
 2019-09-04  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
diff --git a/gcc/testsuite/g++.dg/torture/pr88149.C b/gcc/testsuite/g++.dg/torture/pr88149.C
new file mode 100644 (file)
index 0000000..2700a09
--- /dev/null
@@ -0,0 +1,63 @@
+// { dg-do compile }
+// { dg-additional-options "-ftree-vectorize" }
+
+template <typename> struct a;
+template <typename b> struct a<b *> {
+  typedef long c;
+  typedef b &d;
+};
+template <typename e> class f {
+  e ab;
+  typedef a<e> ac;
+
+public:
+  typename ac::d operator[](typename ac::c o) { return ab[o]; }
+};
+template <typename> struct au;
+template <typename b> au<b> operator+(au<b> o, au<b> p2) {
+  au<b> ax = o;
+  ax += p2;
+  return ax;
+}
+template <typename b> au<b> operator-(au<b> o, au<b> p2) {
+  au<b> ax = o;
+  ax -= p2;
+  return ax;
+}
+template <typename b> au<b> operator*(au<b>, au<b> &p2) {
+  au<b> ax;
+  ax *= p2;
+  return ax;
+}
+template <> struct au<double> {
+  double p() { return __real__ az; }
+  double q() { return __imag__ az; }
+  void operator+=(au o) {
+    az += o.p();
+    __imag__ az += o.q();
+  }
+  void operator-=(au o) {
+    az -= o.p();
+    __imag__ az -= o.q();
+  }
+  void operator*=(au &o) {
+    _Complex bd = o.p();
+    __imag__ bd = o.q();
+    az *= bd;
+  }
+  _Complex az;
+};
+long bm, m;
+f<au<double> *> g;
+au<double> h, i, l;
+void bn() {
+  au<double> bq;
+  for (long k; m;) {
+    au<double> br;
+    for (long j = 0; j < bm; ++j) {
+      au<double> n = br * h;
+      i = l + n;
+      g[k] = l - bq;
+    }
+  }
+}
index e2f1c6c7096c59159405897a68ddddbe4b46518d..6ae43b932082beff7e0e710a57a50318a6ca7fdb 100644 (file)
@@ -2482,17 +2482,47 @@ vect_slp_analyze_node_operations (slp_tree node)
       gcc_assert (stmt_info);
       gcc_assert (STMT_SLP_TYPE (stmt_info) != loop_vect);
 
+      /* ???  We have to catch the case late where two first scalar stmts appear
+        in multiple SLP children with different def type and fail.  Remember
+        original def types first since SLP_TREE_DEF_TYPE doesn't necessarily
+        match it when that is vect_internal_def.  */
+      auto_vec<vect_def_type, 4> dt;
+      dt.safe_grow (SLP_TREE_CHILDREN (node).length ());
+      FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
+       dt[j]
+         = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i]));
+
       /* Push SLP node def-type to stmt operands.  */
       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
        if (SLP_TREE_DEF_TYPE (child) != vect_internal_def)
          STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i]))
            = SLP_TREE_DEF_TYPE (child);
-      res = vect_analyze_stmt (stmt, &dummy, node);
+
+      /* Check everything worked out.  */
+      FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
+       if (SLP_TREE_DEF_TYPE (child) != vect_internal_def)
+         {
+           if (STMT_VINFO_DEF_TYPE
+                 (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i]))
+               != SLP_TREE_DEF_TYPE (child))
+             res = false;
+         }
+       else if (STMT_VINFO_DEF_TYPE
+                  (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i])) != dt[j])
+         res = false;
+      if (!res && dump_enabled_p ())
+       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                        "not vectorized: same operand with different "
+                        "def type in stmt.\n");
+
+      if (res)
+       res = vect_analyze_stmt (stmt, &dummy, node);
+
       /* Restore def-types.  */
       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
        if (SLP_TREE_DEF_TYPE (child) != vect_internal_def)
          STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[i]))
-           = vect_internal_def;
+           = dt[j];
       if (! res)
        break;
     }