https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106896
rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |hubicka at gcc dot gnu.org --- Comment #1 from rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> --- The problematic line is: return bb->count.to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count); where bb->count is: {m_val = 0, m_quality = GUESSED_LOCAL} and the entry block count is: {m_val = 0, m_quality = PRECISE} So we fail the first assert here: /* Watch for cases where one count is IPA and other is not. */ if (in.ipa ().initialized_p ()) { gcc_checking_assert (ipa ().initialized_p ()); /* If current count is inter-procedurally 0 and IN is inter-procedurally non-zero, return 0. */ if (in.ipa ().nonzero_p () && !ipa().nonzero_p ()) return 0; } else /* We can handle correctly 0 IPA count within locally estimated profile, but otherwise we are lost and this should not happen. */ gcc_checking_assert (!ipa ().initialized_p () || !ipa ().nonzero_p ()); But ipa() says: /* Return variant of profile count which is always safe to compare across functions. */ profile_count ipa () const { if (m_quality > GUESSED_GLOBAL0_ADJUSTED) return *this; if (m_quality == GUESSED_GLOBAL0) return zero (); if (m_quality == GUESSED_GLOBAL0_ADJUSTED) return adjusted_zero (); return uninitialized (); } So it feels like the ipa() in to_sreal_scale is a speculative “could I compare this value across functions, if I had to?”. The bb->count computation quoted above is deliberately intraprocedural rather than interprocedural. In that context it doesn't really seem relevant that one of the values could be compared across functions, since that isn't what we're doing. What's the right fix here?