This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix ICE on overflow of profile-count


Hi,
the testcase triggers ICE because loop iterates too many times.  We used to
work around by capping all counts to 10000 but that leads to many problems
during IPA profile propagation (because there is no way to determine
frequency of call given frequency of entry when entry frequency is 0).

This patch adds capping.  It seems very rare case and profile is either
already wrong or the program would run just too long to finish.

Bootstrapped/regtested x86_64-linux, comitted.

Honza

	* profile-count.c (profile_count::from_gcov_type): Move from
	profile-count.h; handle overflow.
	* profile-count. (profile_count::from_gcov_type): Move offline.

	PR middle-end/83609
	* gcc.c-torture/compile/pr83069.c: New testcase.
Index: profile-count.c
===================================================================
--- profile-count.c	(revision 255466)
+++ profile-count.c	(working copy)
@@ -327,3 +327,21 @@ profile_count::combine_with_ipa_count (p
     return this->global0 ();
   return this->global0adjusted ();
 }
+
+/* The profiling runtime uses gcov_type, which is usually 64bit integer.
+   Conversions back and forth are used to read the coverage and get it
+   into internal representation.  */
+profile_count
+profile_count::from_gcov_type (gcov_type v)
+  {
+    profile_count ret;
+    gcc_checking_assert (v >= 0);
+    if (dump_file && v >= (gcov_type)max_count)
+      fprintf (dump_file,
+	       "Capping gcov count %" PRId64 " to max_count %" PRId64 "\n",
+	       (int64_t) v, (int64_t) max_count);
+    ret.m_val = MIN (v, (gcov_type)max_count);
+    ret.m_quality = profile_precise;
+    return ret;
+  }
+
Index: profile-count.h
===================================================================
--- profile-count.h	(revision 255466)
+++ profile-count.h	(working copy)
@@ -667,18 +667,6 @@ public:
       return c;
     }
 
-  /* The profiling runtime uses gcov_type, which is usually 64bit integer.
-     Conversions back and forth are used to read the coverage and get it
-     into internal representation.  */
-  static profile_count from_gcov_type (gcov_type v)
-    {
-      profile_count ret;
-      gcc_checking_assert (v >= 0 && (uint64_t) v <= max_count);
-      ret.m_val = v;
-      ret.m_quality = profile_precise;
-      return ret;
-    }
-
   /* Conversion to gcov_type is lossy.  */
   gcov_type to_gcov_type () const
     {
@@ -1083,6 +1071,11 @@ public:
      global0.  */
   profile_count combine_with_ipa_count (profile_count ipa);
 
+  /* The profiling runtime uses gcov_type, which is usually 64bit integer.
+     Conversions back and forth are used to read the coverage and get it
+     into internal representation.  */
+  static profile_count from_gcov_type (gcov_type v);
+
   /* LTO streaming support.  */
   static profile_count stream_in (struct lto_input_block *);
   void stream_out (struct output_block *);
Index: testsuite/gcc.c-torture/compile/pr83069.c
===================================================================
--- testsuite/gcc.c-torture/compile/pr83069.c	(revision 0)
+++ testsuite/gcc.c-torture/compile/pr83069.c	(working copy)
@@ -0,0 +1,14 @@
+#define MAX 98
+
+void foo (unsigned long *res, unsigned long in)
+{
+  for (unsigned long a = 0; a < MAX; a++)
+    for (unsigned long b = 0; b < MAX; b++)
+      for (unsigned long c = 0; c < MAX; c++)
+        for (unsigned long d = 0; d < MAX; d++)
+          for (unsigned long e = 0; e < MAX; e++)
+            for (unsigned long f = 0; f < MAX; f++)
+              for (unsigned long g = 0; g < MAX; g++)
+                *res += a * in;
+}
+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]