]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa-utils: avoid uninitialized probabilities on ICF [PR111559]
authorSergei Trofimovich <siarheit@google.com>
Wed, 27 Sep 2023 13:29:12 +0000 (14:29 +0100)
committerSergei Trofimovich <siarheit@google.com>
Thu, 5 Oct 2023 16:14:27 +0000 (17:14 +0100)
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.

gcc/ipa-utils.cc
gcc/testsuite/gcc.dg/tree-prof/pr111559.c [new file with mode: 0644]

index 956c6294fd73efbbcb8c0fb19d31e49b310d5d3a..6024ac69cc278c7f402396e7317174be017f3648 100644 (file)
@@ -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 (file)
index 0000000..43202c6
--- /dev/null
@@ -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();
+}