]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix PR/46316
authorXinliang David Li <davidxl@google.com>
Tue, 9 Nov 2010 02:01:06 +0000 (02:01 +0000)
committerXinliang David Li <davidxl@gcc.gnu.org>
Tue, 9 Nov 2010 02:01:06 +0000 (02:01 +0000)
From-SVN: r166469

gcc/ChangeLog
gcc/double-int.c
gcc/double-int.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr46316.c [new file with mode: 0644]
gcc/tree-vrp.c

index e4512dd480cec69cddca36950ae9cb05fc444aef..7e080ea5d960373696866b2f7764ca4699a77cc2 100644 (file)
@@ -1,3 +1,11 @@
+2010-11-08  Xinliang David Li  <davidxl@google.com>
+
+       PR/46316
+       * tree-vrp.c (adjust_range_with_scev): Check double_int
+       overflow.
+       * double-int.h (double_int_mul_with_sign): New function.
+       * double-int.c (double_int_mul_with_sign): New function.
+
 2010-11-08  Paul Koning  <ni1d@arrl.net>
 
        * config/pdp11/pdp11.md (lshrsi3, lshrhi3): Fix wrong code.
index cb63f856df34348671f28c6de8c3e6da625b4030..f3501a5c2c0a79e52f3d380e846db55c81277068 100644 (file)
@@ -718,6 +718,19 @@ double_int_mul (double_int a, double_int b)
   return ret;
 }
 
+/* Returns A * B. If the operation overflows according to UNSIGNED_P,
+   *OVERFLOW is set to nonzero.  */
+
+double_int
+double_int_mul_with_sign (double_int a, double_int b,
+                          bool unsigned_p, int *overflow)
+{
+  double_int ret;
+  *overflow = mul_double_with_sign (a.low, a.high, b.low, b.high,
+                                    &ret.low, &ret.high, unsigned_p);
+  return ret;
+}
+
 /* Returns A + B.  */
 
 double_int
index c2f74e95e28980cd92c760aac1107ffb9d43b204..6d1555111d34b852160245f957079b71e5ec9278 100644 (file)
@@ -132,6 +132,7 @@ double_int_fits_in_uhwi_p (double_int cst)
    2 * HOST_BITS_PER_WIDE_INT bits.  */
 
 double_int double_int_mul (double_int, double_int);
+double_int double_int_mul_with_sign (double_int, double_int, bool, int *);
 double_int double_int_add (double_int, double_int);
 double_int double_int_sub (double_int, double_int);
 double_int double_int_neg (double_int);
index 4c348babbc296a3d49fd1b9206724b08c79a76d0..e94dceff04371723547f955fd4f3af2a2e9283bf 100644 (file)
@@ -1,3 +1,8 @@
+2010-11-08  Xinliang David Li  <davidxl@google.com>
+
+       PR/46316
+       * gcc.dg/tree-ssa/pr46316.c: New test.
+       
 2010-11-08  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/46344
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr46316.c b/gcc/testsuite/gcc.dg/tree-ssa/pr46316.c
new file mode 100644 (file)
index 0000000..9b2e085
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+long long __attribute__((noinline,noclone))
+foo (long long t)
+{
+  while (t > -4)
+    t -= 2;
+
+  return t;
+}
+
+int main(void)
+{
+  if (foo (0) != -4)
+    abort ();
+  return 0;
+}
index 2103e1b61bb3609601c8c08c4d9e105c208fe59d..d77cdef2cf518255cb2c663a96a0ba2cfe634c50 100644 (file)
@@ -3403,13 +3403,18 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop,
     {
       value_range_t maxvr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
       double_int dtmp;
-      dtmp = double_int_mul (tree_to_double_int (step),
-                            double_int_sub (loop->nb_iterations_upper_bound,
-                                            double_int_one));
+      bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (step));
+      int overflow = 0;
+
+      dtmp = double_int_mul_with_sign (tree_to_double_int (step),
+                                       double_int_sub (
+                                           loop->nb_iterations_upper_bound,
+                                           double_int_one),
+                                       unsigned_p, &overflow);
       tem = double_int_to_tree (TREE_TYPE (init), dtmp);
       /* If the multiplication overflowed we can't do a meaningful
         adjustment.  */
-      if (double_int_equal_p (dtmp, tree_to_double_int (tem)))
+      if (!overflow && double_int_equal_p (dtmp, tree_to_double_int (tem)))
        {
          extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
                                          TREE_TYPE (init), init, tem);