[gcc r14-4421] ipa-utils: avoid uninitialized probabilities on ICF [PR111559]

Sergei Trofimovich slyfox@gcc.gnu.org
Thu Oct 5 16:14:49 GMT 2023


https://gcc.gnu.org/g:043a6fcbc27f8721301eb2f72a7839f54f393003

commit r14-4421-g043a6fcbc27f8721301eb2f72a7839f54f393003
Author: Sergei Trofimovich <siarheit@google.com>
Date:   Wed Sep 27 14:29:12 2023 +0100

    ipa-utils: avoid uninitialized probabilities on ICF [PR111559]
    
    r14-3459-g0c78240fd7d519 "Check that passes do not forget to define profile"
    exposed check failures in cases when gcc produces uninitialized profile
    probabilities. In case of PR/111559 uninitialized profile is generated
    by edges executed 0 times reported by IPA profile:
    
        $ gcc -O2 -fprofile-generate pr111559.c -o b -fopt-info
        $ ./b
        $ gcc -O2 -fprofile-use -fprofile-correction pr111559.c -o b -fopt-info
    
        pr111559.c: In function 'rule1':
        pr111559.c:6:13: error: probability of edge 3->4 not initialized
            6 | static void rule1(void) { if (p) edge(); }
              |             ^~~~~
        during GIMPLE pass: fixup_cfg
        pr111559.c:6:13: internal compiler error: verify_flow_info failed
    
    The change conservatively ignores updates with zero execution counts and
    uses initially assigned probabilities (`always` probability in case of
    the example).
    
            PR ipa/111283
            PR gcov-profile/111559
    
    gcc/
            * ipa-utils.cc (ipa_merge_profiles): Avoid producing
            uninitialized probabilities when merging counters with zero
            denominators.
    
    gcc/testsuite/
            * gcc.dg/tree-prof/pr111559.c: New test.

Diff:
---
 gcc/ipa-utils.cc                          | 15 ++++++++-------
 gcc/testsuite/gcc.dg/tree-prof/pr111559.c | 16 ++++++++++++++++
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/gcc/ipa-utils.cc b/gcc/ipa-utils.cc
index 956c6294fd7..6024ac69cc2 100644
--- a/gcc/ipa-utils.cc
+++ b/gcc/ipa-utils.cc
@@ -651,13 +651,14 @@ ipa_merge_profiles (struct cgraph_node *dst,
 		{
 		  edge srce = EDGE_SUCC (srcbb, i);
 		  edge dste = EDGE_SUCC (dstbb, i);
-		  dste->probability = 
-		    dste->probability * dstbb->count.ipa ().probability_in
-						 (dstbb->count.ipa ()
-						  + srccount.ipa ())
-		    + srce->probability * srcbb->count.ipa ().probability_in
-						 (dstbb->count.ipa ()
-						  + srccount.ipa ());
+		  profile_count sum =
+		    dstbb->count.ipa () + srccount.ipa ();
+		  if (sum.nonzero_p ())
+		    dste->probability =
+		      dste->probability * dstbb->count.ipa ().probability_in
+						   (sum)
+		      + srce->probability * srcbb->count.ipa ().probability_in
+						   (sum);
 		}
 	      dstbb->count = dstbb->count.ipa () + srccount.ipa ();
 	    }
diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr111559.c b/gcc/testsuite/gcc.dg/tree-prof/pr111559.c
new file mode 100644
index 00000000000..43202c6c888
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/pr111559.c
@@ -0,0 +1,16 @@
+/* { dg-options "-O2" } */
+
+__attribute__((noipa)) static void edge(void) {}
+
+int p = 0;
+
+__attribute__((noinline))
+static void rule1(void) { if (p) edge(); }
+
+__attribute__((noinline))
+static void rule1_same(void) { if (p) edge(); }
+
+__attribute__((noipa)) int main(void) {
+    rule1();
+    rule1_same();
+}


More information about the Gcc-cvs mailing list