Hi,

I was relying on ipa_get_callee_param_type to get type of parameter and then convert arguments to this type while computing jump functions. However, in cases like shown in PR78365, ipa_get_callee_param_type, instead of giving up, would return the wrong type. I think the current uses of ipa_get_callee_param_type are fine with this.

Attached patch now uses callee's DECL_ARGUMENTS to get the type. If it cannot be found, then I would give up and set the jump function to varying.

Bootstrapped and regression tested on x86_64-linux-gnu with no new regressions. Is this OK for trunk?

Thanks,
Kugan

gcc/testsuite/ChangeLog:

2016-11-18  Kugan Vivekanandarajah  <kug...@linaro.org>

        PR IPA/78365
        * gcc.dg/torture/pr78365.c: New test.

gcc/ChangeLog:

2016-11-18  Kugan Vivekanandarajah  <kug...@linaro.org>

        PR IPA/78365
        * ipa-cp.c (propagate_constants_accross_call): get param type from 
callees
        DECL_ARGUMENTS if available.
        * ipa-prop.c (ipa_compute_jump_functions_for_edge): Likewise.
        (ipcp_update_vr):  Remove now redundant conversion of precision for VR.
        * ipa-prop.h: Make ipa_get_callee_param_type local again.
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 2ec671f..924c846 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -2200,6 +2200,9 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
   struct ipa_edge_args *args;
   bool ret = false;
   int i, args_count, parms_count;
+  struct cgraph_node *calee = cs->callee;
+  tree fndecl = calee ? calee->decl : NULL_TREE;
+  tree parm = fndecl ? DECL_ARGUMENTS (fndecl) : NULL_TREE;
 
   callee = cs->callee->function_symbol (&availability);
   if (!callee->definition)
@@ -2247,7 +2250,6 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
     {
       struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
       struct ipcp_param_lattices *dest_plats;
-      tree param_type = ipa_get_callee_param_type (cs, i);
 
       dest_plats = ipa_get_parm_lattices (callee_info, i);
       if (availability == AVAIL_INTERPOSABLE)
@@ -2265,10 +2267,12 @@ propagate_constants_accross_call (struct cgraph_edge 
*cs)
          if (opt_for_fn (callee->decl, flag_ipa_vrp))
            ret |= propagate_vr_accross_jump_function (cs,
                                                       jump_func, dest_plats,
-                                                      param_type);
+                                                      parm ?
+                                                      TREE_TYPE (parm) : 
NULL_TREE);
          else
            ret |= dest_plats->m_value_range.set_to_bottom ();
        }
+      parm = parm ? DECL_CHAIN (parm) : NULL_TREE;
     }
   for (; i < parms_count; i++)
     ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 6321fdd..0f102c6c 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1651,7 +1651,7 @@ determine_locally_known_aggregate_parts (gcall *call, 
tree arg,
 /* Return the Ith param type of callee associated with call graph
    edge E.  */
 
-tree
+static tree
 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
 {
   int n;
@@ -1695,6 +1695,9 @@ ipa_compute_jump_functions_for_edge (struct 
ipa_func_body_info *fbi,
   gcall *call = cs->call_stmt;
   int n, arg_num = gimple_call_num_args (call);
   bool useful_context = false;
+  struct cgraph_node *calee = cs->callee;
+  tree fndecl = calee ? calee->decl : NULL_TREE;
+  tree parm = fndecl ? DECL_ARGUMENTS (fndecl) : NULL_TREE;
 
   if (arg_num == 0 || args->jump_functions)
     return;
@@ -1751,8 +1754,8 @@ ipa_compute_jump_functions_for_edge (struct 
ipa_func_body_info *fbi,
        {
          wide_int min, max;
          value_range_type type;
-         if (TREE_CODE (arg) == SSA_NAME
-             && param_type
+         if (parm
+             && TREE_CODE (arg) == SSA_NAME
              && (type = get_range_info (arg, &min, &max))
              && (type == VR_RANGE || type == VR_ANTI_RANGE))
            {
@@ -1764,7 +1767,7 @@ ipa_compute_jump_functions_for_edge (struct 
ipa_func_body_info *fbi,
              vr.equiv = NULL;
              extract_range_from_unary_expr (&jfunc->m_vr,
                                             NOP_EXPR,
-                                            param_type,
+                                            TREE_TYPE (parm),
                                             &vr, TREE_TYPE (arg));
              if (jfunc->m_vr.type == VR_RANGE
                  || jfunc->m_vr.type == VR_ANTI_RANGE)
@@ -1775,6 +1778,7 @@ ipa_compute_jump_functions_for_edge (struct 
ipa_func_body_info *fbi,
          else
            gcc_assert (!jfunc->vr_known);
        }
+      parm = parm ? DECL_CHAIN (parm) : NULL_TREE;
 
       if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
          && (TREE_CODE (arg) == SSA_NAME || TREE_CODE (arg) == INTEGER_CST))
@@ -5699,8 +5703,6 @@ ipcp_update_vr (struct cgraph_node *node)
       if (vr[i].known
          && (vr[i].type == VR_RANGE || vr[i].type == VR_ANTI_RANGE))
        {
-         tree type = TREE_TYPE (ddef);
-         unsigned prec = TYPE_PRECISION (type);
          if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
            {
              if (dump_file)
@@ -5713,11 +5715,7 @@ ipcp_update_vr (struct cgraph_node *node)
                  print_decs (vr[i].max, dump_file);
                  fprintf (dump_file, "]\n");
                }
-             set_range_info (ddef, vr[i].type,
-                             wide_int_storage::from (vr[i].min, prec,
-                                                     TYPE_SIGN (type)),
-                             wide_int_storage::from (vr[i].max, prec,
-                                                     TYPE_SIGN (type)));
+             set_range_info (ddef, vr[i].type, vr[i].min, vr[i].max);
            }
          else if (POINTER_TYPE_P (TREE_TYPE (ddef))
                   && vr[i].type == VR_ANTI_RANGE
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 0e75cf4..4eeae88 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -818,7 +818,6 @@ ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, 
bool *,
                                                   ipa_parm_adjustment_vec,
                                                   bool);
 void ipa_release_body_info (struct ipa_func_body_info *);
-tree ipa_get_callee_param_type (struct cgraph_edge *e, int i);
 
 /* From tree-sra.c:  */
 tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, bool, tree,
diff --git a/gcc/testsuite/gcc.dg/torture/pr78365.c 
b/gcc/testsuite/gcc.dg/torture/pr78365.c
index e69de29..5180a01 100644
--- a/gcc/testsuite/gcc.dg/torture/pr78365.c
+++ b/gcc/testsuite/gcc.dg/torture/pr78365.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+int a, b, c;
+char d;
+static void fn1 (void *, int);
+int fn2 (int);
+
+void fn1 (cc, yh) void *cc;
+char yh;
+{
+  char y;
+  a = fn2(c - b + 1);
+  for (; y <= yh; y++)
+    ;
+}
+
+void fn3()
+{
+    fn1((void *)fn3, 1);
+    fn1((void *)fn3, d - 1);
+}

Reply via email to