http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55875
--- Comment #3 from Jan Hubicka <hubicka at gcc dot gnu.org> 2013-01-07 13:36:58 UTC --- OK, the problem seems to be already in what simple_iv returns for SSA name 12. Here we should have -1. While analyzing the cast (gdb) p debug_gimple_stmt (at_stmt) _12 = (long unsigned int) _11; that effectively changes addition to minus, we get to CASE_CONVERT: /* In case we have a truncation of a widened operation that in the truncated type has undefined overflow behavior analyze the operation done in an unsigned type of the same precision as the final truncation. We cannot derive a scalar evolution for the widened operation but for the truncated result. */ if (TREE_CODE (type) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (rhs1)) == INTEGER_TYPE && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (rhs1)) && TYPE_OVERFLOW_UNDEFINED (type) && TREE_CODE (rhs1) == SSA_NAME && (def = SSA_NAME_DEF_STMT (rhs1)) && is_gimple_assign (def) && TREE_CODE_CLASS (gimple_assign_rhs_code (def)) == tcc_binary && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST) { tree utype = unsigned_type_for (type); chrec1 = interpret_rhs_expr (loop, at_stmt, utype, gimple_assign_rhs1 (def), gimple_assign_rhs_code (def), gimple_assign_rhs2 (def)); } else chrec1 = analyze_scalar_evolution (loop, rhs1); Here for widening conversions we do nothing. So we get <polynomial_chrec 0x7ffff705d7e0 type <integer_type 0x7ffff6ee8690 unsigned int sizes-gimplified public unsigned SI size <integer_cst 0x7ffff6eeb140 constant 32> unit size <integer_cst 0x7ffff6eeb160 constant 4> align 32 symtab 0 alias set -1 canonical type 0x7ffff6ee8690 precision 32 min <integer_cst 0x7ffff6eeb180 0> max <integer_cst 0x7ffff6eeb120 4294967295> pointer_to_this <pointer_type 0x7ffff6fc9738>> arg 0 <integer_cst 0x7ffff6eeb3c0 type <integer_type 0x7ffff6ee85e8 int> constant 1> arg 1 <integer_cst 0x7ffff6eeb120 type <integer_type 0x7ffff6ee8690 unsigned int> constant 4294967295> arg 2 <integer_cst 0x7ffff7042ae0 type <integer_type 0x7ffff6ee8690 unsigned int> constant 1>> this is correct, since it is done in unsigned int. Next we do: res = chrec_convert (type, chrec1, at_stmt); Eventually we go to convert_affine_scev and we set enforce_overflow_semantics enforce_overflow_semantics = (use_overflow_semantics && nowrap_type_p (type)); This test looks backwards to me. If the type is nowrap, we do not need to enforce anything about overflows, when it is wrap, then we have to. Flipping it however do not change fix the testcase. Anyway, the result of convert_affince_scev makes us to produce <polynomial_chrec 0x7ffff705d810 type <integer_type 0x7ffff6ee87e0 long unsigned int public unsigned DI size <integer_cst 0x7ffff6ecddc0 constant 64> unit size <integer_cst 0x7ffff6ecdde0 constant 8> align 64 symtab 0 alias set -1 canonical type 0x7ffff6ee87e0 precision 64 min <integer_cst 0x7ffff6eeb200 0> max <integer_cst 0x7ffff6eeb1e0 18446744073709551615>> arg 0 <integer_cst 0x7ffff6eeb3c0 type <integer_type 0x7ffff6ee85e8 int> constant 1> arg 1 <integer_cst 0x7ffff7042de0 type <integer_type 0x7ffff6ee87e0 long unsigned int> constant 4294967295> arg 2 <integer_cst 0x7ffff704cba0 type <integer_type 0x7ffff6ee87e0 long unsigned int> constant 1>> that seems already wrong. So the bug seems to be that convert_affince_scev is not doing the right thing here? But what the right thing is? Conversion to -1 or giving up?