static bool
visit_phi (gimple *phi)
{
- bool changed = false;
- tree result;
- tree sameval = VN_TOP;
- bool allsame = true;
+ tree result, sameval = VN_TOP, seen_undef = NULL_TREE;
unsigned n_executable = 0;
+ bool allsame = true;
+ edge_iterator ei;
+ edge e;
/* TODO: We could check for this in init_sccvn, and replace this
with a gcc_assert. */
/* See if all non-TOP arguments have the same value. TOP is
equivalent to everything, so we can ignore it. */
- edge_iterator ei;
- edge e;
FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
if (e->flags & EDGE_EXECUTABLE)
{
if (TREE_CODE (def) == SSA_NAME)
def = SSA_VAL (def);
if (def == VN_TOP)
- continue;
- if (sameval == VN_TOP)
+ ;
+ /* Ignore undefined defs for sameval but record one. */
+ else if (TREE_CODE (def) == SSA_NAME
+ && ssa_undefined_value_p (def, false))
+ seen_undef = def;
+ else if (sameval == VN_TOP)
sameval = def;
else if (!expressions_equal_p (def, sameval))
{
break;
}
}
-
- /* If none of the edges was executable or all incoming values are
- undefined keep the value-number at VN_TOP. If only a single edge
- is exectuable use its value. */
- if (sameval == VN_TOP
- || n_executable == 1)
- return set_ssa_val_to (PHI_RESULT (phi), sameval);
+
+ /* If none of the edges was executable keep the value-number at VN_TOP,
+ if only a single edge is exectuable use its value. */
+ if (n_executable <= 1)
+ result = seen_undef ? seen_undef : sameval;
+ /* If we saw only undefined values create a new undef SSA name to
+ avoid false equivalences. */
+ else if (sameval == VN_TOP)
+ {
+ gcc_assert (seen_undef);
+ result = seen_undef;
+ }
/* First see if it is equivalent to a phi node in this block. We prefer
this as it allows IV elimination - see PRs 66502 and 67167. */
- result = vn_phi_lookup (phi);
- if (result)
- changed = set_ssa_val_to (PHI_RESULT (phi), result);
- /* Otherwise all value numbered to the same value, the phi node has that
- value. */
- else if (allsame)
- changed = set_ssa_val_to (PHI_RESULT (phi), sameval);
+ else if ((result = vn_phi_lookup (phi)))
+ ;
+ /* If all values are the same use that, unless we've seen undefined
+ values as well and the value isn't constant.
+ CCP/copyprop have the same restriction to not remove uninit warnings. */
+ else if (allsame
+ && (! seen_undef || is_gimple_min_invariant (sameval)))
+ result = sameval;
else
{
- vn_phi_insert (phi, PHI_RESULT (phi));
- changed = set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi));
+ result = PHI_RESULT (phi);
+ /* Only insert PHIs that are varying, for constant value numbers
+ we mess up equivalences otherwise as we are only comparing
+ the immediate controlling predicates. */
+ vn_phi_insert (phi, result);
}
- return changed;
+ return set_ssa_val_to (PHI_RESULT (phi), result);
}
/* Try to simplify RHS using equivalences and constant folding. */