re PR debug/90074 (wrong debug info at -O3)
authorRichard Biener <rguenther@suse.de>
Mon, 15 Apr 2019 12:26:11 +0000 (12:26 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 15 Apr 2019 12:26:11 +0000 (12:26 +0000)
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.

From-SVN: r270370

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/guality/pr90074.c [new file with mode: 0644]
gcc/tree-loop-distribution.c

index 0d61af49e43cf56ff5ab0cadb7d73ab42dd85866..2872bd37feeeea41904d43f3b2e82350dbd09289 100644 (file)
@@ -1,3 +1,9 @@
+2019-04-15  Richard Biener  <rguenther@suse.de>
+
+       PR debug/90074
+       * tree-loop-distribution.c (destroy_loop): Preserve correct
+       debug info.
+
 2019-04-15  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/90071
index 38fcc79aa7dc12a5b561c26cc249eb7359bd3946..aacdaff51ed6b7fad7e63cf756508c450ec72ba8 100644 (file)
@@ -1,3 +1,8 @@
+2019-04-15  Richard Biener  <rguenther@suse.de>
+
+       PR debug/90074
+       * gcc.dg/guality/pr90074.c: New testcase.
+
 2019-04-15  Richard Biener  <rguenther@suse.de>
 
        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 (file)
index 0000000..1294928
--- /dev/null
@@ -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;
+}
index 81283d19871440eab64ff344fe8d7a5522525249..8959f52a67b2bc12e787f1c70b6293cb31961416 100644 (file)
@@ -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);