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