aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Trofimovich <siarheit@google.com>2023-09-27 14:29:12 +0100
committerSergei Trofimovich <siarheit@google.com>2023-10-05 17:14:27 +0100
commit043a6fcbc27f8721301eb2f72a7839f54f393003 (patch)
tree119de82d465a4b2b82f1d0dcab76b65efe4ed62d
parent604e76ed867ebde255ccfac835c6f8d6fb5fd4a9 (diff)
downloadgcc-043a6fcbc27f8721301eb2f72a7839f54f393003.zip
gcc-043a6fcbc27f8721301eb2f72a7839f54f393003.tar.gz
gcc-043a6fcbc27f8721301eb2f72a7839f54f393003.tar.bz2
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.
-rw-r--r--gcc/ipa-utils.cc15
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/pr111559.c16
2 files changed, 24 insertions, 7 deletions
diff --git a/gcc/ipa-utils.cc b/gcc/ipa-utils.cc
index 956c629..6024ac6 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 0000000..43202c6
--- /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();
+}