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)

Reply via email to