From b7a9e9f4a275264b35e4422bd883c72c17aaba36 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 15 Apr 2019 12:26:11 +0000 Subject: [PATCH] re PR debug/90074 (wrong debug info at -O3) 2019-04-15 Richard Biener PR debug/90074 * tree-loop-distribution.c (destroy_loop): Preserve correct debug info. * gcc.dg/guality/pr90074.c: New testcase. From-SVN: r270370 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/guality/pr90074.c | 31 +++++++++++++++++++ gcc/tree-loop-distribution.c | 43 +++++++++++++++++++++----- 4 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/guality/pr90074.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0d61af49e43..2872bd37fee 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-04-15 Richard Biener + + PR debug/90074 + * tree-loop-distribution.c (destroy_loop): Preserve correct + debug info. + 2019-04-15 Richard Biener PR tree-optimization/90071 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 38fcc79aa7d..aacdaff51ed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-15 Richard Biener + + PR debug/90074 + * gcc.dg/guality/pr90074.c: New testcase. + 2019-04-15 Richard Biener PR tree-optimization/90071 diff --git a/gcc/testsuite/gcc.dg/guality/pr90074.c b/gcc/testsuite/gcc.dg/guality/pr90074.c new file mode 100644 index 00000000000..12949282516 --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr90074.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +void __attribute__((noinline)) +optimize_me_not () +{ + __asm__ volatile ("" : : : "memory"); +} +char a; +short b[7][1]; +int main() +{ + int i, c; + a = 0; + i = 0; + for (; i < 7; i++) { + c = 0; + for (; c < 1; c++) + b[i][c] = 0; + } + /* i may very well be optimized out, so we cannot test for i == 7. + Instead test i + 1 which will make the test UNSUPPORTED if i + is optimized out. Since the test previously had wrong debug + with i == 0 this is acceptable. Optimally we'd produce a + debug stmt for the final value of the loop during loop distribution + which would fix the UNSUPPORTED cases. + c is optimized out at -Og for no obvious reason. */ + optimize_me_not(); /* { dg-final { gdb-test . "i + 1" "8" } } */ + /* { dg-final { gdb-test .-1 "c + 1" "2" } } */ + return 0; +} diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 81283d19871..8959f52a67b 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -1094,12 +1094,8 @@ destroy_loop (struct loop *loop) bbs = get_loop_body_in_dom_order (loop); - redirect_edge_pred (exit, src); - exit->flags &= ~(EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); - exit->flags |= EDGE_FALLTHRU; - cancel_loop_tree (loop); - rescan_loop_exit (exit, false, true); - + gimple_stmt_iterator dst_gsi = gsi_after_labels (exit->dest); + bool safe_p = single_pred_p (exit->dest); i = nbbs; do { @@ -1116,14 +1112,45 @@ destroy_loop (struct loop *loop) if (virtual_operand_p (gimple_phi_result (phi))) mark_virtual_phi_result_for_renaming (phi); } - for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); - gsi_next (&gsi)) + for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi);) { gimple *stmt = gsi_stmt (gsi); tree vdef = gimple_vdef (stmt); if (vdef && TREE_CODE (vdef) == SSA_NAME) mark_virtual_operand_for_renaming (vdef); + /* Also move and eventually reset debug stmts. We can leave + constant values in place in case the stmt dominates the exit. + ??? Non-constant values from the last iteration can be + replaced with final values if we can compute them. */ + if (gimple_debug_bind_p (stmt)) + { + tree val = gimple_debug_bind_get_value (stmt); + gsi_move_before (&gsi, &dst_gsi); + if (val + && (!safe_p + || !is_gimple_min_invariant (val) + || !dominated_by_p (CDI_DOMINATORS, exit->src, bbs[i]))) + { + gimple_debug_bind_reset_value (stmt); + update_stmt (stmt); + } + } + else + gsi_next (&gsi); } + } + while (i != 0); + + redirect_edge_pred (exit, src); + exit->flags &= ~(EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); + exit->flags |= EDGE_FALLTHRU; + cancel_loop_tree (loop); + rescan_loop_exit (exit, false, true); + + i = nbbs; + do + { + --i; delete_basic_block (bbs[i]); } while (i != 0); -- 2.30.2