Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-11 Thread Martin Liška
On 9/11/19 2:23 PM, Richard Biener wrote:
> On Wed, 11 Sep 2019, Martin Liška wrote:
> 
>> Hello.
>>
>> One another updated version of the patch.
>> Changes from the previous version:
>> - I fixed:
>>   gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 
>> 2));
>>   into gimple_size (GIMPLE_ASSIGN, 3)
>> - I simplified condition in gimple_simplified_result_is_gimple_val
>> - optimize_vec_cond_expr is using build_same_sized_truth_vector_type
> 
> Can you here instead amend ovce_extract_ops to return the type of
> 'cond' which should be the type you want?

Sure, updated in the tested attached patch.

I'm going to install the patch after the Cauldron.

Martin

> 
> Otherwise OK.
> 
> Richard.
> 
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
>> Thanks,
>> Martin

>From 8ad0d2e59350b9410543571059c0d24bcda52db3 Mon Sep 17 00:00:00 2001
From: Li Jia He 
Date: Mon, 15 Jul 2019 00:30:25 -0500
Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd

gcc/ChangeLog

2019-07-16  Li Jia He  
	Martin Liska  

	* gimple-fold.c (and_comparisons_1): Add type as first
	argument.
	(and_var_with_comparison): Likewise.
	(and_var_with_comparison_1): Likewise.
	(or_comparisons_1): Likewise.
	(or_var_with_comparison): Likewise.
	(or_var_with_comparison_1): Likewise.
	(maybe_fold_and_comparisons): Call maybe_fold_comparisons_from_match_pd.
	(maybe_fold_or_comparisons): Likewise.
	(maybe_fold_comparisons_from_match_pd): New.
	* gimple-fold.h (maybe_fold_and_comparisons): Add type argument.
	(maybe_fold_or_comparisons): Likewise.
	* gimple.c (gimple_size): Make it public and add num_ops argument.
	(gimple_init): New function.
	(gimple_alloc): Call gimple_init.
	* gimple.h (gimple_size): New.
	(gimple_init): Likewise.
	* tree-if-conv.c (fold_or_predicates): Pass type.
	* tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise.
	* tree-ssa-reassoc.c (eliminate_redundant_comparison): Likewise.
	(optimize_vec_cond_expr): Likewise.
	(ovce_extract_ops): Return type of conditional expression.
	* tree-ssanames.c (init_ssa_name_imm_use): New.
	(make_ssa_name_fn): Use init_ssa_name_imm_use.
	* tree-ssanames.h (init_ssa_name_imm_use): New.
---
 gcc/gimple-fold.c| 170 +--
 gcc/gimple-fold.h|   4 +-
 gcc/gimple.c |  37 +
 gcc/gimple.h |   2 +
 gcc/tree-if-conv.c   |   2 +-
 gcc/tree-ssa-ifcombine.c |   2 +-
 gcc/tree-ssa-reassoc.c   |  25 --
 gcc/tree-ssanames.c  |  21 +++--
 gcc/tree-ssanames.h  |   1 +
 9 files changed, 189 insertions(+), 75 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index fcffb9802b7..6d9ba367839 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -5371,22 +5371,22 @@ same_bool_result_p (const_tree op1, const_tree op2)
 /* Forward declarations for some mutually recursive functions.  */
 
 static tree
-and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
+and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
 		   enum tree_code code2, tree op2a, tree op2b);
 static tree
-and_var_with_comparison (tree var, bool invert,
+and_var_with_comparison (tree type, tree var, bool invert,
 			 enum tree_code code2, tree op2a, tree op2b);
 static tree
-and_var_with_comparison_1 (gimple *stmt,
+and_var_with_comparison_1 (tree type, gimple *stmt,
 			   enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
+or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b,
 		  enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_var_with_comparison (tree var, bool invert,
+or_var_with_comparison (tree, tree var, bool invert,
 			enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_var_with_comparison_1 (gimple *stmt,
+or_var_with_comparison_1 (tree, gimple *stmt,
 			  enum tree_code code2, tree op2a, tree op2b);
 
 /* Helper function for and_comparisons_1:  try to simplify the AND of the
@@ -5395,7 +5395,7 @@ or_var_with_comparison_1 (gimple *stmt,
Return NULL_EXPR if we can't simplify this to a single expression.  */
 
 static tree
-and_var_with_comparison (tree var, bool invert,
+and_var_with_comparison (tree type, tree var, bool invert,
 			 enum tree_code code2, tree op2a, tree op2b)
 {
   tree t;
@@ -5409,11 +5409,11 @@ and_var_with_comparison (tree var, bool invert,
  !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b))
  Then we only have to consider the simpler non-inverted cases.  */
   if (invert)
-t = or_var_with_comparison_1 (stmt, 
+t = or_var_with_comparison_1 (type, stmt,
   invert_tree_comparison (code2, false),
   op2a, op2b);
   else
-t = and_var_with_comparison_1 (stmt, code2, op2a, op2b);
+t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b);
   return canonicalize_bool (t, invert);
 }
 
@@ -5422,7 +5422,7 @@ and_var_with_comparis

Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-11 Thread Richard Biener
On Wed, 11 Sep 2019, Martin Liška wrote:

> Hello.
> 
> One another updated version of the patch.
> Changes from the previous version:
> - I fixed:
>   gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 
> 2));
>   into gimple_size (GIMPLE_ASSIGN, 3)
> - I simplified condition in gimple_simplified_result_is_gimple_val
> - optimize_vec_cond_expr is using build_same_sized_truth_vector_type

Can you here instead amend ovce_extract_ops to return the type of
'cond' which should be the type you want?

Otherwise OK.

Richard.

> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> Ready to be installed?
> Thanks,
> Martin

Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-11 Thread Martin Liška
Hello.

One another updated version of the patch.
Changes from the previous version:
- I fixed:
  gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 2));
  into gimple_size (GIMPLE_ASSIGN, 3)
- I simplified condition in gimple_simplified_result_is_gimple_val
- optimize_vec_cond_expr is using build_same_sized_truth_vector_type

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin
>From ee44ff1742928e3200ce6a0677e8c8a3dbe4e6d2 Mon Sep 17 00:00:00 2001
From: Li Jia He 
Date: Mon, 15 Jul 2019 00:30:25 -0500
Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd

gcc/ChangeLog

2019-07-16  Li Jia He  
	Martin Liska  

	* gimple-fold.c (and_comparisons_1): Add type as first
	argument.
	(and_var_with_comparison): Likewise.
	(and_var_with_comparison_1): Likewise.
	(or_comparisons_1): Likewise.
	(or_var_with_comparison): Likewise.
	(or_var_with_comparison_1): Likewise.
	(maybe_fold_and_comparisons): Call maybe_fold_comparisons_from_match_pd.
	(maybe_fold_or_comparisons): Likewise.
	(maybe_fold_comparisons_from_match_pd): New.
	* gimple-fold.h (maybe_fold_and_comparisons): Add type argument.
	(maybe_fold_or_comparisons): Likewise.
	* gimple.c (gimple_size): Make it public and add num_ops argument.
	(gimple_init): New function.
	(gimple_alloc): Call gimple_init.
	* gimple.h (gimple_size): New.
	(gimple_init): Likewise.
	* tree-if-conv.c (fold_or_predicates): Pass type.
	* tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise.
	* tree-ssa-reassoc.c (eliminate_redundant_comparison): Likewise.
	(optimize_vec_cond_expr): Likewise.
	* tree-ssanames.c (init_ssa_name_imm_use): New.
	(make_ssa_name_fn): Use init_ssa_name_imm_use.
	* tree-ssanames.h (init_ssa_name_imm_use): New.
---
 gcc/gimple-fold.c| 170 +--
 gcc/gimple-fold.h|   4 +-
 gcc/gimple.c |  37 +
 gcc/gimple.h |   2 +
 gcc/tree-if-conv.c   |   2 +-
 gcc/tree-ssa-ifcombine.c |   2 +-
 gcc/tree-ssa-reassoc.c   |  15 +++-
 gcc/tree-ssanames.c  |  21 +++--
 gcc/tree-ssanames.h  |   1 +
 9 files changed, 183 insertions(+), 71 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index fcffb9802b7..aa2f94ace28 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -5371,22 +5371,22 @@ same_bool_result_p (const_tree op1, const_tree op2)
 /* Forward declarations for some mutually recursive functions.  */
 
 static tree
-and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
+and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
 		   enum tree_code code2, tree op2a, tree op2b);
 static tree
-and_var_with_comparison (tree var, bool invert,
+and_var_with_comparison (tree type, tree var, bool invert,
 			 enum tree_code code2, tree op2a, tree op2b);
 static tree
-and_var_with_comparison_1 (gimple *stmt,
+and_var_with_comparison_1 (tree type, gimple *stmt,
 			   enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
+or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b,
 		  enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_var_with_comparison (tree var, bool invert,
+or_var_with_comparison (tree, tree var, bool invert,
 			enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_var_with_comparison_1 (gimple *stmt,
+or_var_with_comparison_1 (tree, gimple *stmt,
 			  enum tree_code code2, tree op2a, tree op2b);
 
 /* Helper function for and_comparisons_1:  try to simplify the AND of the
@@ -5395,7 +5395,7 @@ or_var_with_comparison_1 (gimple *stmt,
Return NULL_EXPR if we can't simplify this to a single expression.  */
 
 static tree
-and_var_with_comparison (tree var, bool invert,
+and_var_with_comparison (tree type, tree var, bool invert,
 			 enum tree_code code2, tree op2a, tree op2b)
 {
   tree t;
@@ -5409,11 +5409,11 @@ and_var_with_comparison (tree var, bool invert,
  !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b))
  Then we only have to consider the simpler non-inverted cases.  */
   if (invert)
-t = or_var_with_comparison_1 (stmt, 
+t = or_var_with_comparison_1 (type, stmt,
   invert_tree_comparison (code2, false),
   op2a, op2b);
   else
-t = and_var_with_comparison_1 (stmt, code2, op2a, op2b);
+t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b);
   return canonicalize_bool (t, invert);
 }
 
@@ -5422,7 +5422,7 @@ and_var_with_comparison (tree var, bool invert,
Return NULL_EXPR if we can't simplify this to a single expression.  */
 
 static tree
-and_var_with_comparison_1 (gimple *stmt,
+and_var_with_comparison_1 (tree type, gimple *stmt,
 			   enum tree_code code2, tree op2a, tree op2b)
 {
   tree var = gimple_assign_lhs (stmt);
@@ -5453,7 +5453,7 @@ and_var_with_comparison_1 (gimple *stmt,
   /* If the definition is a comparison, recurse on it.  */
   if (TREE_CODE_CLASS

Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-11 Thread Martin Liška
On 9/11/19 10:22 AM, Li Jia He wrote:
> Hi,
> 
> On 2019/9/10 3:40 PM, Martin Liška wrote:
>> On 9/9/19 3:55 PM, Richard Biener wrote:
>>> On Mon, 9 Sep 2019, Martin Liška wrote:
>>>
 On 9/9/19 3:42 PM, Richard Biener wrote:
> There is no newly created GIMPLE?

 Hm, I thought from the beginning that maybe_fold_comparisons_from_match_pd
 can come up with new temporary expressions that need to be inserted into
 GIMPLE stream? But that's probably handled in ifcombine with:

   t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, 
 true,
   GSI_SAME_STMT);
 ?
>>>
>>> No, that case is done when forcing short-circuiting when there was no
>>> simplification.  When there was a simplification we do
>>>
>>>    if (result_inv)
>>>  t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
>>>    t = canonicalize_cond_expr_cond (t);
>>>    if (!t)
>>>  return false;
>>>
>>> so when it is not a condition suitable for direct replacement into
>>>
>>>    gimple_cond_set_condition_from_tree (inner_cond, t);
>>>
>>> we fail.
>>>
>>> Richard.
>>>
>>
>> I see, so I'm sending updated tested patch.
> 

Hello.

Next time, please Reply to all ;)

> Thanks for working on this.
> I tested the patch.  But I found that this patch will cause gcc not to 
> bootstrap.  I found the following statement may be a question.
> '
> gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 2));
> '
> we may need to change it to the following
> '
> gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
> '
> And we may also replace gimple with gassign.

Good point, I'll include the changes to my patchset.

> 
> And we may also need to make some changes to the statements in
> if(op.resimplify (NULL, follow_all_ssa_edges)).  Please take a look at the 
> attachment:

@@ -5888,23 +5890,22 @@

 maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code,

   if (gimple_simplified_result_is_gimple_val (&op)) 
{ 
  tree res = op.ops[0]; 
- switch (TREE_CODE (res)) 
-   { 
-   case SSA_NAME: 
-   { 
- if (res == lhs1) 
-   return build2 (code1, type, op1a, op1b); 
- else if (res == lhs2) 
-   return build2 (code2, type, op2a, op2b); 
- else 
-   return res; 
-   } 
-   case INTEGER_CST: 
- /* Fold expression to boolean_true_node or boolean_false_node.  
*/ 
- return res; 
-   default: 
- return NULL_TREE; 
-   } 
+ if (res == lhs1) 
+   return build2 (code1, type, op1a, op1b); 
+ else if (res == lhs2) 
+   return build2 (code2, type, op2a, op2b); 
+ else 
+   return res; 

I'll include this.

+   } 
+ 
+  if (op.code.is_tree_code () 
+ && TREE_CODE_CLASS ((enum tree_code) op.code) == tcc_comparison) 
+   { 
+ tree op0 = op.ops[0]; 
+ tree op1 = op.ops[1]; 
+ if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2) 
+   return NULL_TREE; /* not simple */ 
+ return build2 ((enum tree_code) op.code, op.type, op0, op1); 
} 
 } 

This is added in patch 3/5.

Martin

> 
> Thanks,
> Lijia He
> 
>>
>> Martin



Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-10 Thread Martin Liška

On 9/9/19 3:55 PM, Richard Biener wrote:

On Mon, 9 Sep 2019, Martin Liška wrote:


On 9/9/19 3:42 PM, Richard Biener wrote:

There is no newly created GIMPLE?


Hm, I thought from the beginning that maybe_fold_comparisons_from_match_pd
can come up with new temporary expressions that need to be inserted into
GIMPLE stream? But that's probably handled in ifcombine with:

  t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, 
true,
  GSI_SAME_STMT);
?


No, that case is done when forcing short-circuiting when there was no
simplification.  When there was a simplification we do

   if (result_inv)
 t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
   t = canonicalize_cond_expr_cond (t);
   if (!t)
 return false;

so when it is not a condition suitable for direct replacement into

   gimple_cond_set_condition_from_tree (inner_cond, t);

we fail.

Richard.



I see, so I'm sending updated tested patch.

Martin
>From f757482a57754e5c7590e0f2cadf3cc4443beab6 Mon Sep 17 00:00:00 2001
From: Li Jia He 
Date: Mon, 15 Jul 2019 00:30:25 -0500
Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd

gcc/ChangeLog

2019-07-16  Li Jia He  
	Martin Liska  

	* gimple-fold.c (and_comparisons_1): Add type as first
	argument.
	(and_var_with_comparison): Likewise.
	(and_var_with_comparison_1): Likewise.
	(or_comparisons_1): Likewise.
	(or_var_with_comparison): Likewise.
	(or_var_with_comparison_1): Likewise.
	(maybe_fold_and_comparisons): Call maybe_fold_comparisons_from_match_pd.
	(maybe_fold_or_comparisons): Likewise.
	(maybe_fold_comparisons_from_match_pd): New.
	* gimple-fold.h (maybe_fold_and_comparisons): Add type argument.
	(maybe_fold_or_comparisons): Likewise.
	* gimple.c (gimple_size): Make it public and add num_ops argument.
	(gimple_init): New function.
	(gimple_alloc): Call gimple_init.
	* gimple.h (gimple_size): New.
	(gimple_init): Likewise.
	* tree-if-conv.c (fold_or_predicates): Pass type.
	* tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise.
	* tree-ssa-reassoc.c (eliminate_redundant_comparison): Likewise.
	(optimize_vec_cond_expr): Likewise.
	* tree-ssanames.c (init_ssa_name_imm_use): New.
	(make_ssa_name_fn): Use init_ssa_name_imm_use.
	* tree-ssanames.h (init_ssa_name_imm_use): New.
---
 gcc/gimple-fold.c| 179 ++-
 gcc/gimple-fold.h|   4 +-
 gcc/gimple.c |  37 
 gcc/gimple.h |   2 +
 gcc/tree-if-conv.c   |   2 +-
 gcc/tree-ssa-ifcombine.c |   2 +-
 gcc/tree-ssa-reassoc.c   |  14 ++-
 gcc/tree-ssanames.c  |  21 +++--
 gcc/tree-ssanames.h  |   1 +
 9 files changed, 191 insertions(+), 71 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index fcffb9802b7..fcdcb087ec4 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -5371,22 +5371,22 @@ same_bool_result_p (const_tree op1, const_tree op2)
 /* Forward declarations for some mutually recursive functions.  */
 
 static tree
-and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
+and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
 		   enum tree_code code2, tree op2a, tree op2b);
 static tree
-and_var_with_comparison (tree var, bool invert,
+and_var_with_comparison (tree type, tree var, bool invert,
 			 enum tree_code code2, tree op2a, tree op2b);
 static tree
-and_var_with_comparison_1 (gimple *stmt,
+and_var_with_comparison_1 (tree type, gimple *stmt,
 			   enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
+or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b,
 		  enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_var_with_comparison (tree var, bool invert,
+or_var_with_comparison (tree, tree var, bool invert,
 			enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_var_with_comparison_1 (gimple *stmt,
+or_var_with_comparison_1 (tree, gimple *stmt,
 			  enum tree_code code2, tree op2a, tree op2b);
 
 /* Helper function for and_comparisons_1:  try to simplify the AND of the
@@ -5395,7 +5395,7 @@ or_var_with_comparison_1 (gimple *stmt,
Return NULL_EXPR if we can't simplify this to a single expression.  */
 
 static tree
-and_var_with_comparison (tree var, bool invert,
+and_var_with_comparison (tree type, tree var, bool invert,
 			 enum tree_code code2, tree op2a, tree op2b)
 {
   tree t;
@@ -5409,11 +5409,11 @@ and_var_with_comparison (tree var, bool invert,
  !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b))
  Then we only have to consider the simpler non-inverted cases.  */
   if (invert)
-t = or_var_with_comparison_1 (stmt, 
+t = or_var_with_comparison_1 (type, stmt,
   invert_tree_comparison (code2, false),
   op2a, op2b);
   else
-t = and_var_with_comparison_1 (stmt, code2, op2a, op2b);
+t = and_var_with_comparison_1 (type, stmt, code2, 

Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-09 Thread Richard Biener
On Mon, 9 Sep 2019, Martin Liška wrote:

> On 9/9/19 3:42 PM, Richard Biener wrote:
> > There is no newly created GIMPLE?
> 
> Hm, I thought from the beginning that maybe_fold_comparisons_from_match_pd
> can come up with new temporary expressions that need to be inserted into
> GIMPLE stream? But that's probably handled in ifcombine with:
> 
> t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, 
> true,
> GSI_SAME_STMT);
> ?

No, that case is done when forcing short-circuiting when there was no
simplification.  When there was a simplification we do

  if (result_inv)
t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
  t = canonicalize_cond_expr_cond (t);
  if (!t)
return false;

so when it is not a condition suitable for direct replacement into

  gimple_cond_set_condition_from_tree (inner_cond, t);

we fail.

Richard.

Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-09 Thread Martin Liška
On 9/9/19 3:42 PM, Richard Biener wrote:
> There is no newly created GIMPLE?

Hm, I thought from the beginning that maybe_fold_comparisons_from_match_pd
can come up with new temporary expressions that need to be inserted into
GIMPLE stream? But that's probably handled in ifcombine with:


  t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, 
true,
  GSI_SAME_STMT);
?

Martin


Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-09 Thread Richard Biener
On Mon, 9 Sep 2019, Martin Liška wrote:

> On 9/9/19 3:10 PM, Richard Biener wrote:
> > On Mon, 9 Sep 2019, Martin Liška wrote:
> > 
> >> Hi.
> >>
> >> I'm sending slightly updated version of the patch where we
> >> need to properly select type in maybe_fold_comparisons_from_match_pd
> >> function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE
> >> and so that we can't return a boolean_type_node.
> >>
> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>
> >> Ready to be installed?
> > 
> > 2019-07-16  Li Jia He  
> > Martin Liska  
> > 
> > * gimple.h (gimple_init): Declare.
> > (gimple_size): Likewise.
> > * gimple.c (gimple_init): Remove static and inline restrictions.
> > (gimple_alloc): Only allocate memory and call gimple_init.
> > (gimple_size): Likewise.
> > 
> > Likewise?
> 
> Fixed.
> 
> > 
> > * tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn.
> > (make_ssa_name_fn): New.
> > 
> > You didn't touch make_ssa_name_fn.
> 
> Likewise here.
> 
> > 
> > Since we're needing another iteration:
> > 
> > +  /* Allocate gimple stmt1 on the stack.  */
> > +  gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size 
> > (GIMPLE_ASSIGN, 2));
> > 
> > You can use gassign *stmt1 here so all the gimple_assign_ fns below
> > get cheaper.
> > 
> > +  if (op.resimplify (NULL, follow_all_ssa_edges))
> > +{
> > +  if (gimple_simplified_result_is_gimple_val (&op))
> > +   {
> > + tree res = op.ops[0];
> > + switch (TREE_CODE (res))
> > +   {
> > +   case SSA_NAME:
> > +   {
> > + gimple *def = SSA_NAME_DEF_STMT (res);
> > 
> > you shouldn't expand SSA names here unless that SSA name is
> > exactly lhs1 or lhs2 from above.  So
> 
> Ah, got it.
> 
> > 
> >  if (res == lhs1)
> >return build2 (...);
> >  else if (res == lhs2)
> >return build2 (..);
> >  else
> >return res;
> > 
> > plus you miss the case where 'op' became a simplified comparison
> > in itself.  So,
> 
> Yes, that part is included in part 3. I'm going to send the updated patch
> 3 as well soon.
> 
> > 
> >  if (op.code.is_tree_code ()
> >  && TREE_CODE_CLASS ((enum tree_code)op.code) == tcc_comparison)
> >{
> >   tree op0 = op.ops[0];
> >   tree op1 = op.ops[1];
> >   if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2)
> > return NULL_TREE;  /* not simple */
> >   return build2 ((enum tree_code)op.code, op.type,
> >  op0, op1);
> >}
> > 
> > note you need not fold_ again.  It's of course ugly that we
> > need to build a GENERIC tree here but that's the current interface
> > and thus OK at the moment.
> 
> I see. But what I need is to insert newly created GIMPLE assignment to
> the provided gimple sequence (gsi), right?

There is no newly created GIMPLE?

Richard.

Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-09 Thread Martin Liška
On 9/9/19 3:10 PM, Richard Biener wrote:
> On Mon, 9 Sep 2019, Martin Liška wrote:
> 
>> Hi.
>>
>> I'm sending slightly updated version of the patch where we
>> need to properly select type in maybe_fold_comparisons_from_match_pd
>> function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE
>> and so that we can't return a boolean_type_node.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
> 
> 2019-07-16  Li Jia He  
> Martin Liska  
> 
> * gimple.h (gimple_init): Declare.
> (gimple_size): Likewise.
> * gimple.c (gimple_init): Remove static and inline restrictions.
> (gimple_alloc): Only allocate memory and call gimple_init.
> (gimple_size): Likewise.
> 
> Likewise?

Fixed.

> 
> * tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn.
> (make_ssa_name_fn): New.
> 
> You didn't touch make_ssa_name_fn.

Likewise here.

> 
> Since we're needing another iteration:
> 
> +  /* Allocate gimple stmt1 on the stack.  */
> +  gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size 
> (GIMPLE_ASSIGN, 2));
> 
> You can use gassign *stmt1 here so all the gimple_assign_ fns below
> get cheaper.
> 
> +  if (op.resimplify (NULL, follow_all_ssa_edges))
> +{
> +  if (gimple_simplified_result_is_gimple_val (&op))
> +   {
> + tree res = op.ops[0];
> + switch (TREE_CODE (res))
> +   {
> +   case SSA_NAME:
> +   {
> + gimple *def = SSA_NAME_DEF_STMT (res);
> 
> you shouldn't expand SSA names here unless that SSA name is
> exactly lhs1 or lhs2 from above.  So

Ah, got it.

> 
>  if (res == lhs1)
>return build2 (...);
>  else if (res == lhs2)
>return build2 (..);
>  else
>return res;
> 
> plus you miss the case where 'op' became a simplified comparison
> in itself.  So,

Yes, that part is included in part 3. I'm going to send the updated patch
3 as well soon.

> 
>  if (op.code.is_tree_code ()
>  && TREE_CODE_CLASS ((enum tree_code)op.code) == tcc_comparison)
>{
>   tree op0 = op.ops[0];
>   tree op1 = op.ops[1];
>   if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2)
> return NULL_TREE;  /* not simple */
>   return build2 ((enum tree_code)op.code, op.type,
>  op0, op1);
>}
> 
> note you need not fold_ again.  It's of course ugly that we
> need to build a GENERIC tree here but that's the current interface
> and thus OK at the moment.

I see. But what I need is to insert newly created GIMPLE assignment to
the provided gimple sequence (gsi), right?

Thanks,
Martin

> 
> Thanks,
> Richard.
> 

>From a0b4daec604ee92ac8e76e416cd912d7d176a811 Mon Sep 17 00:00:00 2001
From: Li Jia He 
Date: Mon, 15 Jul 2019 00:30:25 -0500
Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd

gcc/ChangeLog

2019-07-16  Li Jia He  
	Martin Liska  

	* gimple.h (gimple_init): Declare.
	(gimple_size): Likewise.
	* gimple.c (gimple_init): Remove static and inline restrictions.
	(gimple_alloc): Only allocate memory and call gimple_init.
	(gimple_size): Make it external and add new num_ops argument.
	* gimple-fold.c (maybe_fold_comparisons_from_match_pd): New function.
	(maybe_fold_and_comparisons): Modify and_comparisons_1 invocation and
	call maybe_fold_comparisons_from_match_pd.
	(maybe_fold_or_comparisons): Modify or_comparisons_1 invocation and
	call maybe_fold_comparisons_from_match_pd.
	* tree-ssanames.c (init_ssa_name_imm_use): New.
	(make_ssa_name_fn): Use make_ssa_name_fn.
	* tree-ssanames.h (init_ssa_name_imm_use): New.
---
 gcc/gimple-fold.c   | 108 
 gcc/gimple.c|  37 +--
 gcc/gimple.h|   2 +
 gcc/tree-ssanames.c |  21 ++---
 gcc/tree-ssanames.h |   1 +
 5 files changed, 138 insertions(+), 31 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index fcffb9802b7..50cb3bf7e32 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -5834,6 +5834,85 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
   return NULL_TREE;
 }
 
+/* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons
+   : try to simplify the AND/OR of the ssa variable VAR with the comparison
+   specified by (OP2A CODE2 OP2B) from match.pd.  Return NULL_EXPR if we can't
+   simplify this to a single expression.  As we are going to lower the cost
+   of building SSA names / gimple stmts significantly, we need to allocate
+   them ont the stack.  This will cause the code to be a bit ugly.  */
+
+static tree
+maybe_fold_comparisons_from_match_pd (enum tree_code code, enum tree_code code1,
+  tree op1a, tree op1b,
+  enum tree_code code2, tree op2a,
+  tree op2b)
+{
+  tree type = TREE_TYPE (op1a);
+  if (TREE_CODE (type) != VECTOR_

Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-09 Thread Richard Biener
On Mon, 9 Sep 2019, Martin Liška wrote:

> On 9/9/19 3:10 PM, Marc Glisse wrote:
> > On Mon, 9 Sep 2019, Martin Liška wrote:
> > 
> >> I'm sending slightly updated version of the patch where we
> >> need to properly select type in maybe_fold_comparisons_from_match_pd
> >> function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE
> >> and so that we can't return a boolean_type_node.
> > 
> > +  tree type = TREE_TYPE (op1a);
> > +  if (TREE_CODE (type) != VECTOR_TYPE)
> > +    type = boolean_type_node;
> > 
> > Don't you need build_same_sized_truth_vector_type or something, for 
> > instance with AVX512?
> > 
> > Also, IIRC EQ_EXPR for vectors can return either a vector or a boolean. I 
> > don't know if we can end up here with both versions, but if we can, 
> > guessing the type could be dangerous. Would it be hard to add a type 
> > argument to those functions and delegate this to the caller? Any better 
> > idea (maybe this is already safe and I am just missing it)?
> 
> Richi can you help us here? I'm not sure what guarantees do we have here in 
> GIMPLE?

Oops, I missed this hunk - the caller needs to pass this down, but at 
least from the ifcombine use we are always coming from a if (a CMP b)
context and thus a boolean_type_node result type.  For the reassoc
case there's indeed nothing preventing from vector typed comparisons
sneaking in here, likewise recursion via or_var_with_comparison_1
might run into vectors.

Thus the toplevel interface has to pass down the (common) type of
the two comparisons.

Richard.

Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-09 Thread Martin Liška
On 9/9/19 3:10 PM, Marc Glisse wrote:
> On Mon, 9 Sep 2019, Martin Liška wrote:
> 
>> I'm sending slightly updated version of the patch where we
>> need to properly select type in maybe_fold_comparisons_from_match_pd
>> function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE
>> and so that we can't return a boolean_type_node.
> 
> +  tree type = TREE_TYPE (op1a);
> +  if (TREE_CODE (type) != VECTOR_TYPE)
> +    type = boolean_type_node;
> 
> Don't you need build_same_sized_truth_vector_type or something, for instance 
> with AVX512?
> 
> Also, IIRC EQ_EXPR for vectors can return either a vector or a boolean. I 
> don't know if we can end up here with both versions, but if we can, guessing 
> the type could be dangerous. Would it be hard to add a type argument to those 
> functions and delegate this to the caller? Any better idea (maybe this is 
> already safe and I am just missing it)?

Richi can you help us here? I'm not sure what guarantees do we have here in 
GIMPLE?

Martin

> 



Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-09 Thread Marc Glisse

On Mon, 9 Sep 2019, Martin Liška wrote:


I'm sending slightly updated version of the patch where we
need to properly select type in maybe_fold_comparisons_from_match_pd
function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE
and so that we can't return a boolean_type_node.


+  tree type = TREE_TYPE (op1a);
+  if (TREE_CODE (type) != VECTOR_TYPE)
+type = boolean_type_node;

Don't you need build_same_sized_truth_vector_type or something, for 
instance with AVX512?


Also, IIRC EQ_EXPR for vectors can return either a vector or a boolean. I 
don't know if we can end up here with both versions, but if we can, 
guessing the type could be dangerous. Would it be hard to add a type 
argument to those functions and delegate this to the caller? Any better 
idea (maybe this is already safe and I am just missing it)?


--
Marc Glisse


Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-09 Thread Richard Biener
On Mon, 9 Sep 2019, Martin Liška wrote:

> Hi.
> 
> I'm sending slightly updated version of the patch where we
> need to properly select type in maybe_fold_comparisons_from_match_pd
> function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE
> and so that we can't return a boolean_type_node.
> 
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> Ready to be installed?

2019-07-16  Li Jia He  
Martin Liska  

* gimple.h (gimple_init): Declare.
(gimple_size): Likewise.
* gimple.c (gimple_init): Remove static and inline restrictions.
(gimple_alloc): Only allocate memory and call gimple_init.
(gimple_size): Likewise.

Likewise?

* tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn.
(make_ssa_name_fn): New.

You didn't touch make_ssa_name_fn.

Since we're needing another iteration:

+  /* Allocate gimple stmt1 on the stack.  */
+  gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size 
(GIMPLE_ASSIGN, 2));

You can use gassign *stmt1 here so all the gimple_assign_ fns below
get cheaper.

+  if (op.resimplify (NULL, follow_all_ssa_edges))
+{
+  if (gimple_simplified_result_is_gimple_val (&op))
+   {
+ tree res = op.ops[0];
+ switch (TREE_CODE (res))
+   {
+   case SSA_NAME:
+   {
+ gimple *def = SSA_NAME_DEF_STMT (res);

you shouldn't expand SSA names here unless that SSA name is
exactly lhs1 or lhs2 from above.  So

 if (res == lhs1)
   return build2 (...);
 else if (res == lhs2)
   return build2 (..);
 else
   return res;

plus you miss the case where 'op' became a simplified comparison
in itself.  So,

 if (op.code.is_tree_code ()
 && TREE_CODE_CLASS ((enum tree_code)op.code) == tcc_comparison)
   {
  tree op0 = op.ops[0];
  tree op1 = op.ops[1];
  if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2)
return NULL_TREE;  /* not simple */
  return build2 ((enum tree_code)op.code, op.type,
 op0, op1);
   }

note you need not fold_ again.  It's of course ugly that we
need to build a GENERIC tree here but that's the current interface
and thus OK at the moment.

Thanks,
Richard.

Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-09 Thread Martin Liška
Hi.

I'm sending slightly updated version of the patch where we
need to properly select type in maybe_fold_comparisons_from_match_pd
function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE
and so that we can't return a boolean_type_node.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin
>From b6165b1d4be04f47bfa2b511974f5b8e784acb41 Mon Sep 17 00:00:00 2001
From: Li Jia He 
Date: Mon, 15 Jul 2019 00:30:25 -0500
Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd

gcc/ChangeLog

2019-07-16  Li Jia He  
	Martin Liska  

	* gimple.h (gimple_init): Declare.
	(gimple_size): Likewise.
	* gimple.c (gimple_init): Remove static and inline restrictions.
	(gimple_alloc): Only allocate memory and call gimple_init.
	(gimple_size): Likewise.
	* gimple-fold.c (maybe_fold_comparisons_from_match_pd): New function.
	(maybe_fold_and_comparisons): Modify and_comparisons_1 invocation and
	call maybe_fold_comparisons_from_match_pd.
	(maybe_fold_or_comparisons): Modify or_comparisons_1 invocation and
	call maybe_fold_comparisons_from_match_pd.
	* tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn.
	(make_ssa_name_fn): New.
	* tree-ssanames.h (init_ssa_name_imm_use): New.
---
 gcc/gimple-fold.c   | 112 
 gcc/gimple.c|  37 +--
 gcc/gimple.h|   2 +
 gcc/tree-ssanames.c |  21 ++---
 gcc/tree-ssanames.h |   1 +
 5 files changed, 142 insertions(+), 31 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index fcffb9802b7..8a9eca13b87 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -5834,6 +5834,89 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
   return NULL_TREE;
 }
 
+/* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons
+   : try to simplify the AND/OR of the ssa variable VAR with the comparison
+   specified by (OP2A CODE2 OP2B) from match.pd.  Return NULL_EXPR if we can't
+   simplify this to a single expression.  As we are going to lower the cost
+   of building SSA names / gimple stmts significantly, we need to allocate
+   them ont the stack.  This will cause the code to be a bit ugly.  */
+
+static tree
+maybe_fold_comparisons_from_match_pd (enum tree_code code, enum tree_code code1,
+  tree op1a, tree op1b,
+  enum tree_code code2, tree op2a,
+  tree op2b)
+{
+  tree type = TREE_TYPE (op1a);
+  if (TREE_CODE (type) != VECTOR_TYPE)
+type = boolean_type_node;
+
+  /* Allocate gimple stmt1 on the stack.  */
+  gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 2));
+  gimple_init (stmt1, GIMPLE_ASSIGN, 3);
+  gimple_assign_set_rhs_code (stmt1, code1);
+  gimple_assign_set_rhs1 (stmt1, op1a);
+  gimple_assign_set_rhs2 (stmt1, op1b);
+
+  /* Allocate gimple stmt2 on the stack.  */
+  gimple *stmt2 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 2));
+  gimple_init (stmt2, GIMPLE_ASSIGN, 3);
+  gimple_assign_set_rhs_code (stmt2, code2);
+  gimple_assign_set_rhs1 (stmt2, op2a);
+  gimple_assign_set_rhs2 (stmt2, op2b);
+
+  /* Allocate SSA names(lhs1) on the stack.  */
+  tree lhs1 = (tree)XALLOCA (tree_ssa_name);
+  memset (lhs1, 0, sizeof (tree_ssa_name));
+  TREE_SET_CODE (lhs1, SSA_NAME);
+  TREE_TYPE (lhs1) = type;
+  init_ssa_name_imm_use (lhs1);
+
+  /* Allocate SSA names(lhs2) on the stack.  */
+  tree lhs2 = (tree)XALLOCA (tree_ssa_name);
+  memset (lhs2, 0, sizeof (tree_ssa_name));
+  TREE_SET_CODE (lhs2, SSA_NAME);
+  TREE_TYPE (lhs2) = type;
+  init_ssa_name_imm_use (lhs2);
+
+  gimple_assign_set_lhs (stmt1, lhs1);
+  gimple_assign_set_lhs (stmt2, lhs2);
+
+  gimple_match_op op (gimple_match_cond::UNCOND, code,
+		  type, gimple_assign_lhs (stmt1),
+		  gimple_assign_lhs (stmt2));
+  if (op.resimplify (NULL, follow_all_ssa_edges))
+{
+  if (gimple_simplified_result_is_gimple_val (&op))
+	{
+	  tree res = op.ops[0];
+	  switch (TREE_CODE (res))
+	{
+	case SSA_NAME:
+		{
+		  gimple *def = SSA_NAME_DEF_STMT (res);
+
+		  if (!is_gimple_assign (def)
+		  || TREE_CODE_CLASS (gimple_assign_rhs_code (def))
+		  != tcc_comparison)
+		return NULL_TREE;
+
+		  return fold_build2 (gimple_assign_rhs_code (def),
+  type, gimple_assign_rhs1 (def),
+  gimple_assign_rhs2 (def));
+		}
+	case INTEGER_CST:
+	  /* Fold expression to boolean_true_node or boolean_false_node.  */
+	  return res;
+	default:
+	  return NULL_TREE;
+	}
+	}
+}
+
+  return NULL_TREE;
+}
+
 /* Try to simplify the AND of two comparisons, specified by
(OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
If this can be simplified to a single expression (without requiring
@@ -5845,11 +5928,17 @@ tree
 maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b,
 			enum tree_code code2, tree op2a, tree op2b)
 {
-  tree t = and_comparisons_1 (code1, op

[PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

2019-09-06 Thread Martin Liška
On 9/5/19 3:01 PM, Richard Biener wrote:
> On Tue, 16 Jul 2019, Li Jia He wrote:
> 
>> Hi,
>>
>>   I made some changes based on the recommendations. Would you like to
>>   help me to see it again ? Sorry, it took so long time to provide the
>>   patch.
>>
>>   Note: 1. I keep the code for and_comparisons_1 and or_comparisons_1.
>>  The reason is that I did not found a good way to handle the
>>  optimization of '((x CODE1 y) AND (x CODE2 y))' in match.pd.
>>  Maybe I missing some important information about match.pd.
>>  2. The gimple_resimplify2 function is not used.  Since stmt1,
>>  stmt2, lhs1 and lhs2 are allocated on the stack, Is there a
>>  question with the value on the stack as the return value ?
>>  I may have misunderstood Richard's intention.
> 
> Sorry for the delay in reviewing.
> 
> Rather than exporting gimple_set_code and gimple_size I'd split
> out a
> 
> void
> gimple_init (gimple *, enum gimple_code code, unsigned nops);
> 
> from gimple_alloc (changing that to GC allocate not cleared
> memory) doing all of the actual initialization.  Then the
> allocation would go like
> 
> gimple *stmt1 = (gimple *)XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 
> 3));
> gimple_init (stmt1, GIMPLE_ASSIGN, 3);
> 
> with an overload for gimple_size to account for # of ops.
> 
> +  /* Allocate SSA names(lhs1) on the stack.  */
> +  tree lhs1 = XALLOCA (tree_node);
> 
> you can use (tree) XALLOCA (tree_ssa_name) here
> 
> +  /* Call the interface function of match.pd to simplify the expression.  
> */
> +  tree t = gimple_simplify (code, boolean_type_node, gimple_assign_lhs 
> (stmt1),
> +   gimple_assign_lhs (stmt2), NULL,
> +   follow_all_ssa_edges);
> +
> +  if (t)
> 
> As I told Martin offline the appropriate function to use is
> 
>  You'd do
> 
>   gimple_match_op op (gimple_match_cond::UNCOND, code,
>  boolean_type_node, gimple_assign_lhs (stmt1),
> gimple_assign_lhs (stmt2));
>   if (op->resimplify (NULL, follow_all_ssa_edges))
>{
>   if (gimple_simplified_result_is_gimple_val (res_op))
> .. got a constant or SSA name ..
>   else if (res_op->code.is_tree_code ()
>  && TREE_CODE_CLASS ((tree_code)res_op->code)) ==
> tcc_comparison)
> ... got a comparison res_op->op[0] res_op->code res_op->op[1] ...
> 
> so you get the outermost expression back decomposed.
> 
> Otherwise with you passing NULL as the gimple_seq you'll miss quite
> some simplification cases.
> 
> You also have to watch out for the result containing the LHS of one
> of your temporary stmts.
> 
> +  if (tree t = maybe_fold_comparisons_from_match_pd (BIT_AND_EXPR, code1, 
> op1a,
> +op1b, code2, op2a, 
> op2b))
> +return t;
> +
> +  if (tree t = maybe_fold_comparisons_from_match_pd (BIT_AND_EXPR, code2, 
> op2a,
> +op2b, code1, op1a, 
> op1b))
> +return t;
> 
> with match.pd rules you shouldn't need to call this twice, once with
> swapped operands.
> 
> Otherwise this first patch looks like what I'd have done and we
> can build upon it.
> 
> Not sure if you or Martin wants to improve it according to my
> comments.
> 
> Thanks,
> Richard.
> 

I'm sending patch that addresses the feedback from Richard.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin
>From 6f8feb5ccf46bae2c65b88a90661e23521ce9143 Mon Sep 17 00:00:00 2001
From: Li Jia He 
Date: Mon, 15 Jul 2019 00:30:25 -0500
Subject: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd

gcc/ChangeLog

2019-07-16  Li Jia He  
	Martin Liska  

	* gimple.h (gimple_init): Declare.
	(gimple_size): Likewise.
	* gimple.c (gimple_init): Remove static and inline restrictions.
	(gimple_alloc): Only allocate memory and call gimple_init.
	(gimple_size): Likewise.
	* gimple-fold.c (maybe_fold_comparisons_from_match_pd): New function.
	(maybe_fold_and_comparisons): Modify and_comparisons_1 invocation and
	call maybe_fold_comparisons_from_match_pd.
	(maybe_fold_or_comparisons): Modify or_comparisons_1 invocation and
	call maybe_fold_comparisons_from_match_pd.
	* tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn.
	(make_ssa_name_fn): New.
	* tree-ssanames.h (init_ssa_name_imm_use): New.
---
 gcc/gimple-fold.c   | 108 
 gcc/gimple.c|  37 +--
 gcc/gimple.h|   2 +
 gcc/tree-ssanames.c |  21 ++---
 gcc/