[PATCH] Fix PR90574

Richard Biener rguenther@suse.de
Thu Jun 6 11:43:00 GMT 2019


The following fixes debugging experience (and coverage) for cases
where CFG construction "optimizes" the CFG by squashing labels
into the same basic-block, defeating the regular mechanism of
dropping labels that are not reachable as done by CFG cleanup.

Writing coverage testcases is easy enough here, guality IIRC
cannot test whether we stop at exactly a line - after the
patch gdb when setting a breakpoint on line 4, stops at
line 10 (stepping goes from 2 to 10 directly).

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

The patch has no bad effects on code generation when optimizing,
we just produce more "garbage" CFG upfront to leave optimizing
the CFG to machinery that knows how to do it correctly.  It
does have code-generation effects when not optimizing where
for the first testcase instead of

        nop
.L2:
        cmpl    $1, -4(%rbp)
        jne     .L3

we now emit

        cmpl    $0, -4(%rbp)
.L3:
        cmpl    $1, -4(%rbp)
        jne     .L4

and CFG cleanup done after RTL expansion elides the jump
but not the compare.

Any objections?

Thanks,
Richard.

2019-06-06  Richard Biener  <rguenther@suse.de>

	PR debug/90574
	* tree-cfg.c (stmt_starts_bb_p): Split blocks at labels
	that appear after user labels.

	* gcc.misc-tests/gcov-pr90574-1.c: New testcase.
	* gcc.misc-tests/gcov-pr90574-2.c: Likewise.

Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c	(revision 271990)
+++ gcc/tree-cfg.c	(working copy)
@@ -2722,10 +2722,10 @@ stmt_starts_bb_p (gimple *stmt, gimple *
 	  || FORCED_LABEL (gimple_label_label (label_stmt)))
 	return true;
 
-      if (prev_stmt && gimple_code (prev_stmt) == GIMPLE_LABEL)
+      if (glabel *plabel = safe_dyn_cast <glabel *> (prev_stmt))
 	{
-	  if (DECL_NONLOCAL (gimple_label_label (
-			       as_a <glabel *> (prev_stmt))))
+	  if (DECL_NONLOCAL (gimple_label_label (plabel))
+	      || !DECL_ARTIFICIAL (gimple_label_label (plabel)))
 	    return true;
 
 	  cfg_stats.num_merged_labels++;

Index: gcc/testsuite/gcc.misc-tests/gcov-pr90574-1.c
===================================================================
--- gcc/testsuite/gcc.misc-tests/gcov-pr90574-1.c	(nonexistent)
+++ gcc/testsuite/gcc.misc-tests/gcov-pr90574-1.c	(working copy)
@@ -0,0 +1,20 @@
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+int main(int argc, char **argv)
+{
+  if (argc == 0)
+    {
+      int *ptr;
+label:  /* count(#####) */
+	{
+	}
+    }
+  if (argc == 1)
+    {
+      __builtin_printf("hello\n");
+    }
+  return 0;
+}
+
+/* { dg-final { run-gcov gcov-pr90574-1.c } } */
Index: gcc/testsuite/gcc.misc-tests/gcov-pr90574-2.c
===================================================================
--- gcc/testsuite/gcc.misc-tests/gcov-pr90574-2.c	(nonexistent)
+++ gcc/testsuite/gcc.misc-tests/gcov-pr90574-2.c	(working copy)
@@ -0,0 +1,15 @@
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+int main(int argc, char **argv)
+{
+  switch (argc)
+    {
+    case 0:
+      foo: /* count(#####) */
+    case 1:;
+    }
+  return 0;
+}
+
+/* { dg-final { run-gcov gcov-pr90574-2.c } } */



More information about the Gcc-patches mailing list