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

Reply via email to