https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111559
--- Comment #6 from Sergei Trofimovich <slyfox at gcc dot gnu.org> ---
Uninitialized value comes from `ipa_merge_profiles()` for our `rule1_same()`
alias and `rule1()` functions:
// in gcc/ipa-icf.cc:
else if (create_alias)
{
alias->icf_merged = true;
/* Remove the function's body. */
ipa_merge_profiles (original, alias);
// ...
If I comment out `ipa_merge_profiles (original, alias);` call to leave
`original` as is then failure does not happen. Which means at least
`original`'s profile is fine.
Tracing through `ipa_merge_profiles()` we generate uninitialized probalility
profile when divide by zero at:
// in gcc/ipa-utils.cc
void
ipa_merge_profiles (struct cgraph_node *dst,
struct cgraph_node *src,
bool preserve_body)
// ...
/* TODO: merge also statement histograms. */
FOR_ALL_BB_FN (srcbb, srccfun)
{
unsigned int i;
if (copy_counts) { /* snip: ireelevant */ }
else
{
for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
{
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 ());
}
dstbb->count = dstbb->count.ipa () + srccount.ipa ();
}
}
// ...
Here `dstbb->count.ipa () + srccount.ipa ()` is zero.
This assert should expose it as well:
--- a/gcc/ipa-utils.cc
+++ b/gcc/ipa-utils.cc
@@ -651,13 +651,15 @@ ipa_merge_profiles (struct cgraph_node *dst,
{
edge srce = EDGE_SUCC (srcbb, i);
edge dste = EDGE_SUCC (dstbb, i);
+
+ profile_count den = dstbb->count.ipa () + srccount.ipa ();
+ gcc_assert(den.nonzero_p());
+
dste->probability =
dste->probability * dstbb->count.ipa ().probability_in
- (dstbb->count.ipa ()
- + srccount.ipa ())
+ (den)
+ srce->probability * srcbb->count.ipa ().probability_in
- (dstbb->count.ipa ()
- + srccount.ipa ());
+ (den);
}
dstbb->count = dstbb->count.ipa () + srccount.ipa ();
}
If we attach `gdb` it agrees we exercise these edges 0 times.
(gdb) call dstbb->count.debug()
0 (precise)
(gdb) call srccount.ipa ().debug()
0 (precise)
For comparison we are trying to clobber `always` probability with `undefined`:
(gdb) call dste->probability.debug()
always
What edge is that?
(gdb) call debug_edge(srce)
edge (bb_3, bb_4)
__attribute__((noinline))
void rule1 ()
{
int p.0_1;
<bb 2> [count: 2]:
p.0_1 = p;
if (p.0_1 != 0)
goto <bb 3>; [0.00%]
else
goto <bb 4>; [100.00%]
<bb 3> [count: 0]:
edge ();
<bb 4> [count: 2]:
return;
}
`always` should valid for `bb_3->bb_4`. But for our data input it's `never`.