===================================================================
@@ -3173,6 +3172,33 @@ insert_into_preds_of_block (basic_block
bitmap_insert_into_set (NEW_SETS (block),
newphi);
+ /* If we insert a PHI node for a conversion of another PHI node
+ in the same basic-block try to preserve range information.
+ This is important so that followup loop passes receive optimal
+ number of iteration analysis results. See PR61743. */
+ 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))
+ /* Just handle extension and sign-changes of all-positive ranges. */
+ 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)));
+ }
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Created phi ");
===================================================================
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -funroll-loops -fdump-tree-cunroll-details" } */
+
+#define N 8
+#define M 14
+typedef unsigned char e_u8;
+e_u8 x[256];
+#define MAX(a,b) ((a)>=(b)?(a):(b))
+#define btype e_u8
+
+static inline void bar1(e_u8 a[4][N], e_u8 b[4][N], btype n)
+{
+ int i, j;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < n; j++)
+ a[i][j] ^= b[i][j];
+}
+
+static inline void bar2(e_u8 a[4][N], e_u8 b[256], btype n)
+{
+ int i, j;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < n; j++)
+ a[i][j] = b[a[i][j]] ;
+}
+
+int foo1 (e_u8 a[4][N], int b1, int b2, e_u8 b[M+1][4][N])
+{
+ btype n;
+ int r, m;
+
+ switch (b2) {
+ case 128: n = 4; break;
+ case 192: n = 6; break;
+ case 256: n = 8; break;
+ default : return (-2);
+ }
+ switch (MAX(b1,b2)) {
+ case 128: m = 10; break;
+ case 192: m = 12; break;
+ case 256: m = 14; break;
+ default : return (-3);
+ }
+ bar1(a,b[m],n);
+ bar2(a,x,n);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 2 "cunroll" } } */
+/* { dg-final { scan-tree-dump-times "loop with 8 iterations completely unrolled" 2 "cunroll" } } */
+/* { dg-final { cleanup-tree-dump "cunroll" } } */
===================================================================
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -funroll-loops -fdump-tree-cunroll-details" } */
+
+#define N 8
+#define M 14
+typedef unsigned char e_u8;
+e_u8 x[256];
+#define MAX(a,b) ((a)>=(b)?(a):(b))
+#define btype int
+
+static inline void bar1(e_u8 a[4][N], e_u8 b[4][N], btype n)
+{
+ int i, j;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < n; j++)
+ a[i][j] ^= b[i][j];
+}
+
+static inline void bar2(e_u8 a[4][N], e_u8 b[256], btype n)
+{
+ int i, j;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < n; j++)
+ a[i][j] = b[a[i][j]] ;
+}
+
+int foo1 (e_u8 a[4][N], int b1, int b2, e_u8 b[M+1][4][N])
+{
+ btype n;
+ int r, m;
+
+ switch (b2) {
+ case 128: n = 4; break;
+ case 192: n = 6; break;
+ case 256: n = 8; break;
+ default : return (-2);
+ }
+ switch (MAX(b1,b2)) {
+ case 128: m = 10; break;
+ case 192: m = 12; break;
+ case 256: m = 14; break;
+ default : return (-3);
+ }
+ bar1(a,b[m],n);
+ bar2(a,x,n);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 2 "cunroll" } } */
+/* { dg-final { scan-tree-dump-times "loop with 8 iterations completely unrolled" 2 "cunroll" } } */
+/* { dg-final { cleanup-tree-dump "cunroll" } } */