diff options
-rw-r--r-- | gcc/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/pr88217.C | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr88149.C | 63 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr88427.c | 20 | ||||
-rw-r--r-- | gcc/tree-vect-slp.c | 41 | ||||
-rw-r--r-- | gcc/vr-values.c | 8 |
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)), |