The following addresses wrong debug IL created by SCCP rewriting stmts to defined overflow. I addressed another inefficiency there but needed to adjust the API of rewrite_to_defined_overflow for this which is now taking a stmt iterator for in-place operation and a stmt for sequence producing because gsi_for_stmt doesn't work for stmts not in the IL.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/112320 * gimple-fold.h (rewrite_to_defined_overflow): New overload for in-place operation. * gimple-fold.cc (rewrite_to_defined_overflow): Add stmt iterator argument to worker, define separate API for in-place and not in-place operation. * tree-if-conv.cc (predicate_statements): Simplify. * tree-scalar-evolution.cc (final_value_replacement_loop): Likewise. * tree-ssa-ifcombine.cc (pass_tree_ifcombine::execute): Adjust. * tree-ssa-reassoc.cc (update_range_test): Likewise. * gcc.dg/pr112320.c: New testcase. --- gcc/gimple-fold.cc | 25 ++++++++++++++++++------- gcc/gimple-fold.h | 3 ++- gcc/testsuite/gcc.dg/pr112320.c | 14 ++++++++++++++ gcc/tree-if-conv.cc | 19 +------------------ gcc/tree-scalar-evolution.cc | 15 ++++----------- gcc/tree-ssa-ifcombine.cc | 2 +- gcc/tree-ssa-reassoc.cc | 2 +- 7 files changed, 41 insertions(+), 39 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr112320.c diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 853edd9e5d4..a5be2ee048b 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -8769,12 +8769,14 @@ arith_code_with_undefined_signed_overflow (tree_code code) its operand, carrying out the operation in the corresponding unsigned type and converting the result back to the original type. - If IN_PLACE is true, adjust the stmt in place and return NULL. + If IN_PLACE is true, *GSI points to STMT, adjust the stmt in place and + return NULL. Otherwise returns a sequence of statements that replace STMT and also contain a modified form of STMT itself. */ -gimple_seq -rewrite_to_defined_overflow (gimple *stmt, bool in_place /* = false */) +static gimple_seq +rewrite_to_defined_overflow (gimple_stmt_iterator *gsi, gimple *stmt, + bool in_place) { if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -8801,9 +8803,8 @@ rewrite_to_defined_overflow (gimple *stmt, bool in_place /* = false */) gimple_set_modified (stmt, true); if (in_place) { - gimple_stmt_iterator gsi = gsi_for_stmt (stmt); if (stmts) - gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT); + gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); stmts = NULL; } else @@ -8811,8 +8812,7 @@ rewrite_to_defined_overflow (gimple *stmt, bool in_place /* = false */) gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, gimple_assign_lhs (stmt)); if (in_place) { - gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - gsi_insert_after (&gsi, cvt, GSI_SAME_STMT); + gsi_insert_after (gsi, cvt, GSI_SAME_STMT); update_stmt (stmt); } else @@ -8821,6 +8821,17 @@ rewrite_to_defined_overflow (gimple *stmt, bool in_place /* = false */) return stmts; } +void +rewrite_to_defined_overflow (gimple_stmt_iterator *gsi) +{ + rewrite_to_defined_overflow (gsi, gsi_stmt (*gsi), true); +} + +gimple_seq +rewrite_to_defined_overflow (gimple *stmt) +{ + return rewrite_to_defined_overflow (nullptr, stmt, false); +} /* The valueization hook we use for the gimple_build API simplification. This makes us match fold_buildN behavior by only combining with diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h index 2fd58db9a2e..f69bcc7d3e4 100644 --- a/gcc/gimple-fold.h +++ b/gcc/gimple-fold.h @@ -60,7 +60,8 @@ extern tree gimple_fold_indirect_ref (tree); extern bool gimple_fold_builtin_sprintf (gimple_stmt_iterator *); extern bool gimple_fold_builtin_snprintf (gimple_stmt_iterator *); extern bool arith_code_with_undefined_signed_overflow (tree_code); -extern gimple_seq rewrite_to_defined_overflow (gimple *, bool = false); +extern void rewrite_to_defined_overflow (gimple_stmt_iterator *); +extern gimple_seq rewrite_to_defined_overflow (gimple *); extern void replace_call_with_value (gimple_stmt_iterator *, tree); extern tree tree_vec_extract (gimple_stmt_iterator *, tree, tree, tree, tree); extern void gsi_replace_with_seq_vops (gimple_stmt_iterator *, gimple_seq); diff --git a/gcc/testsuite/gcc.dg/pr112320.c b/gcc/testsuite/gcc.dg/pr112320.c new file mode 100644 index 00000000000..15cf39f898c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr112320.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O -g" } */ + +unsigned void0_effective_addr2; +int void0_i, void0_m, void0_p2; +void void0() +{ + void0_m = 800 - (void0_effective_addr2 & 5); + int b1; + void0_i = 0; + for (; void0_i < void0_m; void0_i++) + b1++; + void0_p2 = b1++; +} diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index 262765139ff..16e06d82f59 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -2774,24 +2774,7 @@ predicate_statements (loop_p loop) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs)) && arith_code_with_undefined_signed_overflow (gimple_assign_rhs_code (stmt))) - { - gsi_remove (&gsi, true); - gimple_seq stmts = rewrite_to_defined_overflow (stmt); - bool first = true; - for (gimple_stmt_iterator gsi2 = gsi_start (stmts); - !gsi_end_p (gsi2);) - { - gassign *stmt2 = as_a <gassign *> (gsi_stmt (gsi2)); - gsi_remove (&gsi2, false); - if (first) - { - gsi_insert_before (&gsi, stmt2, GSI_NEW_STMT); - first = false; - } - else - gsi_insert_after (&gsi, stmt2, GSI_NEW_STMT); - } - } + rewrite_to_defined_overflow (&gsi); else if (gimple_vdef (stmt)) { tree lhs = gimple_assign_lhs (stmt); diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc index a6524de7b92..70b17c5bca1 100644 --- a/gcc/tree-scalar-evolution.cc +++ b/gcc/tree-scalar-evolution.cc @@ -3864,21 +3864,14 @@ final_value_replacement_loop (class loop *loop) while (!gsi_end_p (gsi2)) { gimple *stmt = gsi_stmt (gsi2); - gimple_stmt_iterator gsi3 = gsi2; - gsi_next (&gsi2); - gsi_remove (&gsi3, false); if (is_gimple_assign (stmt) && arith_code_with_undefined_signed_overflow - (gimple_assign_rhs_code (stmt))) - gsi_insert_seq_before (&gsi, - rewrite_to_defined_overflow (stmt), - GSI_SAME_STMT); - else - gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); + (gimple_assign_rhs_code (stmt))) + rewrite_to_defined_overflow (&gsi2); + gsi_next (&gsi2); } } - else - gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT); + gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT); if (dump_file) { fprintf (dump_file, "\n final stmt:\n "); diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc index 46b076804f4..1906a7e14c6 100644 --- a/gcc/tree-ssa-ifcombine.cc +++ b/gcc/tree-ssa-ifcombine.cc @@ -882,7 +882,7 @@ pass_tree_ifcombine::execute (function *fun) || POINTER_TYPE_P (TREE_TYPE (lhs))) && arith_code_with_undefined_signed_overflow (gimple_assign_rhs_code (ass))) - rewrite_to_defined_overflow (ass, true); + rewrite_to_defined_overflow (&gsi); } cfg_changed |= true; } diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc index 41ee36413b5..26321aa4fc5 100644 --- a/gcc/tree-ssa-reassoc.cc +++ b/gcc/tree-ssa-reassoc.cc @@ -2933,7 +2933,7 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange, gimple_stmt_iterator gsin = gsi; gsi_prev (&gsip); gsi_next (&gsin); - rewrite_to_defined_overflow (stmt, true); + rewrite_to_defined_overflow (&gsi); unsigned uid = gimple_uid (stmt); if (gsi_end_p (gsip)) gsip = gsi_after_labels (bb); -- 2.35.3