Hi, PR 118138 and quite a few duplicates that it has acquired in a short time show that even though we are careful to make sure we do not loose any bits when newly allowing type conversions in jump-functions, we still need to perform the fold conversions during IPA constant propagation and not just at the end in order to properly perform sign-extensions or zero-extensions as appropriate.
This patch does just that, changing a safety predicate we already use at the appropriate places to return the necessary type. Bootstrapped and LTO-bootstrapped and tested on x86_64-linux. OK for master? Thanks, Martin gcc/ChangeLog: 2025-01-03 Martin Jambor <mjam...@suse.cz> PR ipa/118138 * ipa-cp.cc (ipacp_value_safe_for_type): Return the appropriate type instead of a bool, accept NULL_TREE VALUEs. (propagate_vals_across_arith_jfunc): Use the new returned value of ipacp_value_safe_for_type. (propagate_vals_across_ancestor): Likewise. (propagate_scalar_across_jump_function): Likewise. gcc/testsuite/ChangeLog: 2025-01-03 Martin Jambor <mjam...@suse.cz> PR ipa/118138 * gcc.dg/ipa/pr118138.c: New test. --- gcc/ipa-cp.cc | 33 +++++++++++++++++------------ gcc/testsuite/gcc.dg/ipa/pr118138.c | 30 ++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr118138.c diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index 1c4f3b0623a..3333ae26208 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -1448,19 +1448,23 @@ initialize_node_lattices (struct cgraph_node *node) } } -/* Return true if VALUE can be safely IPA-CP propagated to a parameter of type - PARAM_TYPE. */ +/* Return VALUE if it is NULL_TREE or if it can be directly safely IPA-CP + propagated to a parameter of type PARAM_TYPE, or return a fold-converted + VALUE to PARAM_TYPE if that is possible. Return NULL_TREE otherwise. */ -static bool +static tree ipacp_value_safe_for_type (tree param_type, tree value) { + if (!value) + return NULL_TREE; 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; + || useless_type_conversion_p (param_type, val_type)) + return value; + if (fold_convertible_p (param_type, value)) + return fold_convert (param_type, value); else - return false; + return NULL_TREE; } /* Return the result of a (possibly arithmetic) operation on the constant @@ -2210,8 +2214,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 - || !ipacp_value_safe_for_type (res_type, cstval)) + cstval = ipacp_value_safe_for_type (res_type, cstval); + if (!cstval) break; ret |= dest_lat->add_value (cstval, cs, src_val, src_idx, @@ -2235,8 +2239,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 - && ipacp_value_safe_for_type (res_type, cstval)) + cstval = ipacp_value_safe_for_type (res_type, cstval); + if (cstval) ret |= dest_lat->add_value (cstval, cs, src_val, src_idx, src_offset); else @@ -2284,8 +2288,8 @@ propagate_vals_across_ancestor (struct cgraph_edge *cs, for (src_val = src_lat->values; src_val; src_val = src_val->next) { tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value); - - if (t && ipacp_value_safe_for_type (param_type, t)) + t = ipacp_value_safe_for_type (param_type, t); + if (t) ret |= dest_lat->add_value (t, cs, src_val, src_idx); else ret |= dest_lat->set_contains_variable (); @@ -2310,7 +2314,8 @@ propagate_scalar_across_jump_function (struct cgraph_edge *cs, if (jfunc->type == IPA_JF_CONST) { tree val = ipa_get_jf_constant (jfunc); - if (ipacp_value_safe_for_type (param_type, val)) + val = ipacp_value_safe_for_type (param_type, val); + if (val) return dest_lat->add_value (val, cs, NULL, 0); else return dest_lat->set_contains_variable (); diff --git a/gcc/testsuite/gcc.dg/ipa/pr118138.c b/gcc/testsuite/gcc.dg/ipa/pr118138.c new file mode 100644 index 00000000000..5c94253f58b --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr118138.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-inline" } */ + +unsigned a = -1; +int b, e, c = 1; +unsigned long d; + +long f(long g) { + return g; +} + +static long h(unsigned g) { + for (; b < 8; b++) + d = f(g); + e = a < d; + if (e) + c = 0; + return 0; +} + +static void i(short g) { + h(g); +} + +int main() { + i(-1); + if (c != 1) + __builtin_abort(); + return 0; +} -- 2.47.1