]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/55011 (GCC in an infinite loop at -O2 in VRP)
authorRichard Biener <rguenther@suse.de>
Mon, 22 Oct 2012 13:26:48 +0000 (13:26 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 22 Oct 2012 13:26:48 +0000 (13:26 +0000)
2012-10-22  Richard Biener  <rguenther@suse.de>

PR tree-optimization/55011
* tree-vrp.c (update_value_range): For invalid lattice transitions
drop to VARYING.

* gcc.dg/torture/pr55011.c: New testcase.

From-SVN: r192689

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr55011.c [new file with mode: 0644]
gcc/tree-vrp.c

index d8db9c9f0ba1129170084e171d9f118b493bfb04..4de896b358ad69e473412b46c67ed9a0f0dccc34 100644 (file)
@@ -1,3 +1,9 @@
+2012-10-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/55011
+       * tree-vrp.c (update_value_range): For invalid lattice transitions
+       drop to VARYING.
+
 2012-10-22  Julian Brown  <julian@codesourcery.com>
 
        * config/arm/arm.h (CANNOT_CHANGE_MODE_CLASS): Avoid subreg'ing
index 39bc6d35dbfa3b46ae9d0167bcf9b7363d8e159a..c994df96272bcbae4b1253f3de8da1bbc58b2f80 100644 (file)
@@ -1,3 +1,8 @@
+2012-10-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/55011
+       * gcc.dg/torture/pr55011.c: New testcase.
+
 2012-10-22  Greta Yorsh  <Greta.Yorsh@arm.com>
 
        * gcc.target/arm/pr40457-1.c: Adjust expected output.
diff --git a/gcc/testsuite/gcc.dg/torture/pr55011.c b/gcc/testsuite/gcc.dg/torture/pr55011.c
new file mode 100644 (file)
index 0000000..67b2613
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+char a;
+
+void f(void)
+{
+  char b = 2;
+
+  for(;;)
+    {
+      unsigned short s = 1, *p = &s, *i;
+
+      for(*i = 0; *i < 4; ++*i)
+       if(a | (*p /= (b += !!a)) <= 63739)
+         return;
+
+      if(!s)
+       a = 0;
+
+      for(;;);
+    }
+}
index de3eb2c6a98de073c181edfd3ae327937e4ca51b..379914cfad673246a654b232432e0cc00b811590 100644 (file)
@@ -819,8 +819,19 @@ update_value_range (const_tree var, value_range_t *new_vr)
           || !vrp_bitmap_equal_p (old_vr->equiv, new_vr->equiv);
 
   if (is_new)
-    set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
-                    new_vr->equiv);
+    {
+      /* Do not allow transitions up the lattice.  The following
+         is slightly more awkward than just new_vr->type < old_vr->type
+        because VR_RANGE and VR_ANTI_RANGE need to be considered
+        the same.  We may not have is_new when transitioning to
+        UNDEFINED or from VARYING.  */
+      if (new_vr->type == VR_UNDEFINED
+         || old_vr->type == VR_VARYING)
+       set_value_range_to_varying (old_vr);
+      else
+       set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
+                        new_vr->equiv);
+    }
 
   BITMAP_FREE (new_vr->equiv);