diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 167913cb927c..6041f75d8242 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -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 *src_lat, - ipcp_lattice *dest_lat, int src_idx) + ipcp_lattice *dest_lat, int src_idx, + tree param_type) { ipcp_value *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 (); diff --git a/gcc/testsuite/gcc.dg/pr99122-3.c b/gcc/testsuite/gcc.dg/pr99122-3.c index 6aa5b2912ca6..6a908ad86c04 100644 --- a/gcc/testsuite/gcc.dg/pr99122-3.c +++ b/gcc/testsuite/gcc.dg/pr99122-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -g -fno-ipa-cp -w" } */ +/* { dg-options "-O2 -g -w" } */ static int foo ();