Hi Martin, As mentioned in PR, the issue here for propagating value of 'm' from f_c1 to foo() is that the jump function operation is FLOAT_EXPR, and the type of input param 'm' is int, so fold_unary() doesn't do the conversion to real_type. The attached patch fixes that by calling fold_convert if operation is FLOAT_EXPR / FIX_TRUNC_EXPR / CONVERT_EXPR and converts it to the type of corresponding parameter in callee.
There are still two issues: a) Using NOP_EXPR for early_exit in ipa_get_jf_pass_through_result. I suppose we need to change to some other code to indicate that there is no operation ? b) Patch does not passing param_type from all callers. I suppose we could fix these incrementally ? Bootstrap+tested on x86_64-unknown-linux-gnu. OK for trunk ? Thanks, Prathamesh
2017-11-03 Prathamesh Kulkarni <prathamesh.kulka...@linaro.org> * ipa-cp.c (ipa_get_jf_pass_through_result): Add new parameter parm_type with default value set to NULL. Call fold_convert if jfunc operation is FLOAT_EXPR or FIX_TRUNC_EXPR or CONVERT_EXPR. (propagate_vals_across_pass_through): Add parameter parm_type. (propagate_scalar_across_jump_function): Add parameter parm_type and pass it to propagate_vals_across_pass_through. (propagate_constants_across_call): Pass param_type to propagate_scalar_across_jump_function. testsuite/ * gcc.dg/ipa/pr82808.c: New test. diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 6b3d8d7364c..20328a43f9b 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1224,7 +1224,8 @@ initialize_node_lattices (struct cgraph_node *node) determined or be considered an interprocedural invariant. */ static tree -ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input) +ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input, + tree parm_type = NULL_TREE) { tree restype, res; @@ -1233,7 +1234,17 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input) if (!is_gimple_ip_invariant (input)) return NULL_TREE; - if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) + if (ipa_get_jf_pass_through_operation (jfunc) == FLOAT_EXPR + || ipa_get_jf_pass_through_operation (jfunc) == FIX_TRUNC_EXPR + || ipa_get_jf_pass_through_operation (jfunc) == CONVERT_EXPR) + { + if (!parm_type) + return NULL_TREE; + + res = fold_convert (parm_type, input); + restype = parm_type; + } + else if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) == tcc_unary) res = fold_unary (ipa_get_jf_pass_through_operation (jfunc), TREE_TYPE (input), input); @@ -1567,7 +1578,8 @@ ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs, static bool propagate_vals_across_pass_through (cgraph_edge *cs, 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 parm_type) { ipcp_value<tree> *src_val; bool ret = false; @@ -1581,7 +1593,8 @@ propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc, else for (src_val = src_lat->values; src_val; src_val = src_val->next) { - tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value); + tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value, + parm_type); if (cstval) ret |= dest_lat->add_value (cstval, cs, src_val, src_idx); @@ -1627,7 +1640,8 @@ propagate_vals_across_ancestor (struct cgraph_edge *cs, static bool propagate_scalar_across_jump_function (struct cgraph_edge *cs, struct ipa_jump_func *jfunc, - ipcp_lattice<tree> *dest_lat) + ipcp_lattice<tree> *dest_lat, + tree param_type) { if (dest_lat->bottom) return false; @@ -1662,7 +1676,7 @@ 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); + dest_lat, src_idx, param_type); else ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat, src_idx); @@ -2279,7 +2293,7 @@ propagate_constants_across_call (struct cgraph_edge *cs) else { ret |= propagate_scalar_across_jump_function (cs, jump_func, - &dest_plats->itself); + &dest_plats->itself, param_type); ret |= propagate_context_across_jump_function (cs, jump_func, i, &dest_plats->ctxlat); ret diff --git a/gcc/testsuite/gcc.dg/ipa/pr82808.c b/gcc/testsuite/gcc.dg/ipa/pr82808.c new file mode 100644 index 00000000000..e9a90e3ce2e --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr82808.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -fno-inline" } */ + +void foo(double *a, double x) +{ + *a = x; +} + +double f_c1(int m, double *a) +{ + foo(a, m); + return *a; +} + +int main(){ + double data; + double ret = 0 ; + + if ((ret = f_c1(2, &data)) != 2) + { + __builtin_abort (); + } + return 0; +}