{
ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
if (disable
+ || !ipa_get_type (info, i)
|| (pre_modified && (surviving_params.length () <= (unsigned) i
|| !surviving_params[i])))
{
}
}
+/* Return true if VALUE can be safely IPA-CP propagated to a parameter of type
+ PARAM_TYPE. */
+
+static bool
+ipacp_value_safe_for_type (tree param_type, tree value)
+{
+ tree val_type = TREE_TYPE (value);
+ if (param_type == val_type
+ || useless_type_conversion_p (param_type, val_type)
+ || fold_convertible_p (param_type, value))
+ return true;
+ else
+ return false;
+}
+
/* Return true iff X and Y should be considered equal values by IPA-CP. */
static bool
{
tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
src_val, res_type);
- if (!cstval)
+ if (!cstval
+ || !ipacp_value_safe_for_type (res_type, cstval))
break;
ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
src_val, res_type);
- if (cstval)
+ if (cstval
+ && ipacp_value_safe_for_type (res_type, cstval))
ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
src_offset);
else
propagate_vals_across_ancestor (struct cgraph_edge *cs,
struct ipa_jump_func *jfunc,
ipcp_lattice<tree> *src_lat,
- ipcp_lattice<tree> *dest_lat, int src_idx)
+ ipcp_lattice<tree> *dest_lat, int src_idx,
+ tree param_type)
{
ipcp_value<tree> *src_val;
bool ret = false;
{
tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
- if (t)
+ if (t && ipacp_value_safe_for_type (param_type, t))
ret |= dest_lat->add_value (t, cs, src_val, src_idx);
else
ret |= dest_lat->set_contains_variable ();
if (jfunc->type == IPA_JF_CONST)
{
tree val = ipa_get_jf_constant (jfunc);
- return dest_lat->add_value (val, cs, NULL, 0);
+ if (ipacp_value_safe_for_type (param_type, val))
+ return dest_lat->add_value (val, cs, NULL, 0);
+ else
+ return dest_lat->set_contains_variable ();
}
else if (jfunc->type == IPA_JF_PASS_THROUGH
|| jfunc->type == IPA_JF_ANCESTOR)
if (jfunc->type == IPA_JF_PASS_THROUGH)
ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
- dest_lat, src_idx, param_type);
+ dest_lat, src_idx,
+ param_type);
else
ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
- src_idx);
+ src_idx, param_type);
if (src_lat->contains_variable)
ret |= dest_lat->set_contains_variable ();