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;
+}

Reply via email to