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; + }