This fixes PR49218 - we have to be careful to catch all overflow cases
when forcing a signed/unsigned double-int to a tree.

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

Richard.

2011-05-30  Richard Guenther  <rguent...@suse.de>

        PR tree-optimization/49218
        * tree-vrp.c (adjust_range_with_scev): Properly check whether
        overflow occured.

        * gcc.c-torture/execute/pr49218.c: New testcase.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c      (revision 174427)
--- gcc/tree-vrp.c      (working copy)
*************** adjust_range_with_scev (value_range_t *v
*** 3423,3433 ****
                                             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 (!overflow && double_int_equal_p (dtmp, tree_to_double_int (tem)))
        {
          extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
                                          TREE_TYPE (init), init, tem);
          /* Likewise if the addition did.  */
--- 3423,3439 ----
                                             loop->nb_iterations_upper_bound,
                                             double_int_one),
                                         unsigned_p, &overflow);
        /* If the multiplication overflowed we can't do a meaningful
!        adjustment.  Likewise if the result doesn't fit in the type
!        of the induction variable.  For a signed type we have to
!        check whether the result has the expected signedness which
!        is that of the step as nb_iterations_upper_bound is unsigned.  */
!       if (!overflow
!         && double_int_fits_to_tree_p (TREE_TYPE (init), dtmp)
!         && (unsigned_p
!             || ((dtmp.high ^ TREE_INT_CST_HIGH (step)) >= 0)))
        {
+         tem = double_int_to_tree (TREE_TYPE (init), dtmp);
          extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
                                          TREE_TYPE (init), init, tem);
          /* Likewise if the addition did.  */
Index: gcc/testsuite/gcc.c-torture/execute/pr49218.c
===================================================================
*** gcc/testsuite/gcc.c-torture/execute/pr49218.c       (revision 0)
--- gcc/testsuite/gcc.c-torture/execute/pr49218.c       (revision 0)
***************
*** 0 ****
--- 1,20 ----
+ #ifdef __SIZEOF_INT128__
+ typedef __int128 L;
+ #else
+ typedef long long L;
+ #endif
+ float f;
+ 
+ int
+ main ()
+ {
+   L i = f;
+   if (i <= 10)
+     do
+       {
+       ++i;
+       asm ("");
+       }
+     while (i != 11);
+   return 0;
+ }

Reply via email to