aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.cc')
-rw-r--r--gcc/tree-ssa-loop-ivopts.cc31
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 581f92b..81b536f 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -452,6 +452,7 @@ struct iv_cand
unsigned id; /* The number of the candidate. */
bool important; /* Whether this is an "important" candidate, i.e. such
that it should be considered by all uses. */
+ bool involves_undefs; /* Whether the IV involves undefined values. */
ENUM_BITFIELD(iv_position) pos : 8; /* Where it is computed. */
gimple *incremented_at;/* For original biv, the statement where it is
incremented. */
@@ -3070,6 +3071,19 @@ get_loop_invariant_expr (struct ivopts_data *data, tree inv_expr)
return *slot;
}
+/* Find the first undefined SSA name in *TP. */
+
+static tree
+find_ssa_undef (tree *tp, int *walk_subtrees, void *)
+{
+ if (TREE_CODE (*tp) == SSA_NAME
+ && ssa_undefined_value_p (*tp, false))
+ return *tp;
+ if (!EXPR_P (*tp))
+ *walk_subtrees = 0;
+ return NULL;
+}
+
/* Adds a candidate BASE + STEP * i. Important field is set to IMPORTANT and
position to POS. If USE is not NULL, the candidate is set as related to
it. If both BASE and STEP are NULL, we add a pseudocandidate for the
@@ -3097,6 +3111,17 @@ add_candidate_1 (struct ivopts_data *data, tree base, tree step, bool important,
if (flag_keep_gc_roots_live && POINTER_TYPE_P (TREE_TYPE (base)))
return NULL;
+ /* If BASE contains undefined SSA names make sure we only record
+ the original IV. */
+ bool involves_undefs = false;
+ if (walk_tree (&base, find_ssa_undef, NULL, NULL))
+ {
+ if (pos != IP_ORIGINAL)
+ return NULL;
+ important = false;
+ involves_undefs = true;
+ }
+
/* For non-original variables, make sure their values are computed in a type
that does not invoke undefined behavior on overflows (since in general,
we cannot prove that these induction variables are non-wrapping). */
@@ -3145,6 +3170,7 @@ add_candidate_1 (struct ivopts_data *data, tree base, tree step, bool important,
cand->var_after = cand->var_before;
}
cand->important = important;
+ cand->involves_undefs = involves_undefs;
cand->incremented_at = incremented_at;
cand->doloop_p = doloop;
data->vcands.safe_push (cand);
@@ -4958,6 +4984,11 @@ determine_group_iv_cost_generic (struct ivopts_data *data,
the candidate. */
if (cand->pos == IP_ORIGINAL && cand->incremented_at == use->stmt)
cost = no_cost;
+ /* If the IV candidate involves undefined SSA values and is not the
+ same IV as on the USE avoid using that candidate here. */
+ else if (cand->involves_undefs
+ && (!use->iv || !operand_equal_p (cand->iv->base, use->iv->base, 0)))
+ return false;
else
cost = get_computation_cost (data, use, cand, false,
&inv_vars, NULL, &inv_expr);