108 lines
3.2 KiB
Diff
108 lines
3.2 KiB
Diff
2019-04-15 Richard Biener <rguenther@suse.de>
|
|
|
|
PR debug/90074
|
|
* tree-loop-distribution.c (destroy_loop): Preserve correct
|
|
debug info.
|
|
|
|
* gcc.dg/guality/pr90074.c: New testcase.
|
|
|
|
--- gcc/tree-loop-distribution.c (revision 270369)
|
|
+++ gcc/tree-loop-distribution.c (revision 270370)
|
|
@@ -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);
|
|
--- gcc/testsuite/gcc.dg/guality/pr90074.c (nonexistent)
|
|
+++ gcc/testsuite/gcc.dg/guality/pr90074.c (revision 270370)
|
|
@@ -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;
|
|
+}
|