@@ -1276,6 +1276,7 @@ initialize_node_lattices (struct cgraph_node *node)
{
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])))
{
@@ -1304,6 +1305,21 @@ initialize_node_lattices (struct cgraph_node *node)
}
}
+/* 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
@@ -2072,7 +2088,8 @@ propagate_vals_across_arith_jfunc (cgraph_edge *cs,
{
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,
@@ -2096,7 +2113,8 @@ propagate_vals_across_arith_jfunc (cgraph_edge *cs,
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
@@ -2132,7 +2150,8 @@ static bool
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;
@@ -2144,7 +2163,7 @@ propagate_vals_across_ancestor (struct cgraph_edge *cs,
{
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 ();
@@ -2169,7 +2188,10 @@ propagate_scalar_across_jump_function (struct cgraph_edge *cs,
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)
@@ -2196,10 +2218,11 @@ propagate_scalar_across_jump_function (struct cgraph_edge *cs,
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 ();
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -g -fno-ipa-cp -w" } */
+/* { dg-options "-O2 -g -w" } */
static int foo ();