From: Richard Biener Date: Thu, 26 Jan 2017 08:16:37 +0000 (+0000) Subject: backport: [multiple changes] X-Git-Tag: releases/gcc-5.5.0~557 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92763b509e67616f446e6d21e780f1aa727e75b9;p=thirdparty%2Fgcc.git backport: [multiple changes] 2017-01-26 Richard Biener Backport from mainline 2016-09-27 Richard Biener PR tree-optimization/77745 * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): When removing redundant stores make sure to check compatibility of the TBAA state for downstream accesses. * tree-ssa-sccvn.c (visit_reference_op_store): Likewise for when value-numbering virtual operands for store matches. * g++.dg/torture/pr77745.C: New testcase. 2016-09-29 Richard Biener PR tree-optimization/77768 * tree-ssa-sccvn.c (visit_reference_op_store): Properly deal with stores to a place we know has a constant value. * tree-vrp.c (set_defs_to_varying): New helper avoiding writing to vr_const_varying. (vrp_initialize): Call it. (vrp_visit_stmt): Likewise. (evrp_dom_walker::before_dom_children): Likewise. * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): Handle stores to readonly memory when removing redundant stores. * gcc.dg/torture/pr77768.c: New testcase. From-SVN: r244918 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b241a85663e2..84f84e528bcc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2017-01-26 Richard Biener + + Backport from mainline + 2016-09-27 Richard Biener + + PR tree-optimization/77745 + * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): + When removing redundant stores make sure to check compatibility + of the TBAA state for downstream accesses. + * tree-ssa-sccvn.c (visit_reference_op_store): Likewise for when + value-numbering virtual operands for store matches. + + 2016-09-29 Richard Biener + + PR tree-optimization/77768 + * tree-ssa-sccvn.c (visit_reference_op_store): Properly deal + with stores to a place we know has a constant value. + * tree-vrp.c (set_defs_to_varying): New helper avoiding + writing to vr_const_varying. + (vrp_initialize): Call it. + (vrp_visit_stmt): Likewise. + (evrp_dom_walker::before_dom_children): Likewise. + * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): + Handle stores to readonly memory when removing redundant stores. + 2017-01-24 Wilco Dijkstra Backport from mainline diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f20224e4e252..a9c135a08778 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2017-01-26 Richard Biener + + Backport from mainline + 2016-09-27 Richard Biener + + PR tree-optimization/77745 + * g++.dg/torture/pr77745.C: New testcase. + + 2016-09-29 Richard Biener + + PR tree-optimization/77768 + * gcc.dg/torture/pr77768.c: New testcase. + 2017-01-24 Wilco Dijkstra Backport from mainline diff --git a/gcc/testsuite/g++.dg/torture/pr77745.C b/gcc/testsuite/g++.dg/torture/pr77745.C new file mode 100644 index 000000000000..dfba7e438ba3 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr77745.C @@ -0,0 +1,25 @@ +// { dg-do run } +// { dg-additional-options "-std=gnu++14" } + +inline void* operator new(__SIZE_TYPE__, void* __p) noexcept { return __p; } + +long foo(char *c1, char *c2) +{ + long *p1 = new (c1) long; + *p1 = 100; + long long *p2 = new (c2) long long; + *p2 = 200; + long *p3 = new (c2) long; + *p3 = 200; + return *p1; +} +int main() +{ + union { + char c; + long l; + long long ll; + } c; + if (foo(&c.c, &c.c) != 200) + __builtin_abort(); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr77768.c b/gcc/testsuite/gcc.dg/torture/pr77768.c new file mode 100644 index 000000000000..47e1484b77a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr77768.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ + +static const int a; +int b; +int *c, *d; +int main() +{ + c = (int *)&a; + c == d ?: __builtin_exit(0); + for (; b; b++ >= (*d = a)) + ; + return 0; +} diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 459d8e3cf5f0..32cee65d29eb 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -4320,26 +4320,36 @@ eliminate_dom_walker::before_dom_children (basic_block b) && !is_gimple_reg (gimple_assign_lhs (stmt)) && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))) - { - tree val; + { + tree val; tree rhs = gimple_assign_rhs1 (stmt); - val = vn_reference_lookup (gimple_assign_lhs (stmt), - gimple_vuse (stmt), VN_WALK, NULL, false); - if (TREE_CODE (rhs) == SSA_NAME) - rhs = VN_INFO (rhs)->valnum; - if (val - && operand_equal_p (val, rhs, 0)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Deleted redundant store "); - print_gimple_stmt (dump_file, stmt, 0, 0); - } - - /* Queue stmt for removal. */ - el_to_remove.safe_push (stmt); - continue; - } + vn_reference_t vnresult; + val = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_WALK, + &vnresult, false); + if (TREE_CODE (rhs) == SSA_NAME) + rhs = VN_INFO (rhs)->valnum; + if (val + && operand_equal_p (val, rhs, 0)) + { + /* We can only remove the later store if the former aliases + at least all accesses the later one does or if the store + was to readonly memory storing the same value. */ + alias_set_type set = get_alias_set (lhs); + if (! vnresult + || vnresult->set == set + || alias_set_subset_of (set, vnresult->set)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Deleted redundant store "); + print_gimple_stmt (dump_file, stmt, 0, 0); + } + + /* Queue stmt for removal. */ + el_to_remove.safe_push (stmt); + continue; + } + } } bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 349bae7b0e43..5007a993fb0a 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -3132,7 +3132,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt) { bool changed = false; vn_reference_t vnresult = NULL; - tree result, assign; + tree assign; bool resultsame = false; tree vuse = gimple_vuse (stmt); tree vdef = gimple_vdef (stmt); @@ -3156,31 +3156,40 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt) Otherwise, the vdefs for the store are used when inserting into the table, since the store generates a new memory state. */ - result = vn_reference_lookup (lhs, vuse, VN_NOWALK, NULL, false); - - if (result) + vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false); + if (vnresult + && vnresult->result) { + tree result = vnresult->result; if (TREE_CODE (result) == SSA_NAME) result = SSA_VAL (result); resultsame = expressions_equal_p (result, op); + if (resultsame) + { + /* If the TBAA state isn't compatible for downstream reads + we cannot value-number the VDEFs the same. */ + alias_set_type set = get_alias_set (lhs); + if (vnresult->set != set + && ! alias_set_subset_of (set, vnresult->set)) + resultsame = false; + } } - if ((!result || !resultsame) + if (!resultsame) + { /* Only perform the following when being called from PRE which embeds tail merging. */ - && default_vn_walk_kind == VN_WALK) - { - assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op); - vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false); - if (vnresult) + if (default_vn_walk_kind == VN_WALK) { - VN_INFO (vdef)->use_processed = true; - return set_ssa_val_to (vdef, vnresult->result_vdef); + assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op); + vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false); + if (vnresult) + { + VN_INFO (vdef)->use_processed = true; + return set_ssa_val_to (vdef, vnresult->result_vdef); + } } - } - if (!result || !resultsame) - { if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "No store match\n"); @@ -3193,9 +3202,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt) /* Have to set value numbers before insert, since insert is going to valueize the references in-place. */ if (vdef) - { - changed |= set_ssa_val_to (vdef, vdef); - } + changed |= set_ssa_val_to (vdef, vdef); /* Do not insert structure copies into the tables. */ if (is_gimple_min_invariant (op) diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index e8a87c4830c3..b25783830c83 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -807,6 +807,23 @@ get_value_range (const_tree var) return vr; } +/* Set value-ranges of all SSA names defined by STMT to varying. */ + +static void +set_defs_to_varying (gimple stmt) +{ + ssa_op_iter i; + tree def; + FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF) + { + value_range_t *vr = get_value_range (def); + /* Avoid writing to vr_const_varying get_value_range may return. */ + if (vr->type != VR_VARYING) + set_value_range_to_varying (vr); + } +} + + /* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */ static inline bool @@ -7061,10 +7078,7 @@ vrp_initialize (void) prop_set_simulate_again (stmt, true); else if (!stmt_interesting_for_vrp (stmt)) { - ssa_op_iter i; - tree def; - FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF) - set_value_range_to_varying (get_value_range (def)); + set_defs_to_varying (stmt); prop_set_simulate_again (stmt, false); } else @@ -7117,8 +7131,7 @@ vrp_valueize_1 (tree name) static enum ssa_prop_result vrp_visit_assignment_or_call (gimple stmt, tree *output_p) { - tree def, lhs; - ssa_op_iter iter; + tree lhs; enum gimple_code code = gimple_code (stmt); lhs = gimple_get_lhs (stmt); @@ -7235,8 +7248,7 @@ vrp_visit_assignment_or_call (gimple stmt, tree *output_p) } /* Every other statement produces no useful ranges. */ - FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF) - set_value_range_to_varying (get_value_range (def)); + set_defs_to_varying (stmt); return SSA_PROP_VARYING; } @@ -8009,9 +8021,6 @@ vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p) static enum ssa_prop_result vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p) { - tree def; - ssa_op_iter iter; - if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "\nVisiting statement:\n"); @@ -8029,8 +8038,7 @@ vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p) /* All other statements produce nothing of interest for VRP, so mark their outputs varying and prevent further simulation. */ - FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF) - set_value_range_to_varying (get_value_range (def)); + set_defs_to_varying (stmt); return SSA_PROP_VARYING; }