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.
This commit is contained in:
Sergei Trofimovich 2023-09-27 14:29:12 +01:00
parent 604e76ed86
commit 043a6fcbc2
2 changed files with 24 additions and 7 deletions

View 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 ();
}

View file

@ -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();
}