diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 1e80da3826ec427fefc9d9e8d882c21d2b3b05c8..ba6ced36e27b7b3a30d51135fd6aba72d66dbe0d 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -3994,7 +3994,13 @@ get_computation_aff_1 (class loop *loop, gimple *at, struct iv_use *use, if (TYPE_PRECISION (utype) > TYPE_PRECISION (ctype)) return false; - var = var_at_stmt (loop, cand, at); + if (use->outside) + { + var = cand->var_after; + ubase = fold_build2 (MINUS_EXPR, utype, ubase, ustep); + } + else + var = var_at_stmt (loop, cand, at); uutype = unsigned_type_for (utype); /* If the conversion is not noop, perform it. */ @@ -7328,19 +7334,32 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data, } } - gsi_insert_seq_before (&bsi, stmt_list, GSI_SAME_STMT); - if (gimple_code (use->stmt) == GIMPLE_PHI) + if (use->outside) { + gcc_assert (gimple_code (use->stmt) != GIMPLE_PHI); ass = gimple_build_assign (tgt, comp); - gsi_insert_before (&bsi, ass, GSI_SAME_STMT); - + gimple_seq_add_stmt (&stmt_list, ass); + bsi = gsi_for_stmt (SSA_NAME_DEF_STMT (cand->var_after)); + gsi_insert_seq_after (&bsi, stmt_list, GSI_SAME_STMT); bsi = gsi_for_stmt (use->stmt); - remove_phi_node (&bsi, false); + gsi_remove (&bsi, true); } else { - gimple_assign_set_rhs_from_tree (&bsi, comp); - use->stmt = gsi_stmt (bsi); + gsi_insert_seq_before (&bsi, stmt_list, GSI_SAME_STMT); + if (gimple_code (use->stmt) == GIMPLE_PHI) + { + ass = gimple_build_assign (tgt, comp); + gsi_insert_before (&bsi, ass, GSI_SAME_STMT); + + bsi = gsi_for_stmt (use->stmt); + remove_phi_node (&bsi, false); + } + else + { + gimple_assign_set_rhs_from_tree (&bsi, comp); + use->stmt = gsi_stmt (bsi); + } } }