aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/testsuite/ChangeLog18
-rw-r--r--gcc/testsuite/g++.dg/pr88217.C18
-rw-r--r--gcc/testsuite/g++.dg/torture/pr88149.C63
-rw-r--r--gcc/testsuite/gcc.dg/pr88427.c20
-rw-r--r--gcc/tree-vect-slp.c41
-rw-r--r--gcc/vr-values.c8
7 files changed, 183 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 23336eb..f1127d7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2019-02-08 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2018-12-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/88427
+ * vr-values.c (vr_values::extract_range_from_phi_node):
+ Handle symbolic ranges conservatively when trying to drop
+ to Inf +- 1.
+
+ 2018-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/88217
+ * vr-values.c (vr_values::extract_range_from_phi_node): Make
+ sure to handle results > +INF and < -INF correctly when
+ trying to drop down to +INF - 1 or -INF + 1.
+
+ 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-02-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d766e41..1ddb054 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,21 @@
+2019-02-08 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2018-12-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/88427
+ * gcc.dg/pr88427.c: New testcase.
+
+ 2018-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/88217
+ * g++.dg/pr88217.C: New testcase.
+
+ 2018-11-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/88149
+ * g++.dg/torture/pr88149.C: New testcase.
+
2019-02-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
diff --git a/gcc/testsuite/g++.dg/pr88217.C b/gcc/testsuite/g++.dg/pr88217.C
new file mode 100644
index 0000000..b0506ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr88217.C
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -fstrict-enums -fno-tree-forwprop -fno-tree-fre" }
+
+extern "C" int printf (const char *, ...);
+
+enum E { e1, e2, e3, X };
+E operator*(E e) { return e; }
+E begin(E e) { return e; }
+E end(E e) { return X; }
+E operator++(E& e) { return e = E(e+1); }
+
+int main()
+{
+ for (auto e: e1)
+ {
+ printf ("%d ", e);
+ }
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr88149.C b/gcc/testsuite/g++.dg/torture/pr88149.C
new file mode 100644
index 0000000..2700a09
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr88149.C
@@ -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;
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr88427.c b/gcc/testsuite/gcc.dg/pr88427.c
new file mode 100644
index 0000000..60b179c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88427.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-dce -fno-tree-fre -Wno-div-by-zero" } */
+
+void
+uj (int eq, int s4)
+{
+ short int tm = 0;
+
+ for (;;)
+ if (eq == s4)
+ {
+ tm += !!s4;
+ if (tm == s4)
+ {
+ eq += tm;
+ for (;;)
+ eq /= 0;
+ }
+ }
+}
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 48ed96b..625e99a 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2819,21 +2819,48 @@ vect_slp_analyze_node_operations (vec_info *vinfo, slp_tree node,
= vect_get_num_vectors (vf * group_size, vectype);
}
+ /* ??? 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)[0]));
+
/* 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)[0]))
= SLP_TREE_DEF_TYPE (child);
- bool res = vect_analyze_stmt (stmt, &dummy, node, node_instance);
+
+ /* Check everything worked out. */
+ bool res = true;
+ 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)[0]))
+ != SLP_TREE_DEF_TYPE (child))
+ res = false;
+ }
+ else if (STMT_VINFO_DEF_TYPE
+ (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[0])) != 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, node_instance);
+
/* 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)[0]))
- = vect_internal_def;
- if (! res)
- return false;
+ STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[0]))
+ = dt[j];
- return true;
+ return res;
}
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index b1f587d..22243e9 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -2901,7 +2901,9 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
if (cmp_min < 0)
vr_result->min = lhs_vr->min;
else if (cmp_min > 0
- && !vrp_val_is_min (vr_result->min))
+ && (TREE_CODE (vr_result->min) != INTEGER_CST
+ || tree_int_cst_lt (vrp_val_min (TREE_TYPE (vr_result->min)),
+ vr_result->min)))
vr_result->min
= int_const_binop (PLUS_EXPR,
vrp_val_min (TREE_TYPE (vr_result->min)),
@@ -2911,7 +2913,9 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
if (cmp_max > 0)
vr_result->max = lhs_vr->max;
else if (cmp_max < 0
- && !vrp_val_is_max (vr_result->max))
+ && (TREE_CODE (vr_result->max) != INTEGER_CST
+ || tree_int_cst_lt (vr_result->max,
+ vrp_val_max (TREE_TYPE (vr_result->min)))))
vr_result->max
= int_const_binop (MINUS_EXPR,
vrp_val_max (TREE_TYPE (vr_result->min)),