Hi, This patch fixes problem in profile_count::to_sreal_scale. We our porfile counters can be function local, global (ipa) or function local but globally 0. The last is used to hold static estimates for functions executed 0 times in profile. Now only one 64bit value is stored and if we compute frequency of global0 counter in global counter we mix them up and return non-zero value incorrectly.
I also implemented unit test, but will commit sanity checking separately from fixes: there are multiple bugs in this area I tracked down. Bootstrapped/regtested x86_64-linux, comitted. Honza * profile-count.c (profile_count::to_sreal_scale): Handle correctly combination of globa0 and global counters.. Index: profile-count.c =================================================================== --- profile-count.c (revision 278681) +++ profile-count.c (working copy) @@ -310,6 +311,20 @@ profile_count::to_sreal_scale (profile_c } if (known) *known = true; + /* 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 ()); if (*this == zero ()) return 0; if (m_val == in.m_val)