This fixes PR55011, it seems nothing checks for invalid lattice
transitions in VRP, so the following adds that since we now
can produce a lot more UNDEFINED than before not doing so triggers
issues.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2012-10-22  Richard Biener  <rguent...@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.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c      (revision 192671)
--- gcc/tree-vrp.c      (working copy)
*************** update_value_range (const_tree var, valu
*** 819,826 ****
           || !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);
  
    BITMAP_FREE (new_vr->equiv);
  
--- 819,837 ----
           || !vrp_bitmap_equal_p (old_vr->equiv, new_vr->equiv);
  
    if (is_new)
!     {
!       /* 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);
  
Index: gcc/testsuite/gcc.dg/torture/pr55011.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr55011.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr55011.c      (working copy)
***************
*** 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(;;);
+     }
+ }

Reply via email to