range_fits_type_p erroneously returns true in cases where the range has overflowed. So for example, we might have a range [0, +INF(OVF)] and conclude the range fits in an unsigned type.

This in turn can cause VRP to rewrite a conditional in an unsafe way as seen by the testcase.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu.

OK for the trunk?

commit 45d8f974a4fae7bf07b7213b4ccda81fe410d49b
Author: Jeff Law <l...@redhat.com>
Date:   Wed May 1 12:33:20 2013 -0600

        PR tree-optimization/57124
            * tree-vrp.c (range_fits_type_p): If min/max of the range has
            overflowed, then the range does not fit the type.
    
            PR tree-optimization/57124
            * gcc.c-torture/execute/pr57124.c: New test.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 50a3b1d..658ddda 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2013-04-26  Jeff Law  <l...@redhat.com>
+
+       PR tree-optimization/57124
+       * tree-vrp.c (range_fits_type_p): If min/max of the range has
+       overflowed, then the range does not fit the type.
+
 2013-04-30  Greta Yorsh  <greta.yo...@arm.com>
 
        * config/arm/thumb2.md (thumb2_incscc, thumb2_decscc): Delete.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1016036..3ed531e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-05-01  Jeff Law  <l...@redhat.com>
+
+       PR tree-optimization/57124
+       * gcc.c-torture/execute/pr57124.c: New test.
+
 2013-04-30  Thomas Koenig  <tkoe...@gcc.gnu.org>
 
        PR fortran/57071
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57124.c 
b/gcc/testsuite/gcc.c-torture/execute/pr57124.c
new file mode 100644
index 0000000..835d249
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr57124.c
@@ -0,0 +1,27 @@
+__attribute__ ((noinline))
+foo(short unsigned int *p1, short unsigned int *p2)
+{
+  short unsigned int x1, x4;
+  int x2, x3, x5, x6;
+  unsigned int x7;
+  
+  x1 = *p1;
+  x2 = (int) x1;
+  x3 = x2 * 65536;
+  x4 = *p2;
+  x5 = (int) x4;
+  x6 = x3 + x4;
+  x7 = (unsigned int) x6;
+  if (x7 <= 268435455U)
+    abort ();
+  exit (0);
+}
+
+main()
+{
+  short unsigned int x, y;
+  x = -5;
+  y = -10;
+  foo (&x, &y);
+}
+
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 6ed353f..02f2f19 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8537,7 +8537,9 @@ range_fits_type_p (value_range_t *vr, unsigned precision, 
bool unsigned_p)
   /* Now we can only handle ranges with constant bounds.  */
   if (vr->type != VR_RANGE
       || TREE_CODE (vr->min) != INTEGER_CST
-      || TREE_CODE (vr->max) != INTEGER_CST)
+      || TREE_CODE (vr->max) != INTEGER_CST
+      || is_negative_overflow_infinity (vr->min)
+      || is_positive_overflow_infinity (vr->max))
     return false;
 
   /* For sign changes, the MSB of the double_int has to be clear.

Reply via email to