diff mbox

[RFC] Handle unary pass-through jump functions for ipa-vrp

Message ID 6209da14-e430-493e-026d-6f1bc19a8265@linaro.org
State Superseded
Headers show

Commit Message

Kugan Vivekanandarajah Oct. 28, 2016, 3:03 a.m. UTC
Hi,

On 28/10/16 01:58, Jan Hubicka wrote:
>> gcc/testsuite/ChangeLog:

>>

>> 2016-10-25  Kugan Vivekanandarajah  <kuganv@linaro.org>

>>

>> 	* gcc.dg/ipa/vrp7.c: New test.

>>

>>

>> gcc/ChangeLog:

>>

>> 2016-10-25  Kugan Vivekanandarajah  <kuganv@linaro.org>

>>

>> 	* ipa-cp.c (ipa_get_jf_pass_through_result): Skip unary expressions.

>> 	(propagate_vr_accross_jump_function): Handle unary expressions.

>> 	(propagate_constants_accross_call): Pass param type to

>> 	propagate_vr_accross_jump_function.

>> 	* ipa-prop.c (load_from_param): Renamed from load_from_unmodified_param.

>> 	Also handles unary expr.

>> 	(ipa_set_jf_unary_pass_through): New.

>> 	(ipa_load_from_parm_agg): Renamed load_from_unmodified_param.

>> 	(compute_complex_assign_jump_func): Handle unary expressions.

>> 	(ipa_write_jump_function): Likewise.

>> 	(ipa_read_jump_function): Likewise.

>> 	* ipa-prop.h: export ipa_get_callee_param_type.

>

>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c

>> index 1dc5cb6..d0dc3d7 100644

>> --- a/gcc/ipa-cp.c

>> +++ b/gcc/ipa-cp.c

>> @@ -122,6 +122,7 @@ along with GCC; see the file COPYING3.  If not see

>>  #include "ipa-inline.h"

>>  #include "ipa-utils.h"

>>  #include "tree-ssa-ccp.h"

>> +#include "gimple.h"

>>

>>  template <typename valtype> class ipcp_value;

>>

>> @@ -1221,7 +1222,12 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)

>>

>>    if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)

>>      return input;

>> -  if (!is_gimple_ip_invariant (input))

>> +

>> +  if (!is_gimple_ip_invariant (input)

>> +      /* TODO: Unary expressions are not handles in ipa constant

>> +	 propagation. */

>

> handled.

> I would expect them to be already folded here?  I would expect that hanlding

> unary expressions in constant propagation is no harder than for VRP?


I have changed this now.

>

>> +     || (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))

>> +	  == tcc_unary))

>>      return NULL_TREE;

>>

>>    if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))

>> @@ -1845,7 +1851,8 @@ propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j

>>  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)

>

> New param needs comment.


Done.

Also addressed Martin's comments.

I have also separated the constant parameter conversion out and posted 
as https://gcc.gnu.org/ml/gcc-patches/2016-10/msg02309.html. This is now 
handling just unary pass-through jump functions.

Bootstrapped and regression tested on x86_64-linux-gnu with no new 
regressions.

Is this OK for trunk?

Thanks,
Kugan

gcc/testsuite/ChangeLog:

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

	* gcc.dg/ipa/vrp7.c: New test.


gcc/ChangeLog:

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

	* ipa-cp.c (ipa_get_jf_pass_through_result): Handle unary expressions.
	(propagate_vr_accross_jump_function): Likewise.
	* ipa-prop.c (ipa_set_jf_unary_pass_through): New.
	(load_from_param_1): New.
	(load_from_unmodified_param): Factor common part into load_from_param_1.
	(load_from_param): New.
	(compute_complex_assign_jump_func): Handle unary expressions.
	(ipa_write_jump_function): Likewise.
	(ipa_read_jump_function): Likewise.


> Patch is OK with changes Martin suggested.

>

> Honza

>

Comments

Martin Jambor Nov. 3, 2016, 5:36 p.m. UTC | #1
Hi,

On Fri, Oct 28, 2016 at 02:03:47PM +1100, kugan wrote:
>

> ...snip...

> 

> I have also separated the constant parameter conversion out and posted as

> https://gcc.gnu.org/ml/gcc-patches/2016-10/msg02309.html. This is now

> handling just unary pass-through jump functions.

> 

> Bootstrapped and regression tested on x86_64-linux-gnu with no new

> regressions.

> 

> Is this OK for trunk?

> 

> Thanks,

> Kugan

> 

> gcc/testsuite/ChangeLog:

> 

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

> 

> 	* gcc.dg/ipa/vrp7.c: New test.

> 

> 

> gcc/ChangeLog:

> 

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

> 

> 	* ipa-cp.c (ipa_get_jf_pass_through_result): Handle unary expressions.

> 	(propagate_vr_accross_jump_function): Likewise.

> 	* ipa-prop.c (ipa_set_jf_unary_pass_through): New.

> 	(load_from_param_1): New.

> 	(load_from_unmodified_param): Factor common part into load_from_param_1.

> 	(load_from_param): New.

> 	(compute_complex_assign_jump_func): Handle unary expressions.

> 	(ipa_write_jump_function): Likewise.

> 	(ipa_read_jump_function): Likewise.

> 

> 

> > Patch is OK with changes Martin suggested.

> > 

> > Honza

> > 


> From b7d9b413951ba20d156a7801640cc7d7bc57c062 Mon Sep 17 00:00:00 2001

> From: Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>

> Date: Fri, 28 Oct 2016 10:16:38 +1100

> Subject: [PATCH 2/2] add unary jump function

> 

> ---

>  gcc/ipa-cp.c                    | 39 +++++++++++++++---

>  gcc/ipa-prop.c                  | 89 +++++++++++++++++++++++++++++++++++------

>  gcc/testsuite/gcc.dg/ipa/vrp7.c | 32 +++++++++++++++

>  3 files changed, 142 insertions(+), 18 deletions(-)

>  create mode 100644 gcc/testsuite/gcc.dg/ipa/vrp7.c

> 

> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c

> index 9f28557..8fc95dd 100644

> --- a/gcc/ipa-cp.c

> +++ b/gcc/ipa-cp.c

> @@ -1225,13 +1225,21 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)

>      return NULL_TREE;

>  

>    if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))

> -      == tcc_comparison)

> -    restype = boolean_type_node;

> +      == tcc_unary)

> +    {

> +      res = fold_unary (ipa_get_jf_pass_through_operation (jfunc),

> +			TREE_TYPE (input), input);

> +    }


Please do not put curly braces around a single statement.  Apart from
that, no objection from me.

Thanks,

Martin
Kugan Vivekanandarajah Nov. 8, 2016, 10:13 a.m. UTC | #2
Hi,


On 04/11/16 04:36, Martin Jambor wrote:
> Hi,

>

> On Fri, Oct 28, 2016 at 02:03:47PM +1100, kugan wrote:

>>

>> ...snip...

>>

>> I have also separated the constant parameter conversion out and posted as

>> https://gcc.gnu.org/ml/gcc-patches/2016-10/msg02309.html. This is now

>> handling just unary pass-through jump functions.

>>

>> Bootstrapped and regression tested on x86_64-linux-gnu with no new

>> regressions.

>>

>> Is this OK for trunk?

>>

>> Thanks,

>> Kugan

>>

>> gcc/testsuite/ChangeLog:

>>

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

>>

>> 	* gcc.dg/ipa/vrp7.c: New test.

>>

>>

>> gcc/ChangeLog:

>>

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

>>

>> 	* ipa-cp.c (ipa_get_jf_pass_through_result): Handle unary expressions.

>> 	(propagate_vr_accross_jump_function): Likewise.

>> 	* ipa-prop.c (ipa_set_jf_unary_pass_through): New.

>> 	(load_from_param_1): New.

>> 	(load_from_unmodified_param): Factor common part into load_from_param_1.

>> 	(load_from_param): New.

>> 	(compute_complex_assign_jump_func): Handle unary expressions.

>> 	(ipa_write_jump_function): Likewise.

>> 	(ipa_read_jump_function): Likewise.

>>

>>

>>> Patch is OK with changes Martin suggested.

>>>

>>> Honza

>>>

>

>> From b7d9b413951ba20d156a7801640cc7d7bc57c062 Mon Sep 17 00:00:00 2001

>> From: Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>

>> Date: Fri, 28 Oct 2016 10:16:38 +1100

>> Subject: [PATCH 2/2] add unary jump function

>>

>> ---

>>  gcc/ipa-cp.c                    | 39 +++++++++++++++---

>>  gcc/ipa-prop.c                  | 89 +++++++++++++++++++++++++++++++++++------

>>  gcc/testsuite/gcc.dg/ipa/vrp7.c | 32 +++++++++++++++

>>  3 files changed, 142 insertions(+), 18 deletions(-)

>>  create mode 100644 gcc/testsuite/gcc.dg/ipa/vrp7.c

>>

>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c

>> index 9f28557..8fc95dd 100644

>> --- a/gcc/ipa-cp.c

>> +++ b/gcc/ipa-cp.c

>> @@ -1225,13 +1225,21 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)

>>      return NULL_TREE;

>>

>>    if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))

>> -      == tcc_comparison)

>> -    restype = boolean_type_node;

>> +      == tcc_unary)

>> +    {

>> +      res = fold_unary (ipa_get_jf_pass_through_operation (jfunc),

>> +			TREE_TYPE (input), input);

>> +    }

>

> Please do not put curly braces around a single statement.  Apart from

> that, no objection from me.


Thanks Martin, I will fix this.

Honza, is this OK for you with the above fix?

Thanks,
Kugan
>

> Thanks,

>

> Martin

>
Jan Hubicka Nov. 8, 2016, 3:17 p.m. UTC | #3
> Hi,

> 

> 

> On 04/11/16 04:36, Martin Jambor wrote:

> >Hi,

> >

> >On Fri, Oct 28, 2016 at 02:03:47PM +1100, kugan wrote:

> >>

> >>...snip...

> >>

> >>I have also separated the constant parameter conversion out and posted as

> >>https://gcc.gnu.org/ml/gcc-patches/2016-10/msg02309.html. This is now

> >>handling just unary pass-through jump functions.

> >>

> >>Bootstrapped and regression tested on x86_64-linux-gnu with no new

> >>regressions.

> >>

> >>Is this OK for trunk?

> >>

> >>Thanks,

> >>Kugan

> >>

> >>gcc/testsuite/ChangeLog:

> >>

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

> >>

> >>	* gcc.dg/ipa/vrp7.c: New test.

> >>

> >>

> >>gcc/ChangeLog:

> >>

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

> >>

> >>	* ipa-cp.c (ipa_get_jf_pass_through_result): Handle unary expressions.

> >>	(propagate_vr_accross_jump_function): Likewise.

> >>	* ipa-prop.c (ipa_set_jf_unary_pass_through): New.

> >>	(load_from_param_1): New.

> >>	(load_from_unmodified_param): Factor common part into load_from_param_1.

> >>	(load_from_param): New.

> >>	(compute_complex_assign_jump_func): Handle unary expressions.

> >>	(ipa_write_jump_function): Likewise.

> >>	(ipa_read_jump_function): Likewise.

> >>

> >>

> >>>Patch is OK with changes Martin suggested.

> >>>

> >>>Honza

> >>>

> >

> >>From b7d9b413951ba20d156a7801640cc7d7bc57c062 Mon Sep 17 00:00:00 2001

> >>From: Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>

> >>Date: Fri, 28 Oct 2016 10:16:38 +1100

> >>Subject: [PATCH 2/2] add unary jump function

> >>

> >>---

> >> gcc/ipa-cp.c                    | 39 +++++++++++++++---

> >> gcc/ipa-prop.c                  | 89 +++++++++++++++++++++++++++++++++++------

> >> gcc/testsuite/gcc.dg/ipa/vrp7.c | 32 +++++++++++++++

> >> 3 files changed, 142 insertions(+), 18 deletions(-)

> >> create mode 100644 gcc/testsuite/gcc.dg/ipa/vrp7.c

> >>

> >>diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c

> >>index 9f28557..8fc95dd 100644

> >>--- a/gcc/ipa-cp.c

> >>+++ b/gcc/ipa-cp.c

> >>@@ -1225,13 +1225,21 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)

> >>     return NULL_TREE;

> >>

> >>   if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))

> >>-      == tcc_comparison)

> >>-    restype = boolean_type_node;

> >>+      == tcc_unary)

> >>+    {

> >>+      res = fold_unary (ipa_get_jf_pass_through_operation (jfunc),

> >>+			TREE_TYPE (input), input);

> >>+    }

> >

> >Please do not put curly braces around a single statement.  Apart from

> >that, no objection from me.

> 

> Thanks Martin, I will fix this.

> 

> Honza, is this OK for you with the above fix?


OK,
thanks!
Honza
> 

> Thanks,

> Kugan

> >

> >Thanks,

> >

> >Martin

> >
Bin.Cheng Nov. 11, 2016, 3:46 p.m. UTC | #4
On Tue, Nov 8, 2016 at 10:13 AM, kugan
<kugan.vivekanandarajah@linaro.org> wrote:
> Hi,

>

>

>

> On 04/11/16 04:36, Martin Jambor wrote:

>>

>> Hi,

>>

>> On Fri, Oct 28, 2016 at 02:03:47PM +1100, kugan wrote:

>>>

>>>

>>> ...snip...

>>>

>>> I have also separated the constant parameter conversion out and posted as

>>> https://gcc.gnu.org/ml/gcc-patches/2016-10/msg02309.html. This is now

>>> handling just unary pass-through jump functions.

>>>

>>> Bootstrapped and regression tested on x86_64-linux-gnu with no new

>>> regressions.

>>>

>>> Is this OK for trunk?

>>>

>>> Thanks,

>>> Kugan

>>>

>>> gcc/testsuite/ChangeLog:

>>>

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

>>>

>>>         * gcc.dg/ipa/vrp7.c: New test.

>>>

>>>

>>> gcc/ChangeLog:

>>>

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

>>>

>>>         * ipa-cp.c (ipa_get_jf_pass_through_result): Handle unary

>>> expressions.

>>>         (propagate_vr_accross_jump_function): Likewise.

>>>         * ipa-prop.c (ipa_set_jf_unary_pass_through): New.

>>>         (load_from_param_1): New.

>>>         (load_from_unmodified_param): Factor common part into

>>> load_from_param_1.

>>>         (load_from_param): New.

>>>         (compute_complex_assign_jump_func): Handle unary expressions.

>>>         (ipa_write_jump_function): Likewise.

>>>         (ipa_read_jump_function): Likewise.

>>>

>>>

>>>> Patch is OK with changes Martin suggested.

>>>>

>>>> Honza

>>>>

>>

>>> From b7d9b413951ba20d156a7801640cc7d7bc57c062 Mon Sep 17 00:00:00 2001

>>> From: Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>

>>> Date: Fri, 28 Oct 2016 10:16:38 +1100

>>> Subject: [PATCH 2/2] add unary jump function

>>>

>>> ---

>>>  gcc/ipa-cp.c                    | 39 +++++++++++++++---

>>>  gcc/ipa-prop.c                  | 89

>>> +++++++++++++++++++++++++++++++++++------

>>>  gcc/testsuite/gcc.dg/ipa/vrp7.c | 32 +++++++++++++++

>>>  3 files changed, 142 insertions(+), 18 deletions(-)

>>>  create mode 100644 gcc/testsuite/gcc.dg/ipa/vrp7.c

>>>

>>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c

>>> index 9f28557..8fc95dd 100644

>>> --- a/gcc/ipa-cp.c

>>> +++ b/gcc/ipa-cp.c

>>> @@ -1225,13 +1225,21 @@ ipa_get_jf_pass_through_result (struct

>>> ipa_jump_func *jfunc, tree input)

>>>      return NULL_TREE;

>>>

>>>    if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))

>>> -      == tcc_comparison)

>>> -    restype = boolean_type_node;

>>> +      == tcc_unary)

>>> +    {

>>> +      res = fold_unary (ipa_get_jf_pass_through_operation (jfunc),

>>> +                       TREE_TYPE (input), input);

>>> +    }

>>

>>

>> Please do not put curly braces around a single statement.  Apart from

>> that, no objection from me.

>

>

> Thanks Martin, I will fix this.

>

> Honza, is this OK for you with the above fix?

>

> Thanks,

> Kugan

>>

>>

>> Thanks,

>>

>> Martin

>>

>

Hi,
This new test fails on AArch64.  I created PR78316 for tracking.

Thanks,
bin
diff mbox

Patch

From b7d9b413951ba20d156a7801640cc7d7bc57c062 Mon Sep 17 00:00:00 2001
From: Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
Date: Fri, 28 Oct 2016 10:16:38 +1100
Subject: [PATCH 2/2] add unary jump function

---
 gcc/ipa-cp.c                    | 39 +++++++++++++++---
 gcc/ipa-prop.c                  | 89 +++++++++++++++++++++++++++++++++++------
 gcc/testsuite/gcc.dg/ipa/vrp7.c | 32 +++++++++++++++
 3 files changed, 142 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/vrp7.c

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 9f28557..8fc95dd 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1225,13 +1225,21 @@  ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
     return NULL_TREE;
 
   if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
-      == tcc_comparison)
-    restype = boolean_type_node;
+      == tcc_unary)
+    {
+      res = fold_unary (ipa_get_jf_pass_through_operation (jfunc),
+			TREE_TYPE (input), input);
+    }
   else
-    restype = TREE_TYPE (input);
-  res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype,
-		     input, ipa_get_jf_pass_through_operand (jfunc));
-
+    {
+      if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
+	  == tcc_comparison)
+	restype = boolean_type_node;
+      else
+	restype = TREE_TYPE (input);
+      res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype,
+			 input, ipa_get_jf_pass_through_operand (jfunc));
+    }
   if (res && !is_gimple_ip_invariant (res))
     return NULL_TREE;
 
@@ -1870,6 +1878,25 @@  propagate_vr_accross_jump_function (cgraph_edge *cs,
 
       if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
 	return dest_lat->meet_with (src_lats->m_value_range);
+      else if (param_type
+	       && (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
+		   == tcc_unary))
+	{
+	  value_range vr;
+	  memset (&vr, 0, sizeof (vr));
+	  tree operand_type = ipa_get_type (caller_info, src_idx);
+	  enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
+
+	  if (src_lats->m_value_range.bottom_p ())
+	    return false;
+
+	  extract_range_from_unary_expr (&vr,
+					 operation,
+					 param_type,
+					 &src_lats->m_value_range.m_vr,
+					 operand_type);
+	  return dest_lat->meet_with (&vr);
+	}
     }
   else if (jfunc->type == IPA_JF_CONST)
     {
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 74fe199..8312c5a 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -446,6 +446,18 @@  ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
   jfunc->value.pass_through.agg_preserved = agg_preserved;
 }
 
+/* Set JFUNC to be an unary pass through jump function.  */
+
+static void
+ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
+			       enum tree_code operation)
+{
+  jfunc->type = IPA_JF_PASS_THROUGH;
+  jfunc->value.pass_through.operand = NULL_TREE;
+  jfunc->value.pass_through.formal_id = formal_id;
+  jfunc->value.pass_through.operation = operation;
+  jfunc->value.pass_through.agg_preserved = false;
+}
 /* Set JFUNC to be an arithmetic pass through jump function.  */
 
 static void
@@ -849,21 +861,19 @@  parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
   return !modified;
 }
 
-/* If STMT is an assignment that loads a value from an parameter declaration,
-   return the index of the parameter in ipa_node_params which has not been
-   modified.  Otherwise return -1.  */
+/* Main worker for load_from_unmodified_param and load_from_param.
+   If STMT is an assignment that loads a value from an parameter declaration,
+   return the index of the parameter in ipa_node_params.  Otherwise return -1.  */
 
 static int
-load_from_unmodified_param (struct ipa_func_body_info *fbi,
-			    vec<ipa_param_descriptor> descriptors,
-			    gimple *stmt)
+load_from_param_1 (struct ipa_func_body_info *fbi,
+		   vec<ipa_param_descriptor> descriptors,
+		   gimple *stmt)
 {
   int index;
   tree op1;
 
-  if (!gimple_assign_single_p (stmt))
-    return -1;
-
+  gcc_checking_assert (is_gimple_assign (stmt));
   op1 = gimple_assign_rhs1 (stmt);
   if (TREE_CODE (op1) != PARM_DECL)
     return -1;
@@ -876,6 +886,40 @@  load_from_unmodified_param (struct ipa_func_body_info *fbi,
   return index;
 }
 
+/* If STMT is an assignment that loads a value from an parameter declaration,
+   return the index of the parameter in ipa_node_params which has not been
+   modified.  Otherwise return -1.  */
+
+static int
+load_from_unmodified_param (struct ipa_func_body_info *fbi,
+			    vec<ipa_param_descriptor> descriptors,
+			    gimple *stmt)
+{
+  if (!gimple_assign_single_p (stmt))
+    return -1;
+
+  return load_from_param_1 (fbi, descriptors, stmt);
+}
+
+/* If STMT is an assignment that loads a value from an parameter declaration,
+   return the index of the parameter in ipa_node_params.  Otherwise return -1.  */
+
+static int
+load_from_param (struct ipa_func_body_info *fbi,
+		 vec<ipa_param_descriptor> descriptors,
+		 gimple *stmt)
+{
+  if (!is_gimple_assign (stmt))
+    return -1;
+
+  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
+  if ((get_gimple_rhs_class (rhs_code) != GIMPLE_SINGLE_RHS)
+      && (get_gimple_rhs_class (rhs_code) != GIMPLE_UNARY_RHS))
+    return -1;
+
+  return load_from_param_1 (fbi, descriptors, stmt);
+}
+
 /* Return true if memory reference REF (which must be a load through parameter
    with INDEX) loads data that are known to be unmodified in this function
    before reaching statement STMT.  */
@@ -1109,6 +1153,7 @@  compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
   tree op1, tc_ssa, base, ssa;
   bool reverse;
   int index;
+  gimple *stmt2 = stmt;
 
   op1 = gimple_assign_rhs1 (stmt);
 
@@ -1117,13 +1162,16 @@  compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
       if (SSA_NAME_IS_DEFAULT_DEF (op1))
 	index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
       else
-	index = load_from_unmodified_param (fbi, info->descriptors,
-					    SSA_NAME_DEF_STMT (op1));
+	{
+	  index = load_from_param (fbi, info->descriptors,
+				   SSA_NAME_DEF_STMT (op1));
+	  stmt2 = SSA_NAME_DEF_STMT (op1);
+	}
       tc_ssa = op1;
     }
   else
     {
-      index = load_from_unmodified_param (fbi, info->descriptors, stmt);
+      index = load_from_param (fbi, info->descriptors, stmt);
       tc_ssa = gimple_assign_lhs (stmt);
     }
 
@@ -1147,6 +1195,13 @@  compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
 	  bool agg_p = parm_ref_data_pass_through_p (fbi, index, call, tc_ssa);
 	  ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
 	}
+      else if (is_gimple_assign (stmt2)
+	       && (gimple_expr_code (stmt2) != NOP_EXPR)
+	       && (TREE_CODE_CLASS (gimple_expr_code (stmt2)) == tcc_unary))
+	{
+	  ipa_set_jf_unary_pass_through (jfunc, index,
+					 gimple_assign_rhs_code (stmt2));
+	}
       return;
     }
 
@@ -4666,6 +4721,11 @@  ipa_write_jump_function (struct output_block *ob,
 	  bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
 	  streamer_write_bitpack (&bp);
 	}
+      else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
+	       == tcc_unary)
+	{
+	  streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
+	}
       else
 	{
 	  stream_write_tree (ob, jump_func->value.pass_through.operand, true);
@@ -4745,6 +4805,11 @@  ipa_read_jump_function (struct lto_input_block *ib,
 	  bool agg_preserved = bp_unpack_value (&bp, 1);
 	  ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
 	}
+      else if (TREE_CODE_CLASS (operation) == tcc_unary)
+	{
+	  int formal_id =  streamer_read_uhwi (ib);
+	  ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
+	}
       else
 	{
 	  tree operand = stream_read_tree (ib, data_in);
diff --git a/gcc/testsuite/gcc.dg/ipa/vrp7.c b/gcc/testsuite/gcc.dg/ipa/vrp7.c
new file mode 100644
index 0000000..e4e0bc6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/vrp7.c
@@ -0,0 +1,32 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-cp-details" } */
+
+volatile int cond;
+int abs (int);
+
+static __attribute__((noinline, noclone))
+int foo (int i)
+{
+  if (i < 5)
+    __builtin_abort ();
+  return 0;
+}
+
+static __attribute__((noinline, noclone))
+int bar (int j)
+{
+  foo (~j);
+  foo (abs (j));
+  foo (j);
+  return 0;
+}
+
+int main ()
+{
+  for (unsigned int i = 0; i < 10; ++i)
+    bar (i);
+
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\\[-10, 9\\\]" 1 "cp" } } */
-- 
2.7.4