https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61743
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- Ok, so it's probably the range information on a SSA name we lose because we restrict retaining that to the case where the new SSA name definition is in the same basic-block as the original one: /* If this now constitutes a copy duplicate points-to and range info appropriately. This is especially important for inserted code. See tree-ssa-copy.c for similar code. */ if (sprime && TREE_CODE (sprime) == SSA_NAME) { basic_block sprime_b = gimple_bb (SSA_NAME_DEF_STMT (sprime)); ... else if (!POINTER_TYPE_P (TREE_TYPE (lhs)) && SSA_NAME_RANGE_INFO (lhs) && !SSA_NAME_RANGE_INFO (sprime) && b == sprime_b) duplicate_ssa_name_range_info (sprime, SSA_NAME_RANGE_TYPE (lhs), SSA_NAME_RANGE_INFO (lhs)); this is beause range info may not be valid if not dominated by a check that constrains it. In this case this is overly conservative. Removing the b == sprime_b test fixes the testcase back to unrolling t.c:20 like 4.9 did. Note that I don't think we can remove the check. Before r211625 we simply retained an SSA name copy at the original place which is now copy-propagated out: # RANGE [4, 8] NONZERO 0x0000000000000000e _43 = prephitmp_45; OTOH for 4.9 later copyprop also removes _43 and has no range-info on _45. But it retains a loop-closed SSA PHI node: <bb 23>: # RANGE [4, 8] NONZERO 0x0000000000000000e # _76 = PHI <_43(10)> goto <bb 14>; which is only there because of that initial copy and earlier CSE I guess. So the 2nd loop does see range info. So in the end the events are unfortunate. The only way out would be to make PRE "translate" range-info and set it on PHIs it inserts: Found partial partial redundancy for expression {nop_expr,n_1} (0018) Created phi prephitmp_57 = PHI <4(3), 6(17), 8(4)> in block 5 (0018) # RANGE [4, 8] NONZERO 14 # n_1 = PHI <4(3), 6(17), 8(4)> # prephitmp_57 = PHI <4(3), 6(17), 8(4)> <L11>: note how _57 misses range-info (but trivially has the same as n_1). A hack like Index: gcc/tree-ssa-pre.c =================================================================== --- gcc/tree-ssa-pre.c (revision 213700) +++ gcc/tree-ssa-pre.c (working copy) @@ -3218,6 +3218,28 @@ insert_into_preds_of_block (basic_block bitmap_insert_into_set (NEW_SETS (block), newphi); + if (expr->kind == NARY + && CONVERT_EXPR_CODE_P (expr->u.nary->opcode) + && TREE_CODE (expr->u.nary->op[0]) == SSA_NAME + && gimple_bb (SSA_NAME_DEF_STMT (expr->u.nary->op[0])) == block + && INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (expr->u.nary->op[0])) + && (TYPE_PRECISION (type) + >= TYPE_PRECISION (TREE_TYPE (expr->u.nary->op[0]))) + && SSA_NAME_RANGE_INFO (expr->u.nary->op[0])) + { + wide_int min, max; + if (get_range_info (expr->u.nary->op[0], &min, &max) == VR_RANGE + && !wi::neg_p (min, SIGNED) + && !wi::neg_p (max, SIGNED)) + set_range_info (temp, + SSA_NAME_RANGE_TYPE (expr->u.nary->op[0]), + wide_int_storage::from (min, TYPE_PRECISION (type), + TYPE_SIGN (type)), + wide_int_storage::from (max, TYPE_PRECISION (type), + TYPE_SIGN (type))); + } + handles this very special case (a widening/sign-changing conversion that doesn't change the range with an original definition in the same BB as the PHI is placed in - which means the original definition has to be a PHI node as well). Get's us back to unrolling t.c.:20