https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112303

--- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #11)
> (In reply to Richard Biener from comment #10)
> > Looks like so, can you test that?  I think !(bb->count >= new_count) is 
> > good,
> > we're using this kind of compare regularly.
> 
> Sure, I'll test that.

Actually no, that doesn't help, nor the IMO better
  if (!new_count.initialized_p () || bb->count < new_count)
    new_count = bb->count;
because if say bb->count is not initialized but e->count is, we don't want to
overwrite it.
The thing is that new_count is actually not used unless e is non-NULL.

The actual problem is different, bb->count of one of the duplicated blocks is
initialized to the largest possible unitialized m_val (0x3ffffffffffffffe aka
2305843009213693950 (estimated locally, freq 144115188075855872.0000)
) and then scaled to uninitialized.
This is because in the second duplicate_loop_body_to_header_edge on the
testcase (with the #c9 patch to reproduce it even on the trunk) we have
(gdb) p count_le.debug ()
1729382256910270463 (estimated locally, freq 108086391056891904.0000)
(gdb) p count_out_orig.debug ()
576460752303423488 (estimated locally, freq 36028797018963968.0000)
but
1264          profile_count new_count_le = count_le + count_out_orig;
is
(gdb) p new_count_le.debug ()
uninitialized
because 0x17ffffffffffffff + 0x800000000000000 yields the largest possible
value.

If profile_count wants to use the 0x1fffffffffffffff value as unitialized,
shouldn't
it perform saturating arithmetics such that the counts will be never larger
than
0x1ffffffffffffffe unless it is really meant to be uninitialized?
I mean in all those spots like operator+ which just m_val + other.m_val and
similar without checking for overflow?  What about apply_scale etc.?

Honza?

Reply via email to