public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] Handle unary pass-through jump functions for ipa-vrp
@ 2016-10-24 23:18 kugan
  2016-10-27 12:11 ` Martin Jambor
  2016-10-27 14:59 ` [RFC] Handle unary pass-through jump functions for ipa-vrp Jan Hubicka
  0 siblings, 2 replies; 19+ messages in thread
From: kugan @ 2016-10-24 23:18 UTC (permalink / raw)
  To: gcc-patches, Jan Hubicka, Martin Jambor

[-- Attachment #1: Type: text/plain, Size: 1311 bytes --]

Hi,

Attached RFC patch handles unary pass-through jump functions for ipa-vrp 
such that in the following case:

int bar (int j)
{
   foo (~j);
   foo (abs (j));
   foo (j);
   return 0;
}

We can infer value ranges for argument foo from bar. See test-case 
vrp7.c in the patch.

I will also try to handle other passes like constant propagation as 
follow up based on the comments.

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

Does this look OK?

Thanks,
Kugan

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.

[-- Attachment #2: p.txt --]
[-- Type: text/plain, Size: 9031 bytes --]

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. */
+     || (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)
 {
   struct ipcp_param_lattices *src_lats;
   ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
@@ -1863,18 +1870,43 @@ 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);
+
+	  if (src_lats->m_value_range.bottom_p ())
+	    return false;
+
+	  extract_range_from_unary_expr (&vr,
+					 ipa_get_jf_pass_through_operation (jfunc),
+					 param_type,
+					 &src_lats->m_value_range.m_vr,
+					 operand_type);
+	  return dest_lat->meet_with (&vr);
+	}
     }
-  else if (jfunc->type == IPA_JF_CONST)
+  else if (param_type
+	   && jfunc->type == IPA_JF_CONST)
     {
       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));
 	  return dest_lat->meet_with (&jfunc->m_vr);
 	}
     }
@@ -2220,6 +2252,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 +2269,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..9147b27 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
@@ -850,18 +862,17 @@ parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int 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.  */
+   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 (struct ipa_func_body_info *fbi,
+		 vec<ipa_param_descriptor> descriptors,
+		 gimple *stmt)
 {
   int index;
   tree op1;
 
-  if (!gimple_assign_single_p (stmt))
+  if (!is_gimple_assign (stmt))
     return -1;
 
   op1 = gimple_assign_rhs1 (stmt);
@@ -1025,7 +1036,7 @@ ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
       */
 
       gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
-      index = load_from_unmodified_param (fbi, descriptors, def);
+      index = load_from_param (fbi, descriptors, def);
     }
 
   if (index >= 0)
@@ -1109,6 +1120,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 +1129,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 +1162,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;
     }
 
@@ -1595,7 +1617,7 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
     }
 }
 
-static tree
+tree
 ipa_get_callee_param_type (struct cgraph_edge *e, int i)
 {
   int n;
@@ -4663,6 +4685,10 @@ 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);
@@ -4742,6 +4768,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/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/vrp7.c b/gcc/testsuite/gcc.dg/ipa/vrp7.c
index e69de29..e4e0bc6 100644
--- a/gcc/testsuite/gcc.dg/ipa/vrp7.c
+++ 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" } } */

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Handle unary pass-through jump functions for ipa-vrp
  2016-10-24 23:18 [RFC] Handle unary pass-through jump functions for ipa-vrp kugan
@ 2016-10-27 12:11 ` Martin Jambor
  2016-10-28  2:58   ` [ipa-vrp] ice in set_value_range kugan
  2016-10-27 14:59 ` [RFC] Handle unary pass-through jump functions for ipa-vrp Jan Hubicka
  1 sibling, 1 reply; 19+ messages in thread
From: Martin Jambor @ 2016-10-27 12:11 UTC (permalink / raw)
  To: kugan; +Cc: gcc-patches, Jan Hubicka

Hi,

On Tue, Oct 25, 2016 at 10:18:25AM +1100, kugan wrote:
> Hi,
> 
> Attached RFC patch handles unary pass-through jump functions for ipa-vrp
> such that in the following case:
> 
> int bar (int j)
> {
>   foo (~j);
>   foo (abs (j));
>   foo (j);
>   return 0;
> }

Thanks for working on this.  Although I cannot approve your patches, I
do have a few comments inline:


> 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. */
> +     || (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)

Please also add a brief description of the new parameter to the
function comment.

>  {
>    struct ipcp_param_lattices *src_lats;
>    ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
> @@ -1863,18 +1870,43 @@ 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);
> +
> +	  if (src_lats->m_value_range.bottom_p ())
> +	    return false;
> +
> +	  extract_range_from_unary_expr (&vr,
> +					 ipa_get_jf_pass_through_operation (jfunc),

Here you get over 80 characters of text width.  Tough to deal with, I
know, but please fix :-)

> +					 param_type,
> +					 &src_lats->m_value_range.m_vr,
> +					 operand_type);
> +	  return dest_lat->meet_with (&vr);
> +	}
>      }
> -  else if (jfunc->type == IPA_JF_CONST)
> +  else if (param_type
> +	   && jfunc->type == IPA_JF_CONST)
>      {
>        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)?

Side note: I wonder whether it is a good idea to store the
intermediary result to the jump function.  I'd prefer if we did that
only after actually making transformation decisions, if at all.  But
that is only a minor nit and not something that needs to be addressed
as a part of this change.

>  	  return dest_lat->meet_with (&jfunc->m_vr);
>  	}
>      }
> @@ -2220,6 +2252,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 +2269,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..9147b27 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
> @@ -850,18 +862,17 @@ parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int 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.  */
> +   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 (struct ipa_func_body_info *fbi,
> +		 vec<ipa_param_descriptor> descriptors,
> +		 gimple *stmt)

This is the only thing I dislike in this patch, I would like to keep
the ability to really know that we are looking at a load of an
unmodified parameter for cases when it is required/useful (e.g. in
ipa_load_from_parm_agg which I suppose "works" because there are not
that many unary operations on pointers).

Please either provide two distinct functions (sharing the common parts
in a load_from_param_1 function) or add a parameter that will
differentiate between unmodified and unary-op-modified parameters.
One way could be that the that parameter would be pointer to an enum
tree_code in which the function will return the OP for you if non-NULL
and will insist on a GIMPLE_SINGLE_RHS if it is NULL.

>  {
>    int index;
>    tree op1;
>  
> -  if (!gimple_assign_single_p (stmt))
> +  if (!is_gimple_assign (stmt))
>      return -1;

Even in the modifying case, I still think that you want to check any
operation embedded in the statement is GIMPLE_UNARY_RHS or
GIMPLE_SINGLE_RHS.

>  
>    op1 = gimple_assign_rhs1 (stmt);
> @@ -1025,7 +1036,7 @@ ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
>        */
>  
>        gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
> -      index = load_from_unmodified_param (fbi, descriptors, def);
> +      index = load_from_param (fbi, descriptors, def);
>      }
>  
>    if (index >= 0)
> @@ -1109,6 +1120,7 @@ compute_complex_assign_jump_func (struct
> ipa_func_body_info *fbi,

After you add this new capability to the function, its comment will
need an update.

>    tree op1, tc_ssa, base, ssa;
>    bool reverse;
>    int index;
> +  gimple *stmt2 = stmt;
>  
>    op1 = gimple_assign_rhs1 (stmt);
>  
> @@ -1117,13 +1129,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 +1162,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;
>      }
>  
> @@ -1595,7 +1617,7 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
>      }
>  }
>  
> -static tree
> +tree
>  ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>  {
>    int n;
> @@ -4663,6 +4685,10 @@ 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)

This is quite clearly over 80 characters wide.


Apart from the above, I'll be happy to see this in.

Thanks,

Martin

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Handle unary pass-through jump functions for ipa-vrp
  2016-10-24 23:18 [RFC] Handle unary pass-through jump functions for ipa-vrp kugan
  2016-10-27 12:11 ` Martin Jambor
@ 2016-10-27 14:59 ` Jan Hubicka
  2016-10-28  3:04   ` kugan
  1 sibling, 1 reply; 19+ messages in thread
From: Jan Hubicka @ 2016-10-27 14:59 UTC (permalink / raw)
  To: kugan; +Cc: gcc-patches, Jan Hubicka, Martin Jambor

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

> +     || (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.

Patch is OK with changes Martin suggested.

Honza

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [ipa-vrp] ice in set_value_range
  2016-10-27 12:11 ` Martin Jambor
@ 2016-10-28  2:58   ` kugan
  2016-11-03 16:25     ` Martin Jambor
  0 siblings, 1 reply; 19+ messages in thread
From: kugan @ 2016-10-28  2:58 UTC (permalink / raw)
  To: gcc-patches, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 1585 bytes --]

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  <kuganv@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  <kuganv@linaro.org>

	PR ipa/78121
	* gcc.dg/ipa/pr78121.c: New test.

[-- Attachment #2: 0001-fix-convertion.patch --]
[-- Type: text/x-patch, Size: 4162 bytes --]

From 64776c1b43c9fd68aee6c40624660d20e1c4e653 Mon Sep 17 00:00:00 2001
From: Kugan Vivekanandarajah <kugan.vivekanandarajah@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


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Handle unary pass-through jump functions for ipa-vrp
  2016-10-27 14:59 ` [RFC] Handle unary pass-through jump functions for ipa-vrp Jan Hubicka
@ 2016-10-28  3:04   ` kugan
  2016-11-03 17:36     ` Martin Jambor
  0 siblings, 1 reply; 19+ messages in thread
From: kugan @ 2016-10-28  3:04 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches, Martin Jambor

[-- Attachment #1: Type: text/plain, Size: 3451 bytes --]

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
>

[-- Attachment #2: 0002-add-unary-jump-function.patch --]
[-- Type: text/x-patch, Size: 8633 bytes --]

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


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [ipa-vrp] ice in set_value_range
  2016-10-28  2:58   ` [ipa-vrp] ice in set_value_range kugan
@ 2016-11-03 16:25     ` Martin Jambor
  2016-11-08 10:11       ` kugan
  0 siblings, 1 reply; 19+ messages in thread
From: Martin Jambor @ 2016-11-03 16:25 UTC (permalink / raw)
  To: kugan; +Cc: gcc-patches, Jan Hubicka

Hi,

On Fri, Oct 28, 2016 at 01:58:13PM +1100, kugan wrote:
> > 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?
> 

I have no objections, but we need to wait for Honza.

Thanks,

Martin

> Thanks,
> Kugan
> 
> 
> gcc/ChangeLog:
> 
> 2016-10-28  Kugan Vivekanandarajah  <kuganv@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  <kuganv@linaro.org>
> 
> 	PR ipa/78121
> 	* gcc.dg/ipa/pr78121.c: New test.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Handle unary pass-through jump functions for ipa-vrp
  2016-10-28  3:04   ` kugan
@ 2016-11-03 17:36     ` Martin Jambor
  2016-11-08 10:13       ` kugan
  0 siblings, 1 reply; 19+ messages in thread
From: Martin Jambor @ 2016-11-03 17:36 UTC (permalink / raw)
  To: kugan; +Cc: Jan Hubicka, gcc-patches

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [ipa-vrp] ice in set_value_range
  2016-11-03 16:25     ` Martin Jambor
@ 2016-11-08 10:11       ` kugan
  2016-11-08 15:17         ` Jan Hubicka
  2016-11-09  6:02         ` Andrew Pinski
  0 siblings, 2 replies; 19+ messages in thread
From: kugan @ 2016-11-08 10:11 UTC (permalink / raw)
  To: gcc-patches, Jan Hubicka

Hi,

On 04/11/16 03:24, Martin Jambor wrote:
> Hi,
>
> On Fri, Oct 28, 2016 at 01:58:13PM +1100, kugan wrote:
>>> 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?
>>
>
> I have no objections, but we need to wait for Honza.
Thanks.

Honza, is this OK for you ?

Thanks,
Kugan

>
> Thanks,
>
> Martin
>
>> Thanks,
>> Kugan
>>
>>
>> gcc/ChangeLog:
>>
>> 2016-10-28  Kugan Vivekanandarajah  <kuganv@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  <kuganv@linaro.org>
>>
>> 	PR ipa/78121
>> 	* gcc.dg/ipa/pr78121.c: New test.
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Handle unary pass-through jump functions for ipa-vrp
  2016-11-03 17:36     ` Martin Jambor
@ 2016-11-08 10:13       ` kugan
  2016-11-08 15:17         ` Jan Hubicka
  2016-11-11 15:46         ` Bin.Cheng
  0 siblings, 2 replies; 19+ messages in thread
From: kugan @ 2016-11-08 10:13 UTC (permalink / raw)
  To: Jan Hubicka, gcc-patches

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
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [ipa-vrp] ice in set_value_range
  2016-11-08 10:11       ` kugan
@ 2016-11-08 15:17         ` Jan Hubicka
  2016-11-09  6:02         ` Andrew Pinski
  1 sibling, 0 replies; 19+ messages in thread
From: Jan Hubicka @ 2016-11-08 15:17 UTC (permalink / raw)
  To: kugan; +Cc: gcc-patches, Jan Hubicka

> Hi,
> 
> On 04/11/16 03:24, Martin Jambor wrote:
> >Hi,
> >
> >On Fri, Oct 28, 2016 at 01:58:13PM +1100, kugan wrote:
> >>>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?
> >>
> >
> >I have no objections, but we need to wait for Honza.
> Thanks.
> 
> Honza, is this OK for you ?
OK,
thanks!
Honza
> 
> Thanks,
> Kugan
> 
> >
> >Thanks,
> >
> >Martin
> >
> >>Thanks,
> >>Kugan
> >>
> >>
> >>gcc/ChangeLog:
> >>
> >>2016-10-28  Kugan Vivekanandarajah  <kuganv@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  <kuganv@linaro.org>
> >>
> >>	PR ipa/78121
> >>	* gcc.dg/ipa/pr78121.c: New test.
> >

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Handle unary pass-through jump functions for ipa-vrp
  2016-11-08 10:13       ` kugan
@ 2016-11-08 15:17         ` Jan Hubicka
  2016-11-13  8:20           ` kugan
  2016-11-11 15:46         ` Bin.Cheng
  1 sibling, 1 reply; 19+ messages in thread
From: Jan Hubicka @ 2016-11-08 15:17 UTC (permalink / raw)
  To: kugan; +Cc: Jan Hubicka, gcc-patches

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [ipa-vrp] ice in set_value_range
  2016-11-08 10:11       ` kugan
  2016-11-08 15:17         ` Jan Hubicka
@ 2016-11-09  6:02         ` Andrew Pinski
  2016-11-09  8:02           ` kugan
  2016-11-10  8:12           ` Andreas Schwab
  1 sibling, 2 replies; 19+ messages in thread
From: Andrew Pinski @ 2016-11-09  6:02 UTC (permalink / raw)
  To: kugan; +Cc: gcc-patches, Jan Hubicka

On Tue, Nov 8, 2016 at 2:11 AM, kugan <kugan.vivekanandarajah@linaro.org> wrote:
> Hi,
>
> On 04/11/16 03:24, Martin Jambor wrote:
>>
>> Hi,
>>
>> On Fri, Oct 28, 2016 at 01:58:13PM +1100, kugan wrote:
>>>>
>>>> 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?
>>>
>>
>> I have no objections, but we need to wait for Honza.
>
> Thanks.
>
> Honza, is this OK for you ?


Either this patch or the patch for "Handle unary pass-through jump
functions for ipa-vrp" caused a bootstrap failure on
aarch64-linux-gnu.
Bootstrap comparison failure!
gcc/go/types.o differs
gcc/fortran/class.o differs
gcc/tree-ssa-live.o differs
gcc/data-streamer-out.o differs
gcc/ira-build.o differs
gcc/hsa-gen.o differs
gcc/hsa-brig.o differs
gcc/omp-low.o differs
gcc/lto-streamer-in.o differs
gcc/real.o differs
gcc/final.o differs
gcc/df-core.o differs

I bootstrap with the following options:

--with-cpu=thunderx+lse --enable-languages=c,c++,fortran,go
--disable-werror --with-sysroot=/ --enable-plugins
--enable-gnu-indirect-function

I have not tried removing the +lse part though

Thanks,
Andrew Pinski


>
> Thanks,
> Kugan
>
>
>>
>> Thanks,
>>
>> Martin
>>
>>> Thanks,
>>> Kugan
>>>
>>>
>>> gcc/ChangeLog:
>>>
>>> 2016-10-28  Kugan Vivekanandarajah  <kuganv@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  <kuganv@linaro.org>
>>>
>>>         PR ipa/78121
>>>         * gcc.dg/ipa/pr78121.c: New test.
>>
>>
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [ipa-vrp] ice in set_value_range
  2016-11-09  6:02         ` Andrew Pinski
@ 2016-11-09  8:02           ` kugan
  2016-11-10  6:14             ` Andrew Pinski
  2016-11-10  8:12           ` Andreas Schwab
  1 sibling, 1 reply; 19+ messages in thread
From: kugan @ 2016-11-09  8:02 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: gcc-patches, Jan Hubicka

Hi Andrew,

On 09/11/16 17:02, Andrew Pinski wrote:
> Either this patch or the patch for "Handle unary pass-through jump
> functions for ipa-vrp" caused a bootstrap failure on
> aarch64-linux-gnu.
> Bootstrap comparison failure!
> gcc/go/types.o differs
> gcc/fortran/class.o differs
> gcc/tree-ssa-live.o differs
> gcc/data-streamer-out.o differs
> gcc/ira-build.o differs
> gcc/hsa-gen.o differs
> gcc/hsa-brig.o differs
> gcc/omp-low.o differs
> gcc/lto-streamer-in.o differs
> gcc/real.o differs
> gcc/final.o differs
> gcc/df-core.o differs
>
> I bootstrap with the following options:
>
> --with-cpu=thunderx+lse --enable-languages=c,c++,fortran,go
> --disable-werror --with-sysroot=/ --enable-plugins
> --enable-gnu-indirect-function
>
> I have not tried removing the +lse part though

Sorry about the breakage. I will try to reproduce this.

Thanks,
Kugan

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [ipa-vrp] ice in set_value_range
  2016-11-09  8:02           ` kugan
@ 2016-11-10  6:14             ` Andrew Pinski
  2016-11-10  6:18               ` kugan
  0 siblings, 1 reply; 19+ messages in thread
From: Andrew Pinski @ 2016-11-10  6:14 UTC (permalink / raw)
  To: kugan; +Cc: gcc-patches, Jan Hubicka

On Wed, Nov 9, 2016 at 12:01 AM, kugan
<kugan.vivekanandarajah@linaro.org> wrote:
> Hi Andrew,
>
> On 09/11/16 17:02, Andrew Pinski wrote:
>>
>> Either this patch or the patch for "Handle unary pass-through jump
>> functions for ipa-vrp" caused a bootstrap failure on
>> aarch64-linux-gnu.
>> Bootstrap comparison failure!
>> gcc/go/types.o differs
>> gcc/fortran/class.o differs
>> gcc/tree-ssa-live.o differs
>> gcc/data-streamer-out.o differs
>> gcc/ira-build.o differs
>> gcc/hsa-gen.o differs
>> gcc/hsa-brig.o differs
>> gcc/omp-low.o differs
>> gcc/lto-streamer-in.o differs
>> gcc/real.o differs
>> gcc/final.o differs
>> gcc/df-core.o differs
>>
>> I bootstrap with the following options:
>>
>> --with-cpu=thunderx+lse --enable-languages=c,c++,fortran,go
>> --disable-werror --with-sysroot=/ --enable-plugins
>> --enable-gnu-indirect-function
>>
>> I have not tried removing the +lse part though

I was able to reproduce it with just  --with-cpu=thunderx .  I am
trying without " --with-cpu=thunderx" now.  This is in my jenkins env
and I have not tried to reproduce it outside of it yet.

Thanks,
Andrew

>
>
> Sorry about the breakage. I will try to reproduce this.
>
> Thanks,
> Kugan

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [ipa-vrp] ice in set_value_range
  2016-11-10  6:14             ` Andrew Pinski
@ 2016-11-10  6:18               ` kugan
  0 siblings, 0 replies; 19+ messages in thread
From: kugan @ 2016-11-10  6:18 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: gcc-patches, Jan Hubicka

Hi Andrew,

On 10/11/16 17:14, Andrew Pinski wrote:
> On Wed, Nov 9, 2016 at 12:01 AM, kugan
> <kugan.vivekanandarajah@linaro.org> wrote:
>> Hi Andrew,
>>
>> On 09/11/16 17:02, Andrew Pinski wrote:
>>>
>>> Either this patch or the patch for "Handle unary pass-through jump
>>> functions for ipa-vrp" caused a bootstrap failure on
>>> aarch64-linux-gnu.
>>> Bootstrap comparison failure!
>>> gcc/go/types.o differs
>>> gcc/fortran/class.o differs
>>> gcc/tree-ssa-live.o differs
>>> gcc/data-streamer-out.o differs
>>> gcc/ira-build.o differs
>>> gcc/hsa-gen.o differs
>>> gcc/hsa-brig.o differs
>>> gcc/omp-low.o differs
>>> gcc/lto-streamer-in.o differs
>>> gcc/real.o differs
>>> gcc/final.o differs
>>> gcc/df-core.o differs
>>>
>>> I bootstrap with the following options:
>>>
>>> --with-cpu=thunderx+lse --enable-languages=c,c++,fortran,go
>>> --disable-werror --with-sysroot=/ --enable-plugins
>>> --enable-gnu-indirect-function
>>>
>>> I have not tried removing the +lse part though
>
> I was able to reproduce it with just  --with-cpu=thunderx .  I am
> trying without " --with-cpu=thunderx" now.  This is in my jenkins env
> and I have not tried to reproduce it outside of it yet.

I can reproduce it. I am going to revert it as this is affecting your 
bootstrap. I will commit after fixing this (of-course after review)

Thanks,
Kugan

> Thanks,
> Andrew
>
>>
>>
>> Sorry about the breakage. I will try to reproduce this.
>>
>> Thanks,
>> Kugan

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [ipa-vrp] ice in set_value_range
  2016-11-09  6:02         ` Andrew Pinski
  2016-11-09  8:02           ` kugan
@ 2016-11-10  8:12           ` Andreas Schwab
  1 sibling, 0 replies; 19+ messages in thread
From: Andreas Schwab @ 2016-11-10  8:12 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: kugan, gcc-patches, Jan Hubicka

On Nov 09 2016, Andrew Pinski <pinskia@gmail.com> wrote:

> Either this patch or the patch for "Handle unary pass-through jump
> functions for ipa-vrp" caused a bootstrap failure on
> aarch64-linux-gnu.
> Bootstrap comparison failure!
> gcc/go/types.o differs
> gcc/fortran/class.o differs
> gcc/tree-ssa-live.o differs
> gcc/data-streamer-out.o differs
> gcc/ira-build.o differs
> gcc/hsa-gen.o differs
> gcc/hsa-brig.o differs
> gcc/omp-low.o differs
> gcc/lto-streamer-in.o differs
> gcc/real.o differs
> gcc/final.o differs
> gcc/df-core.o differs

Similar failure on ia64.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Handle unary pass-through jump functions for ipa-vrp
  2016-11-08 10:13       ` kugan
  2016-11-08 15:17         ` Jan Hubicka
@ 2016-11-11 15:46         ` Bin.Cheng
  1 sibling, 0 replies; 19+ messages in thread
From: Bin.Cheng @ 2016-11-11 15:46 UTC (permalink / raw)
  To: kugan; +Cc: Jan Hubicka, gcc-patches

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Handle unary pass-through jump functions for ipa-vrp
  2016-11-08 15:17         ` Jan Hubicka
@ 2016-11-13  8:20           ` kugan
  2016-11-13 11:50             ` Jan Hubicka
  0 siblings, 1 reply; 19+ messages in thread
From: kugan @ 2016-11-13  8:20 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1423 bytes --]

Hi Honza,

I reverted this patch after it was reported that it resulted in 
bootstrap compare failure in some targets.

I reproduced it and tracked to a mistake in the patch that introduced it.

That is, in propagate_vr_accross_jump_function, I had:

	  if (src_lats->m_value_range.bottom_p ())
	    return false;

which should have been:

	  if (src_lats->m_value_range.bottom_p ())
	    return dest_lat->set_to_bottom ();


I also fixed update_jump_functions_after_inlining as reported in pr78268.

I now bootstrapped the patch (lto and normal) on two affected targets 
aarch64-none-linux-gnu and powerpc64le-unknown-linux-gnu. I also tested 
it on x86_64-linux-gnu with no new regressions. Is this OK?


Thanks,
Kugan


gcc/testsuite/ChangeLog:

2016-11-13  Kugan Vivekanandarajah  <kuganv@linaro.org>

	* g++.dg/torture/pr78268.C: New test.


gcc/ChangeLog:

2016-11-13  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.
	* 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.
	(update_jump_functions_after_inlining): Likewise.
	(ipa_write_jump_function): Likewise.
	(ipa_read_jump_function): Likewise.


[-- Attachment #2: p.txt --]
[-- Type: text/plain, Size: 9288 bytes --]

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 79e621a..2ec671f 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1219,13 +1219,19 @@ 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;
 
@@ -1857,13 +1863,32 @@ propagate_vr_accross_jump_function (cgraph_edge *cs,
   if (jfunc->type == IPA_JF_PASS_THROUGH)
     {
       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
-      if (dest_lat->bottom_p ())
-	return false;
       int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
       src_lats = ipa_get_parm_lattices (caller_info, src_idx);
 
       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 dest_lat->set_to_bottom ();
+
+	  extract_range_from_unary_expr (&vr,
+					 operation,
+					 param_type,
+					 &src_lats->m_value_range.m_vr,
+					 operand_type);
+	  if (vr.type == VR_RANGE
+	      || vr.type == VR_ANTI_RANGE)
+	    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..6321fdd 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,11 @@ 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;
     }
 
@@ -2518,6 +2571,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	      dst->value.ancestor.agg_preserved &=
 		src->value.pass_through.agg_preserved;
 	    }
+	  else if (src->type == IPA_JF_PASS_THROUGH
+		   && TREE_CODE_CLASS (src->value.pass_through.operation) == tcc_unary)
+	    {
+	      dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
+	      dst->value.ancestor.agg_preserved = false;
+	    }
 	  else if (src->type == IPA_JF_ANCESTOR)
 	    {
 	      dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
@@ -2583,6 +2642,8 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 			  && ipa_get_jf_pass_through_agg_preserved (src);
 			ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
 		      }
+		    else if (TREE_CODE_CLASS (operation) == tcc_unary)
+		      ipa_set_jf_unary_pass_through (dst, formal_id, operation);
 		    else
 		      {
 			tree operand = ipa_get_jf_pass_through_operand (src);
@@ -4666,6 +4727,9 @@ 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 +4809,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/g++.dg/torture/pr78268.C b/gcc/testsuite/g++.dg/torture/pr78268.C
index e69de29..ef4547c 100644
--- a/gcc/testsuite/g++.dg/torture/pr78268.C
+++ b/gcc/testsuite/g++.dg/torture/pr78268.C
@@ -0,0 +1,25 @@
+// { dg-do compile }
+typedef enum {} nsresult;
+
+struct A {
+      virtual nsresult m_fn1(bool);
+};
+
+struct B {
+      A *operator[](int);
+};
+
+struct C {
+      nsresult m_fn2(bool);
+        bool m_fn3(bool);
+	  B mDataSources;
+};
+nsresult C::m_fn2(bool p1)
+{
+  m_fn3(!p1);
+}
+
+bool C::m_fn3(bool p1)
+{
+  mDataSources[0]->m_fn1(p1);
+}

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Handle unary pass-through jump functions for ipa-vrp
  2016-11-13  8:20           ` kugan
@ 2016-11-13 11:50             ` Jan Hubicka
  0 siblings, 0 replies; 19+ messages in thread
From: Jan Hubicka @ 2016-11-13 11:50 UTC (permalink / raw)
  To: kugan; +Cc: Jan Hubicka, gcc-patches

> Hi Honza,
> 
> I reverted this patch after it was reported that it resulted in
> bootstrap compare failure in some targets.
> 
> I reproduced it and tracked to a mistake in the patch that introduced it.
> 
> That is, in propagate_vr_accross_jump_function, I had:
> 
> 	  if (src_lats->m_value_range.bottom_p ())
> 	    return false;
> 
> which should have been:
> 
> 	  if (src_lats->m_value_range.bottom_p ())
> 	    return dest_lat->set_to_bottom ();

Oops, sorry for missing that :)
> 
> 
> I also fixed update_jump_functions_after_inlining as reported in pr78268.
> 
> I now bootstrapped the patch (lto and normal) on two affected
> targets aarch64-none-linux-gnu and powerpc64le-unknown-linux-gnu. I
> also tested it on x86_64-linux-gnu with no new regressions. Is this
> OK?

Yes, thanks for fixing the issue!

Can you, please, also send patch to https://gcc.gnu.org/gcc-7/changes.html
which mention the new features and command line options?

Honza

> 
> 
> Thanks,
> Kugan
> 
> 
> gcc/testsuite/ChangeLog:
> 
> 2016-11-13  Kugan Vivekanandarajah  <kuganv@linaro.org>
> 
> 	* g++.dg/torture/pr78268.C: New test.
> 
> 
> gcc/ChangeLog:
> 
> 2016-11-13  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.
> 	* 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.
> 	(update_jump_functions_after_inlining): Likewise.
> 	(ipa_write_jump_function): Likewise.
> 	(ipa_read_jump_function): Likewise.
> 

> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> index 79e621a..2ec671f 100644
> --- a/gcc/ipa-cp.c
> +++ b/gcc/ipa-cp.c
> @@ -1219,13 +1219,19 @@ 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;
>  
> @@ -1857,13 +1863,32 @@ propagate_vr_accross_jump_function (cgraph_edge *cs,
>    if (jfunc->type == IPA_JF_PASS_THROUGH)
>      {
>        struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
> -      if (dest_lat->bottom_p ())
> -	return false;
>        int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
>        src_lats = ipa_get_parm_lattices (caller_info, src_idx);
>  
>        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 dest_lat->set_to_bottom ();
> +
> +	  extract_range_from_unary_expr (&vr,
> +					 operation,
> +					 param_type,
> +					 &src_lats->m_value_range.m_vr,
> +					 operand_type);
> +	  if (vr.type == VR_RANGE
> +	      || vr.type == VR_ANTI_RANGE)
> +	    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..6321fdd 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,11 @@ 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;
>      }
>  
> @@ -2518,6 +2571,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>  	      dst->value.ancestor.agg_preserved &=
>  		src->value.pass_through.agg_preserved;
>  	    }
> +	  else if (src->type == IPA_JF_PASS_THROUGH
> +		   && TREE_CODE_CLASS (src->value.pass_through.operation) == tcc_unary)
> +	    {
> +	      dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
> +	      dst->value.ancestor.agg_preserved = false;
> +	    }
>  	  else if (src->type == IPA_JF_ANCESTOR)
>  	    {
>  	      dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
> @@ -2583,6 +2642,8 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>  			  && ipa_get_jf_pass_through_agg_preserved (src);
>  			ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
>  		      }
> +		    else if (TREE_CODE_CLASS (operation) == tcc_unary)
> +		      ipa_set_jf_unary_pass_through (dst, formal_id, operation);
>  		    else
>  		      {
>  			tree operand = ipa_get_jf_pass_through_operand (src);
> @@ -4666,6 +4727,9 @@ 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 +4809,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/g++.dg/torture/pr78268.C b/gcc/testsuite/g++.dg/torture/pr78268.C
> index e69de29..ef4547c 100644
> --- a/gcc/testsuite/g++.dg/torture/pr78268.C
> +++ b/gcc/testsuite/g++.dg/torture/pr78268.C
> @@ -0,0 +1,25 @@
> +// { dg-do compile }
> +typedef enum {} nsresult;
> +
> +struct A {
> +      virtual nsresult m_fn1(bool);
> +};
> +
> +struct B {
> +      A *operator[](int);
> +};
> +
> +struct C {
> +      nsresult m_fn2(bool);
> +        bool m_fn3(bool);
> +	  B mDataSources;
> +};
> +nsresult C::m_fn2(bool p1)
> +{
> +  m_fn3(!p1);
> +}
> +
> +bool C::m_fn3(bool p1)
> +{
> +  mDataSources[0]->m_fn1(p1);
> +}

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2016-11-13 11:50 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-24 23:18 [RFC] Handle unary pass-through jump functions for ipa-vrp kugan
2016-10-27 12:11 ` Martin Jambor
2016-10-28  2:58   ` [ipa-vrp] ice in set_value_range kugan
2016-11-03 16:25     ` Martin Jambor
2016-11-08 10:11       ` kugan
2016-11-08 15:17         ` Jan Hubicka
2016-11-09  6:02         ` Andrew Pinski
2016-11-09  8:02           ` kugan
2016-11-10  6:14             ` Andrew Pinski
2016-11-10  6:18               ` kugan
2016-11-10  8:12           ` Andreas Schwab
2016-10-27 14:59 ` [RFC] Handle unary pass-through jump functions for ipa-vrp Jan Hubicka
2016-10-28  3:04   ` kugan
2016-11-03 17:36     ` Martin Jambor
2016-11-08 10:13       ` kugan
2016-11-08 15:17         ` Jan Hubicka
2016-11-13  8:20           ` kugan
2016-11-13 11:50             ` Jan Hubicka
2016-11-11 15:46         ` Bin.Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).