diff options
author | Sergei Trofimovich <siarheit@google.com> | 2023-09-27 14:29:12 +0100 |
---|---|---|
committer | Sergei Trofimovich <siarheit@google.com> | 2023-10-05 17:14:27 +0100 |
commit | 043a6fcbc27f8721301eb2f72a7839f54f393003 (patch) | |
tree | 119de82d465a4b2b82f1d0dcab76b65efe4ed62d /gcc | |
parent | 604e76ed867ebde255ccfac835c6f8d6fb5fd4a9 (diff) | |
download | gcc-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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ipa-utils.cc | 15 | ||||
-rw-r--r-- | 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 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(); +} |