Hi,

     {
       tree val = ipa_get_jf_constant (jfunc);
       if (TREE_CODE (val) == INTEGER_CST)
        {
+         value_range vr;
          if (TREE_OVERFLOW_P (val))
            val = drop_tree_overflow (val);
-         jfunc->vr_known = true;
-         jfunc->m_vr.type = VR_RANGE;
-         jfunc->m_vr.min = val;
-         jfunc->m_vr.max = val;
+
+         vr.type = VR_RANGE;
+         vr.min = val;
+         vr.max = val;
+         vr.equiv = NULL;
+         extract_range_from_unary_expr (&jfunc->m_vr,
+                                        NOP_EXPR,
+                                        param_type,
+                                        &vr, TREE_TYPE (val));

Do I understand it correctly that extract_range_from_unary_expr deals
with any potential type conversions better (compared to what you did
before here)?

Yes, this can be wrong at times too as reported in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78121. I have separated this part of the patch with a testcase.

Please note that I am using fold_convert in the attached patch.

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

Thanks,
Kugan


gcc/ChangeLog:

2016-10-28  Kugan Vivekanandarajah  <kug...@linaro.org>

        PR ipa/78121
        * ipa-cp.c (propagate_vr_accross_jump_function): Pass param type.
        Also fold constant passed as argument while computing value range.
        (propagate_constants_accross_call): Pass param type.
        * ipa-prop.c: export ipa_get_callee_param_type.
        * ipa-prop.h: export ipa_get_callee_param_type.

gcc/testsuite/ChangeLog:

2016-10-28  Kugan Vivekanandarajah  <kug...@linaro.org>

        PR ipa/78121
        * gcc.dg/ipa/pr78121.c: New test.
>From 64776c1b43c9fd68aee6c40624660d20e1c4e653 Mon Sep 17 00:00:00 2001
From: Kugan Vivekanandarajah <kugan.vivekanandara...@linaro.org>
Date: Fri, 28 Oct 2016 09:44:23 +1100
Subject: [PATCH 1/2] fix convertion

---
 gcc/ipa-cp.c                       | 16 +++++++++++++---
 gcc/ipa-prop.c                     |  5 ++++-
 gcc/ipa-prop.h                     |  1 +
 gcc/testsuite/gcc.dg/ipa/pr78121.c | 16 ++++++++++++++++
 4 files changed, 34 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/pr78121.c

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 1dc5cb6..9f28557 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1840,12 +1840,14 @@ propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j
 }
 
 /* Propagate value range across jump function JFUNC that is associated with
-   edge CS and update DEST_PLATS accordingly.  */
+   edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
+   accordingly.  */
 
 static bool
 propagate_vr_accross_jump_function (cgraph_edge *cs,
 				    ipa_jump_func *jfunc,
-				    struct ipcp_param_lattices *dest_plats)
+				    struct ipcp_param_lattices *dest_plats,
+				    tree param_type)
 {
   struct ipcp_param_lattices *src_lats;
   ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
@@ -1853,6 +1855,11 @@ propagate_vr_accross_jump_function (cgraph_edge *cs,
   if (dest_lat->bottom_p ())
     return false;
 
+  if (!param_type
+      || (!INTEGRAL_TYPE_P (param_type)
+	  && !POINTER_TYPE_P (param_type)))
+    return dest_lat->set_to_bottom ();
+
   if (jfunc->type == IPA_JF_PASS_THROUGH)
     {
       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
@@ -1871,6 +1878,7 @@ propagate_vr_accross_jump_function (cgraph_edge *cs,
 	{
 	  if (TREE_OVERFLOW_P (val))
 	    val = drop_tree_overflow (val);
+	  val = fold_convert (param_type, val);
 	  jfunc->vr_known = true;
 	  jfunc->m_vr.type = VR_RANGE;
 	  jfunc->m_vr.min = val;
@@ -2220,6 +2228,7 @@ 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)
@@ -2236,7 +2245,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
 						       dest_plats);
 	  if (opt_for_fn (callee->decl, flag_ipa_vrp))
 	    ret |= propagate_vr_accross_jump_function (cs,
-						       jump_func, dest_plats);
+						       jump_func, dest_plats,
+						       param_type);
 	  else
 	    ret |= dest_plats->m_value_range.set_to_bottom ();
 	}
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 1629870..74fe199 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1595,7 +1595,10 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
     }
 }
 
-static tree
+/* Return the Ith param type of callee associated with call graph
+   edge E.  */
+
+tree
 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
 {
   int n;
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 4eeae88..0e75cf4 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -818,6 +818,7 @@ 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/ipa/pr78121.c b/gcc/testsuite/gcc.dg/ipa/pr78121.c
new file mode 100644
index 0000000..4a0ae18
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr78121.c
@@ -0,0 +1,16 @@
+/* PR ipa/78121 */
+/* { dg-do compile } */
+/* { dg-options "-ansi -O2 -fdump-ipa-cp-details" } */
+
+void fn2 (unsigned char c);
+int a;
+static void fn1(c) unsigned char c;
+{
+    if (a)
+          fn2 (c);
+      fn1('#');
+}
+
+void fn3() { fn1 (267); }
+
+/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\\[11, 35\\\]" 1 "cp" } } */
-- 
2.7.4

Reply via email to