diff mbox series

[3/5] Rewrite part of and_comparisons_1 into match.pd.

Message ID c04bad8c-a1ba-239a-9fee-c9dc9be7e3a3@suse.cz
State New
Headers show
Series [1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd | expand

Commit Message

Martin Liška Sept. 9, 2019, 12:24 p.m. UTC
Hi.

The patch is about transition of and_comparisons_1 matching
into match.pd.

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

Ready to be installed?
Thanks,
Martin

Comments

Martin Liška Sept. 9, 2019, 1:41 p.m. UTC | #1
On 9/9/19 2:24 PM, Martin Liška wrote:
> Hi.
> 
> The patch is about transition of and_comparisons_1 matching
> into match.pd.
> 
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> Ready to be installed?
> Thanks,
> Martin
> 

Updated version (as mentioned in part 1).

Martin
Martin Liška Sept. 10, 2019, 7:41 a.m. UTC | #2
On 9/9/19 3:41 PM, Martin Liška wrote:
> On 9/9/19 2:24 PM, Martin Liška wrote:
>> Hi.
>>
>> The patch is about transition of and_comparisons_1 matching
>> into match.pd.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
>> Thanks,
>> Martin
>>
> 
> Updated version (as mentioned in part 1).
> 
> Martin
> 

And there's updated part 3 where I properly handle the
TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison case.

Martin
Bernhard Reutner-Fischer Sept. 10, 2019, 8:52 a.m. UTC | #3
On 9 September 2019 15:41:05 CEST, "Martin Liška" <mliska@suse.cz> wrote:
>On 9/9/19 2:24 PM, Martin Liška wrote:
>> Hi.
>> 
>> The patch is about transition of and_comparisons_1 matching
>> into match.pd.
>> 
>> Patch can bootstrap on x86_64-linux-gnu and survives regression
>tests.
>> 
>> Ready to be installed?
>> Thanks,
>> Martin
>> 
>
>Updated version (as mentioned in part 1).
>

+	       && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)

COMPARISON_CLASS_P

thanks,
Marc Glisse Sept. 10, 2019, 11:19 a.m. UTC | #4
(some quick comments, I didn't check in details)

+    (and:c (code1 @0 INTEGER_CST@1) (code2 @0 INTEGER_CST@2))
[...]
+       (if (code1 == NE_EXPR && !val) (code2 @0 @2))))))))

How about

(and:c (code1 @0 INTEGER_CST@1) (code2@3 @0 INTEGER_CST@2))
[...]
(if (code1 == NE_EXPR && !val) @3)))))))

instead? This is also a way to check how well the generator handles this, 
when @3 may not really exist (was in a gimple_cond).

(and:c (eq@3 @0 INTEGER_CST@1) (code2 @0 INTEGER_CST@2))

could be simplified to

(and @3 (code2 @1 @2))

always (a trivial transform) and let the rest of the machinery fold code2 
on constants and then and with a constant. This way you would only need to 
handle code1==NE_EXPR in the complicated transform, it might be slightly 
more readable. (I am not saying we absolutely have to do it this way, it 
is just a suggestion)

+   (and (code1:c @0 INTEGER_CST@1) (code2:c @0 INTEGER_CST@2))

Don't we canonicalize 3 < X to X > 3? That would make the :c unnecessary. 
Actually I don't remember how :c works on non-commutative operations 
(there was also :C I think).

+      /* Chose the more restrictive of two < or <= comparisons.  */

Choose?
Martin Liška Sept. 11, 2019, 8:10 a.m. UTC | #5
On 9/10/19 10:52 AM, Bernhard Reutner-Fischer wrote:
> On 9 September 2019 15:41:05 CEST, "Martin Liška" <mliska@suse.cz> wrote:
>> On 9/9/19 2:24 PM, Martin Liška wrote:
>>> Hi.
>>>
>>> The patch is about transition of and_comparisons_1 matching
>>> into match.pd.
>>>
>>> Patch can bootstrap on x86_64-linux-gnu and survives regression
>> tests.
>>>
>>> Ready to be installed?
>>> Thanks,
>>> Martin
>>>
>>
>> Updated version (as mentioned in part 1).
>>
> 
> +	       && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
> 
> COMPARISON_CLASS_P
> 
> thanks,
> 

Thanks for the comment.

Martin
Martin Liška Sept. 11, 2019, 8:27 a.m. UTC | #6
On 9/10/19 1:19 PM, Marc Glisse wrote:
> (some quick comments, I didn't check in details)

Thanks for them.

> 
> +    (and:c (code1 @0 INTEGER_CST@1) (code2 @0 INTEGER_CST@2))
> [...]
> +       (if (code1 == NE_EXPR && !val) (code2 @0 @2))))))))
> 
> How about
> 
> (and:c (code1 @0 INTEGER_CST@1) (code2@3 @0 INTEGER_CST@2))
> [...]
> (if (code1 == NE_EXPR && !val) @3)))))))
> 
> instead? This is also a way to check how well the generator handles this, when @3 may not really exist (was in a gimple_cond).

I like the changes. I applied them to all patterns in the patch set.

> 
> (and:c (eq@3 @0 INTEGER_CST@1) (code2 @0 INTEGER_CST@2))
> 
> could be simplified to
> 
> (and @3 (code2 @1 @2))
> 
> always (a trivial transform) and let the rest of the machinery fold code2 on constants and then and with a constant. This way you would only need to handle code1==NE_EXPR in the complicated transform, it might be slightly more readable. (I am not saying we absolutely have to do it this way, it is just a suggestion)

That would be possible, I can experiment with that after the patch set is applied.
The current patch is more or less direct transformation of what we have in gimple-fold.c.
> 
> +   (and (code1:c @0 INTEGER_CST@1) (code2:c @0 INTEGER_CST@2))
> 
> Don't we canonicalize 3 < X to X > 3? That would make the :c unnecessary. Actually I don't remember how :c works on non-commutative operations (there was also :C I think).

Dunno here, Richi?

> 
> +      /* Chose the more restrictive of two < or <= comparisons.  */
> 
> Choose?

Yep.

Thank you,
Martin

>
Martin Liška Sept. 11, 2019, 11:17 a.m. UTC | #7
I'm sending updated version of the patch where I changed
from previous version:
- more compact matching is used (note @3 and @4):
  (and (code1:c@3 @0 INTEGER_CST@1) (code2:c@4 @0 INTEGER_CST@2))

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

Ready to be installed?
Thanks,
Martin
Richard Biener Sept. 11, 2019, 12:43 p.m. UTC | #8
On Wed, 11 Sep 2019, Martin Liška wrote:

> I'm sending updated version of the patch where I changed
> from previous version:
> - more compact matching is used (note @3 and @4):
>   (and (code1:c@3 @0 INTEGER_CST@1) (code2:c@4 @0 INTEGER_CST@2))
> 
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> Ready to be installed?

--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -1894,9 +1894,11 @@ dt_node *
 dt_node::append_simplify (simplify *s, unsigned pattern_no,
                          dt_operand **indexes)
 {
+  dt_simplify *s2;
   dt_simplify *n = new dt_simplify (s, pattern_no, indexes);
   for (unsigned i = 0; i < kids.length (); ++i)
-    if (dt_simplify *s2 = dyn_cast <dt_simplify *> (kids[i]))
+    if ((s2 = dyn_cast <dt_simplify *> (kids[i]))
+       && s->match->location != s2->s->match->location)
       {

can you retain the warning for verbose >= 1 please?  And put in
a comment that duplicates are sometimes hard to avoid with
nested for so this keeps match.pd sources small.

+  /* Function maybe_fold_comparisons_from_match_pd creates temporary
+     SSA_NAMEs.  */
+  if (TREE_CODE (op1) == SSA_NAME && TREE_CODE (op2) == SSA_NAME)
+    {
+      gimple *s = SSA_NAME_DEF_STMT (op2);
+      if (is_gimple_assign (s))
+       return same_bool_comparison_p (op1, gimple_assign_rhs_code (s),
+                                      gimple_assign_rhs1 (s),
+                                      gimple_assign_rhs2 (s));
+      else
+       return false;
+    }

when do you actually run into the need to add this?  The whole
same_bool_result_p/same_bool_comparison_p helpers look a bit
odd to me.  It shouldn't be special to the new temporaries
either so at least the comment looks out-of place.

+      else if (op.code.is_tree_code ()
+              && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
+       {

COMPARISON_CLASS_P ((tree_code)op.code)

as was noted.

Any particular reason you needed to swap the calls in
maybe_fold_and/or_comparisons?

+(for code1 (eq ne)
+ (for code2 (eq ne lt gt le ge)
+  (for and (truth_and bit_and)
+   (simplify

You could save some code-bloat with writing

  (for and (
#if GENERIC
  truth_and
#endif
  bit_and)

but since you are moving the patterns from GIMPLE code I'd say
simply remove truth_and and that innermost for?

Otherwise OK.

Thanks,
Richard.




> Thanks,
> Martin
>
Martin Liška Sept. 11, 2019, 1:19 p.m. UTC | #9
On 9/11/19 2:43 PM, Richard Biener wrote:
> On Wed, 11 Sep 2019, Martin Liška wrote:
> 
>> I'm sending updated version of the patch where I changed
>> from previous version:
>> - more compact matching is used (note @3 and @4):
>>   (and (code1:c@3 @0 INTEGER_CST@1) (code2:c@4 @0 INTEGER_CST@2))
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
> 
> --- a/gcc/genmatch.c
> +++ b/gcc/genmatch.c
> @@ -1894,9 +1894,11 @@ dt_node *
>  dt_node::append_simplify (simplify *s, unsigned pattern_no,
>                           dt_operand **indexes)
>  {
> +  dt_simplify *s2;
>    dt_simplify *n = new dt_simplify (s, pattern_no, indexes);
>    for (unsigned i = 0; i < kids.length (); ++i)
> -    if (dt_simplify *s2 = dyn_cast <dt_simplify *> (kids[i]))
> +    if ((s2 = dyn_cast <dt_simplify *> (kids[i]))
> +       && s->match->location != s2->s->match->location)
>        {
> 
> can you retain the warning for verbose >= 1 please?  And put in
> a comment that duplicates are sometimes hard to avoid with
> nested for so this keeps match.pd sources small.

Sure.

> 
> +  /* Function maybe_fold_comparisons_from_match_pd creates temporary
> +     SSA_NAMEs.  */
> +  if (TREE_CODE (op1) == SSA_NAME && TREE_CODE (op2) == SSA_NAME)
> +    {
> +      gimple *s = SSA_NAME_DEF_STMT (op2);
> +      if (is_gimple_assign (s))
> +       return same_bool_comparison_p (op1, gimple_assign_rhs_code (s),
> +                                      gimple_assign_rhs1 (s),
> +                                      gimple_assign_rhs2 (s));
> +      else
> +       return false;
> +    }
> 
> when do you actually run into the need to add this?  The whole
> same_bool_result_p/same_bool_comparison_p helpers look a bit
> odd to me.  It shouldn't be special to the new temporaries
> either so at least the comment looks out-of place.

At some point it was needed to handle gcc/testsuite/gcc.dg/pr46909.c
test-case. Apparently, now the test-case is fine with the hunk. I will it
removal of the hunk.

> 
> +      else if (op.code.is_tree_code ()
> +              && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
> +       {
> 
> COMPARISON_CLASS_P ((tree_code)op.code)
> 
> as was noted.

Won't work here:

/home/marxin/Programming/gcc/gcc/gimple-fold.c: In function ‘tree_node* maybe_fold_comparisons_from_match_pd(tree, tree_code, tree_code, tree, tree, tree_code, tree, tree)’:
/home/marxin/Programming/gcc/gcc/tree.h:239:49: error: base operand of ‘->’ is not a pointer
  239 | #define TREE_CODE(NODE) ((enum tree_code) (NODE)->base.code)
      |                                                 ^~

> 
> Any particular reason you needed to swap the calls in
> maybe_fold_and/or_comparisons?
> 
> +(for code1 (eq ne)
> + (for code2 (eq ne lt gt le ge)
> +  (for and (truth_and bit_and)
> +   (simplify
> 
> You could save some code-bloat with writing
> 
>   (for and (
> #if GENERIC
>   truth_and
> #endif
>   bit_and)
> 
> but since you are moving the patterns from GIMPLE code I'd say
> simply remove truth_and and that innermost for?

I'm gonna drop the generic tree codes support.

Martin

> 
> Otherwise OK.
> 
> Thanks,
> Richard.
> 
> 
> 
> 
>> Thanks,
>> Martin
>>
>
Martin Liška Sept. 11, 2019, 1:57 p.m. UTC | #10
On 9/11/19 3:19 PM, Martin Liška wrote:
> On 9/11/19 2:43 PM, Richard Biener wrote:
>> On Wed, 11 Sep 2019, Martin Liška wrote:
>>
>>> I'm sending updated version of the patch where I changed
>>> from previous version:
>>> - more compact matching is used (note @3 and @4):
>>>   (and (code1:c@3 @0 INTEGER_CST@1) (code2:c@4 @0 INTEGER_CST@2))
>>>
>>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>>
>>> Ready to be installed?
>>
>> --- a/gcc/genmatch.c
>> +++ b/gcc/genmatch.c
>> @@ -1894,9 +1894,11 @@ dt_node *
>>  dt_node::append_simplify (simplify *s, unsigned pattern_no,
>>                           dt_operand **indexes)
>>  {
>> +  dt_simplify *s2;
>>    dt_simplify *n = new dt_simplify (s, pattern_no, indexes);
>>    for (unsigned i = 0; i < kids.length (); ++i)
>> -    if (dt_simplify *s2 = dyn_cast <dt_simplify *> (kids[i]))
>> +    if ((s2 = dyn_cast <dt_simplify *> (kids[i]))
>> +       && s->match->location != s2->s->match->location)
>>        {
>>
>> can you retain the warning for verbose >= 1 please?  And put in
>> a comment that duplicates are sometimes hard to avoid with
>> nested for so this keeps match.pd sources small.
> 
> Sure.
> 
>>
>> +  /* Function maybe_fold_comparisons_from_match_pd creates temporary
>> +     SSA_NAMEs.  */
>> +  if (TREE_CODE (op1) == SSA_NAME && TREE_CODE (op2) == SSA_NAME)
>> +    {
>> +      gimple *s = SSA_NAME_DEF_STMT (op2);
>> +      if (is_gimple_assign (s))
>> +       return same_bool_comparison_p (op1, gimple_assign_rhs_code (s),
>> +                                      gimple_assign_rhs1 (s),
>> +                                      gimple_assign_rhs2 (s));
>> +      else
>> +       return false;
>> +    }
>>
>> when do you actually run into the need to add this?  The whole
>> same_bool_result_p/same_bool_comparison_p helpers look a bit
>> odd to me.  It shouldn't be special to the new temporaries
>> either so at least the comment looks out-of place.
> 
> At some point it was needed to handle gcc/testsuite/gcc.dg/pr46909.c
> test-case. Apparently, now the test-case is fine with the hunk. I will it
> removal of the hunk.

So it's not needed.

> 
>>
>> +      else if (op.code.is_tree_code ()
>> +              && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
>> +       {
>>
>> COMPARISON_CLASS_P ((tree_code)op.code)
>>
>> as was noted.
> 
> Won't work here:
> 
> /home/marxin/Programming/gcc/gcc/gimple-fold.c: In function ‘tree_node* maybe_fold_comparisons_from_match_pd(tree, tree_code, tree_code, tree, tree, tree_code, tree, tree)’:
> /home/marxin/Programming/gcc/gcc/tree.h:239:49: error: base operand of ‘->’ is not a pointer
>   239 | #define TREE_CODE(NODE) ((enum tree_code) (NODE)->base.code)
>       |                                                 ^~
> 
>>
>> Any particular reason you needed to swap the calls in
>> maybe_fold_and/or_comparisons?
>>
>> +(for code1 (eq ne)
>> + (for code2 (eq ne lt gt le ge)
>> +  (for and (truth_and bit_and)
>> +   (simplify
>>
>> You could save some code-bloat with writing
>>
>>   (for and (
>> #if GENERIC
>>   truth_and
>> #endif
>>   bit_and)
>>
>> but since you are moving the patterns from GIMPLE code I'd say
>> simply remove truth_and and that innermost for?
> 
> I'm gonna drop the generic tree codes support.

It's dropped in the updated patch.

Martin

> 
> Martin
> 
>>
>> Otherwise OK.
>>
>> Thanks,
>> Richard.
>>
>>
>>
>>
>>> Thanks,
>>> Martin
>>>
>>
>
Richard Biener Sept. 16, 2019, 9:04 a.m. UTC | #11
On Wed, 11 Sep 2019, Martin Liška wrote:

> On 9/11/19 3:19 PM, Martin Liška wrote:
> > On 9/11/19 2:43 PM, Richard Biener wrote:
> >> Any particular reason you needed to swap the calls in
> >> maybe_fold_and/or_comparisons?

You didn't answer this, besides that the patch is OK.

Thanks,
Richard.
Martin Liška Sept. 16, 2019, 1:47 p.m. UTC | #12
On 9/16/19 5:04 AM, Richard Biener wrote:
> On Wed, 11 Sep 2019, Martin Liška wrote:
> 
>> On 9/11/19 3:19 PM, Martin Liška wrote:
>>> On 9/11/19 2:43 PM, Richard Biener wrote:
>>>> Any particular reason you needed to swap the calls in
>>>> maybe_fold_and/or_comparisons?
> 
> You didn't answer this, besides that the patch is OK.

Ah, sorry.

No, there's not any particular reason. My motivation was that I moved
the patterns from the beginning of and_comparisons_1 to match.pd.
So that I wanted to begin with the maybe_fold_comparisons_from_match_pd.

I'll put it back to the original order.

Martin

> 
> Thanks,
> Richard.
>
diff mbox series

Patch

From 15045058d6caf84734ea949a297b6e31d9a8647c Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Fri, 6 Sep 2019 12:34:49 +0200
Subject: [PATCH 3/5] Rewrite part of and_comparisons_1 into match.pd.

gcc/ChangeLog:

2019-09-09  Martin Liska  <mliska@suse.cz>

	* genmatch.c (dt_node::append_simplify): Ignore warning
	for the same location.
	* gimple-fold.c (same_bool_result_p): Handle newly
	created SSA_NAMEs ar arguments.
	(and_comparisons_1): Add new argument gimple_stmt_iterator.
	(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_comparisons_from_match_pd): Handle creation
	of temporary SSA_NAMEs. Add new argument gimple_stmt_iterator.
	(maybe_fold_and_comparisons): Likewise.
	(maybe_fold_or_comparisons): Likewise.
	* gimple-fold.h (maybe_fold_and_comparisons): Likewise.
	(maybe_fold_or_comparisons): Likewise.
	* match.pd: Add rules for (X OP1 CST1) && (X OP2 CST2).
	* tree-if-conv.c (fold_or_predicates): Do not
	pass gimple_stmt_iterator.
	* tree-ssa-ifcombine.c (ifcombine_ifandif): Pass gimple_stmt_iterator.
	* tree-ssa-reassoc.c (eliminate_redundant_comparison): Do not
	pass gimple_stmt_iterator.
	(optimize_vec_cond_expr): Likewise.
---
 gcc/genmatch.c           |   4 +-
 gcc/gimple-fold.c        | 261 +++++++++++++--------------------------
 gcc/gimple-fold.h        |   6 +-
 gcc/match.pd             |  68 ++++++++++
 gcc/tree-if-conv.c       |   2 +-
 gcc/tree-ssa-ifcombine.c |   5 +-
 gcc/tree-ssa-reassoc.c   |  11 +-
 7 files changed, 172 insertions(+), 185 deletions(-)

diff --git a/gcc/genmatch.c b/gcc/genmatch.c
index 2e7bf27eeda..b7194448a0f 100644
--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -1894,9 +1894,11 @@  dt_node *
 dt_node::append_simplify (simplify *s, unsigned pattern_no,
 			  dt_operand **indexes)
 {
+  dt_simplify *s2;
   dt_simplify *n = new dt_simplify (s, pattern_no, indexes);
   for (unsigned i = 0; i < kids.length (); ++i)
-    if (dt_simplify *s2 = dyn_cast <dt_simplify *> (kids[i]))
+    if ((s2 = dyn_cast <dt_simplify *> (kids[i]))
+	&& s->match->location != s2->s->match->location)
       {
 	warning_at (s->match->location, "duplicate pattern");
 	warning_at (s2->s->match->location, "previous pattern defined here");
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 8a9eca13b87..f9971c004b7 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -5350,6 +5350,19 @@  same_bool_result_p (const_tree op1, const_tree op2)
   if (operand_equal_p (op1, op2, 0))
     return true;
 
+  /* Function maybe_fold_comparisons_from_match_pd creates temporary
+     SSA_NAMEs.  */
+  if (TREE_CODE (op1) == SSA_NAME && TREE_CODE (op2) == SSA_NAME)
+    {
+      gimple *s = SSA_NAME_DEF_STMT (op2);
+      if (is_gimple_assign (s))
+	return same_bool_comparison_p (op1, gimple_assign_rhs_code (s),
+				       gimple_assign_rhs1 (s),
+				       gimple_assign_rhs2 (s));
+      else
+	return false;
+    }
+
   /* Check the cases where at least one of the operands is a comparison.
      These are a bit smarter than operand_equal_p in that they apply some
      identifies on SSA_NAMEs.  */
@@ -5372,22 +5385,28 @@  same_bool_result_p (const_tree op1, const_tree op2)
 
 static tree
 and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
-		   enum tree_code code2, tree op2a, tree op2b);
+		   enum tree_code code2, tree op2a, tree op2b,
+		   gimple_stmt_iterator *gsi);
 static tree
 and_var_with_comparison (tree var, bool invert,
-			 enum tree_code code2, tree op2a, tree op2b);
+			 enum tree_code code2, tree op2a, tree op2b,
+			 gimple_stmt_iterator *gsi);
 static tree
 and_var_with_comparison_1 (gimple *stmt,
-			   enum tree_code code2, tree op2a, tree op2b);
+			   enum tree_code code2, tree op2a, tree op2b,
+			   gimple_stmt_iterator *gsi);
 static tree
 or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
-		  enum tree_code code2, tree op2a, tree op2b);
+		  enum tree_code code2, tree op2a, tree op2b,
+		  gimple_stmt_iterator *gsi);
 static tree
 or_var_with_comparison (tree var, bool invert,
-			enum tree_code code2, tree op2a, tree op2b);
+			enum tree_code code2, tree op2a, tree op2b,
+			gimple_stmt_iterator *gsi);
 static tree
 or_var_with_comparison_1 (gimple *stmt,
-			  enum tree_code code2, tree op2a, tree op2b);
+			  enum tree_code code2, tree op2a, tree op2b,
+			  gimple_stmt_iterator *gsi);
 
 /* Helper function for and_comparisons_1:  try to simplify the AND of the
    ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
@@ -5396,7 +5415,8 @@  or_var_with_comparison_1 (gimple *stmt,
 
 static tree
 and_var_with_comparison (tree var, bool invert,
-			 enum tree_code code2, tree op2a, tree op2b)
+			 enum tree_code code2, tree op2a, tree op2b,
+			 gimple_stmt_iterator *gsi)
 {
   tree t;
   gimple *stmt = SSA_NAME_DEF_STMT (var);
@@ -5411,9 +5431,9 @@  and_var_with_comparison (tree var, bool invert,
   if (invert)
     t = or_var_with_comparison_1 (stmt, 
 				  invert_tree_comparison (code2, false),
-				  op2a, op2b);
+				  op2a, op2b, gsi);
   else
-    t = and_var_with_comparison_1 (stmt, code2, op2a, op2b);
+    t = and_var_with_comparison_1 (stmt, code2, op2a, op2b, gsi);
   return canonicalize_bool (t, invert);
 }
 
@@ -5423,7 +5443,8 @@  and_var_with_comparison (tree var, bool invert,
 
 static tree
 and_var_with_comparison_1 (gimple *stmt,
-			   enum tree_code code2, tree op2a, tree op2b)
+			   enum tree_code code2, tree op2a, tree op2b,
+			   gimple_stmt_iterator *gsi)
 {
   tree var = gimple_assign_lhs (stmt);
   tree true_test_var = NULL_TREE;
@@ -5456,9 +5477,7 @@  and_var_with_comparison_1 (gimple *stmt,
       tree t = and_comparisons_1 (innercode,
 				  gimple_assign_rhs1 (stmt),
 				  gimple_assign_rhs2 (stmt),
-				  code2,
-				  op2a,
-				  op2b);
+				  code2, op2a, op2b, gsi);
       if (t)
 	return t;
     }
@@ -5489,11 +5508,13 @@  and_var_with_comparison_1 (gimple *stmt,
       else if (inner1 == false_test_var)
 	return (is_and
 		? boolean_false_node
-		: and_var_with_comparison (inner2, false, code2, op2a, op2b));
+		: and_var_with_comparison (inner2, false, code2, op2a, op2b,
+					   gsi));
       else if (inner2 == false_test_var)
 	return (is_and
 		? boolean_false_node
-		: and_var_with_comparison (inner1, false, code2, op2a, op2b));
+		: and_var_with_comparison (inner1, false, code2, op2a, op2b,
+					   gsi));
 
       /* Next, redistribute/reassociate the AND across the inner tests.
 	 Compute the first partial result, (inner1 AND (op2a code op2b))  */
@@ -5503,7 +5524,7 @@  and_var_with_comparison_1 (gimple *stmt,
 	  && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s),
 					      gimple_assign_rhs1 (s),
 					      gimple_assign_rhs2 (s),
-					      code2, op2a, op2b)))
+					      code2, op2a, op2b, gsi)))
 	{
 	  /* Handle the AND case, where we are reassociating:
 	     (inner1 AND inner2) AND (op2a code2 op2b)
@@ -5535,7 +5556,7 @@  and_var_with_comparison_1 (gimple *stmt,
 	  && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s),
 					      gimple_assign_rhs1 (s),
 					      gimple_assign_rhs2 (s),
-					      code2, op2a, op2b)))
+					      code2, op2a, op2b, gsi)))
 	{
 	  /* Handle the AND case, where we are reassociating:
 	     (inner1 AND inner2) AND (op2a code2 op2b)
@@ -5589,7 +5610,8 @@  and_var_with_comparison_1 (gimple *stmt,
 
 static tree
 and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
-		   enum tree_code code2, tree op2a, tree op2b)
+		   enum tree_code code2, tree op2a, tree op2b,
+		   gimple_stmt_iterator *gsi)
 {
   tree truth_type = truth_type_for (TREE_TYPE (op1a));
 
@@ -5618,136 +5640,6 @@  and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 	return t;
     }
 
-  /* If both comparisons are of the same value against constants, we might
-     be able to merge them.  */
-  if (operand_equal_p (op1a, op2a, 0)
-      && TREE_CODE (op1b) == INTEGER_CST
-      && TREE_CODE (op2b) == INTEGER_CST)
-    {
-      int cmp = tree_int_cst_compare (op1b, op2b);
-
-      /* If we have (op1a == op1b), we should either be able to
-	 return that or FALSE, depending on whether the constant op1b
-	 also satisfies the other comparison against op2b.  */
-      if (code1 == EQ_EXPR)
-	{
-	  bool done = true;
-	  bool val;
-	  switch (code2)
-	    {
-	    case EQ_EXPR: val = (cmp == 0); break;
-	    case NE_EXPR: val = (cmp != 0); break;
-	    case LT_EXPR: val = (cmp < 0); break;
-	    case GT_EXPR: val = (cmp > 0); break;
-	    case LE_EXPR: val = (cmp <= 0); break;
-	    case GE_EXPR: val = (cmp >= 0); break;
-	    default: done = false;
-	    }
-	  if (done)
-	    {
-	      if (val)
-		return fold_build2 (code1, boolean_type_node, op1a, op1b);
-	      else
-		return boolean_false_node;
-	    }
-	}
-      /* Likewise if the second comparison is an == comparison.  */
-      else if (code2 == EQ_EXPR)
-	{
-	  bool done = true;
-	  bool val;
-	  switch (code1)
-	    {
-	    case EQ_EXPR: val = (cmp == 0); break;
-	    case NE_EXPR: val = (cmp != 0); break;
-	    case LT_EXPR: val = (cmp > 0); break;
-	    case GT_EXPR: val = (cmp < 0); break;
-	    case LE_EXPR: val = (cmp >= 0); break;
-	    case GE_EXPR: val = (cmp <= 0); break;
-	    default: done = false;
-	    }
-	  if (done)
-	    {
-	      if (val)
-		return fold_build2 (code2, boolean_type_node, op2a, op2b);
-	      else
-		return boolean_false_node;
-	    }
-	}
-
-      /* Same business with inequality tests.  */
-      else if (code1 == NE_EXPR)
-	{
-	  bool val;
-	  switch (code2)
-	    {
-	    case EQ_EXPR: val = (cmp != 0); break;
-	    case NE_EXPR: val = (cmp == 0); break;
-	    case LT_EXPR: val = (cmp >= 0); break;
-	    case GT_EXPR: val = (cmp <= 0); break;
-	    case LE_EXPR: val = (cmp > 0); break;
-	    case GE_EXPR: val = (cmp < 0); break;
-	    default:
-	      val = false;
-	    }
-	  if (val)
-	    return fold_build2 (code2, boolean_type_node, op2a, op2b);
-	}
-      else if (code2 == NE_EXPR)
-	{
-	  bool val;
-	  switch (code1)
-	    {
-	    case EQ_EXPR: val = (cmp == 0); break;
-	    case NE_EXPR: val = (cmp != 0); break;
-	    case LT_EXPR: val = (cmp <= 0); break;
-	    case GT_EXPR: val = (cmp >= 0); break;
-	    case LE_EXPR: val = (cmp < 0); break;
-	    case GE_EXPR: val = (cmp > 0); break;
-	    default:
-	      val = false;
-	    }
-	  if (val)
-	    return fold_build2 (code1, boolean_type_node, op1a, op1b);
-	}
-
-      /* Chose the more restrictive of two < or <= comparisons.  */
-      else if ((code1 == LT_EXPR || code1 == LE_EXPR)
-	       && (code2 == LT_EXPR || code2 == LE_EXPR))
-	{
-	  if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR))
-	    return fold_build2 (code1, boolean_type_node, op1a, op1b);
-	  else
-	    return fold_build2 (code2, boolean_type_node, op2a, op2b);
-	}
-
-      /* Likewise chose the more restrictive of two > or >= comparisons.  */
-      else if ((code1 == GT_EXPR || code1 == GE_EXPR)
-	       && (code2 == GT_EXPR || code2 == GE_EXPR))
-	{
-	  if ((cmp > 0) || (cmp == 0 && code1 == GT_EXPR))
-	    return fold_build2 (code1, boolean_type_node, op1a, op1b);
-	  else
-	    return fold_build2 (code2, boolean_type_node, op2a, op2b);
-	}
-
-      /* Check for singleton ranges.  */
-      else if (cmp == 0
-	       && ((code1 == LE_EXPR && code2 == GE_EXPR)
-		   || (code1 == GE_EXPR && code2 == LE_EXPR)))
-	return fold_build2 (EQ_EXPR, boolean_type_node, op1a, op2b);
-
-      /* Check for disjoint ranges. */
-      else if (cmp <= 0
-	       && (code1 == LT_EXPR || code1 == LE_EXPR)
-	       && (code2 == GT_EXPR || code2 == GE_EXPR))
-	return boolean_false_node;
-      else if (cmp >= 0
-	       && (code1 == GT_EXPR || code1 == GE_EXPR)
-	       && (code2 == LT_EXPR || code2 == LE_EXPR))
-	return boolean_false_node;
-    }
-
   /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
      NAME's definition is a truth value.  See if there are any simplifications
      that can be done against the NAME's definition.  */
@@ -5762,7 +5654,7 @@  and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 	{
 	case GIMPLE_ASSIGN:
 	  /* Try to simplify by copy-propagating the definition.  */
-	  return and_var_with_comparison (op1a, invert, code2, op2a, op2b);
+	  return and_var_with_comparison (op1a, invert, code2, op2a, op2b, gsi);
 
 	case GIMPLE_PHI:
 	  /* If every argument to the PHI produces the same result when
@@ -5813,7 +5705,7 @@  and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 					     gimple_bb (stmt)))
 			return NULL_TREE;
 		      temp = and_var_with_comparison (arg, invert, code2,
-						      op2a, op2b);
+						      op2a, op2b, gsi);
 		      if (!temp)
 			return NULL_TREE;
 		      else if (!result)
@@ -5845,7 +5737,7 @@  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 op2b, gimple_stmt_iterator *gsi)
 {
   tree type = TREE_TYPE (op1a);
   if (TREE_CODE (type) != VECTOR_TYPE)
@@ -5912,6 +5804,18 @@  maybe_fold_comparisons_from_match_pd (enum tree_code code, enum tree_code code1,
 	      return NULL_TREE;
 	    }
 	}
+      else if (op.code.is_tree_code ()
+	       && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
+	{
+	  if (gsi)
+	    {
+	      tree r = make_ssa_name (type);
+	      gassign *assign = gimple_build_assign (r, (tree_code)op.code,
+						     op.ops[0], op.ops[1]);
+	      gsi_insert_before (gsi, assign, GSI_SAME_STMT);
+	      return r;
+	    }
+	}
     }
 
   return NULL_TREE;
@@ -5926,16 +5830,18 @@  maybe_fold_comparisons_from_match_pd (enum tree_code code, enum tree_code code1,
 
 tree
 maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b,
-			    enum tree_code code2, tree op2a, tree op2b)
+			    enum tree_code code2, tree op2a, tree op2b,
+			    gimple_stmt_iterator *gsi)
 {
-  if (tree t = and_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b))
+  if (tree t = maybe_fold_comparisons_from_match_pd (BIT_AND_EXPR, code1, op1a,
+						     op1b, code2, op2a, op2b,
+						     gsi))
     return t;
 
-  if (tree t = and_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b))
+  if (tree t = and_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b, gsi))
     return t;
 
-  if (tree t = maybe_fold_comparisons_from_match_pd (BIT_AND_EXPR, code1, op1a,
-						     op1b, code2, op2a, op2b))
+  if (tree t = and_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b, gsi))
     return t;
 
   return NULL_TREE;
@@ -5948,7 +5854,8 @@  maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b,
 
 static tree
 or_var_with_comparison (tree var, bool invert,
-			enum tree_code code2, tree op2a, tree op2b)
+			enum tree_code code2, tree op2a, tree op2b,
+			gimple_stmt_iterator *gsi)
 {
   tree t;
   gimple *stmt = SSA_NAME_DEF_STMT (var);
@@ -5963,9 +5870,9 @@  or_var_with_comparison (tree var, bool invert,
   if (invert)
     t = and_var_with_comparison_1 (stmt, 
 				   invert_tree_comparison (code2, false),
-				   op2a, op2b);
+				   op2a, op2b, gsi);
   else
-    t = or_var_with_comparison_1 (stmt, code2, op2a, op2b);
+    t = or_var_with_comparison_1 (stmt, code2, op2a, op2b, gsi);
   return canonicalize_bool (t, invert);
 }
 
@@ -5975,7 +5882,8 @@  or_var_with_comparison (tree var, bool invert,
 
 static tree
 or_var_with_comparison_1 (gimple *stmt,
-			  enum tree_code code2, tree op2a, tree op2b)
+			  enum tree_code code2, tree op2a, tree op2b,
+			  gimple_stmt_iterator *gsi)
 {
   tree var = gimple_assign_lhs (stmt);
   tree true_test_var = NULL_TREE;
@@ -6008,9 +5916,7 @@  or_var_with_comparison_1 (gimple *stmt,
       tree t = or_comparisons_1 (innercode,
 				 gimple_assign_rhs1 (stmt),
 				 gimple_assign_rhs2 (stmt),
-				 code2,
-				 op2a,
-				 op2b);
+				 code2, op2a, op2b, gsi);
       if (t)
 	return t;
     }
@@ -6041,11 +5947,13 @@  or_var_with_comparison_1 (gimple *stmt,
       else if (inner1 == false_test_var)
 	return (is_or
 		? boolean_true_node
-		: or_var_with_comparison (inner2, false, code2, op2a, op2b));
+		: or_var_with_comparison (inner2, false, code2, op2a, op2b,
+					  gsi));
       else if (inner2 == false_test_var)
 	return (is_or
 		? boolean_true_node
-		: or_var_with_comparison (inner1, false, code2, op2a, op2b));
+		: or_var_with_comparison (inner1, false, code2, op2a, op2b,
+					  gsi));
       
       /* Next, redistribute/reassociate the OR across the inner tests.
 	 Compute the first partial result, (inner1 OR (op2a code op2b))  */
@@ -6055,7 +5963,7 @@  or_var_with_comparison_1 (gimple *stmt,
 	  && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s),
 					     gimple_assign_rhs1 (s),
 					     gimple_assign_rhs2 (s),
-					     code2, op2a, op2b)))
+					     code2, op2a, op2b, gsi)))
 	{
 	  /* Handle the OR case, where we are reassociating:
 	     (inner1 OR inner2) OR (op2a code2 op2b)
@@ -6087,7 +5995,7 @@  or_var_with_comparison_1 (gimple *stmt,
 	  && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s),
 					     gimple_assign_rhs1 (s),
 					     gimple_assign_rhs2 (s),
-					     code2, op2a, op2b)))
+					     code2, op2a, op2b, gsi)))
 	{
 	  /* Handle the OR case, where we are reassociating:
 	     (inner1 OR inner2) OR (op2a code2 op2b)
@@ -6142,7 +6050,8 @@  or_var_with_comparison_1 (gimple *stmt,
 
 static tree
 or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
-		  enum tree_code code2, tree op2a, tree op2b)
+		  enum tree_code code2, tree op2a, tree op2b,
+		  gimple_stmt_iterator *gsi)
 {
   tree truth_type = truth_type_for (TREE_TYPE (op1a));
 
@@ -6315,7 +6224,7 @@  or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 	{
 	case GIMPLE_ASSIGN:
 	  /* Try to simplify by copy-propagating the definition.  */
-	  return or_var_with_comparison (op1a, invert, code2, op2a, op2b);
+	  return or_var_with_comparison (op1a, invert, code2, op2a, op2b, gsi);
 
 	case GIMPLE_PHI:
 	  /* If every argument to the PHI produces the same result when
@@ -6366,7 +6275,7 @@  or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 					     gimple_bb (stmt)))
 			return NULL_TREE;
 		      temp = or_var_with_comparison (arg, invert, code2,
-						     op2a, op2b);
+						     op2a, op2b, gsi);
 		      if (!temp)
 			return NULL_TREE;
 		      else if (!result)
@@ -6396,16 +6305,18 @@  or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 
 tree
 maybe_fold_or_comparisons (enum tree_code code1, tree op1a, tree op1b,
-			   enum tree_code code2, tree op2a, tree op2b)
+			   enum tree_code code2, tree op2a, tree op2b,
+			   gimple_stmt_iterator *gsi)
 {
-  if (tree t = or_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b))
+  if (tree t = maybe_fold_comparisons_from_match_pd (BIT_IOR_EXPR, code1, op1a,
+						     op1b, code2, op2a, op2b,
+						     gsi))
     return t;
 
-  if (tree t = or_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b))
+  if (tree t = or_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b, gsi))
     return t;
 
-  if (tree t = maybe_fold_comparisons_from_match_pd (BIT_IOR_EXPR, code1, op1a,
-						     op1b, code2, op2a, op2b))
+  if (tree t = or_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b, gsi))
     return t;
 
   return NULL_TREE;
diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h
index 673d484ff52..3c2d19862a0 100644
--- a/gcc/gimple-fold.h
+++ b/gcc/gimple-fold.h
@@ -32,9 +32,11 @@  extern bool fold_stmt (gimple_stmt_iterator *);
 extern bool fold_stmt (gimple_stmt_iterator *, tree (*) (tree));
 extern bool fold_stmt_inplace (gimple_stmt_iterator *);
 extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, 
-					enum tree_code, tree, tree);
+					enum tree_code, tree, tree,
+					gimple_stmt_iterator *gsi);
 extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree,
-				       enum tree_code, tree, tree);
+				       enum tree_code, tree, tree,
+				       gimple_stmt_iterator *gsi);
 extern bool optimize_atomic_compare_exchange_p (gimple *);
 extern void fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *);
 extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree,
diff --git a/gcc/match.pd b/gcc/match.pd
index 28512d19b73..2c64c460fda 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1949,6 +1949,74 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      (if (eqne == NE_EXPR)
       { constant_boolean_node (true, type); })))))
 
+/* Convert (X == CST1) && (X OP2 CST2) to a known value
+   based on CST1 OP2 CST2.  Similarly for (X != CST1).  */
+
+(for code1 (eq ne)
+ (for code2 (eq ne lt gt le ge)
+  (for and (truth_and bit_and)
+   (simplify
+    (and:c (code1 @0 INTEGER_CST@1) (code2 @0 INTEGER_CST@2))
+     (with
+      {
+       int cmp = tree_int_cst_compare (@1, @2);
+       bool val;
+       switch (code2)
+	 {
+	 case EQ_EXPR: val = (cmp == 0); break;
+	 case NE_EXPR: val = (cmp != 0); break;
+	 case LT_EXPR: val = (cmp < 0); break;
+	 case GT_EXPR: val = (cmp > 0); break;
+	 case LE_EXPR: val = (cmp <= 0); break;
+	 case GE_EXPR: val = (cmp >= 0); break;
+	 default: gcc_unreachable ();
+	 }
+      }
+      (switch
+       (if (code1 == EQ_EXPR && val) (code1 @0 @1))
+       (if (code1 == EQ_EXPR && !val) { constant_boolean_node (false, type); })
+       (if (code1 == NE_EXPR && !val) (code2 @0 @2))))))))
+
+/* Convert (X OP1 CST1) && (X OP2 CST2).  */
+
+(for code1 (lt le gt ge)
+ (for code2 (lt le gt ge)
+  (for and (truth_and bit_and)
+   (simplify
+   (and (code1:c @0 INTEGER_CST@1) (code2:c @0 INTEGER_CST@2))
+    (with
+     {
+      int cmp = tree_int_cst_compare (@1, @2);
+     }
+     (switch
+      /* Chose the more restrictive of two < or <= comparisons.  */
+      (if ((code1 == LT_EXPR || code1 == LE_EXPR)
+	   && (code2 == LT_EXPR || code2 == LE_EXPR))
+       (if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR))
+	(code1 @0 @1)
+	(code2 @0 @2)))
+      /* Likewise chose the more restrictive of two > or >= comparisons.  */
+      (if ((code1 == GT_EXPR || code1 == GE_EXPR)
+	   && (code2 == GT_EXPR || code2 == GE_EXPR))
+       (if ((cmp > 0) || (cmp == 0 && code1 == GT_EXPR))
+	(code1 @0 @1)
+	(code2 @0 @2)))
+      /* Check for singleton ranges.  */
+      (if (cmp == 0
+	   && ((code1 == LE_EXPR && code2 == GE_EXPR)
+	       || (code1 == GE_EXPR && code2 == LE_EXPR)))
+       (eq @0 @1))
+      /* Check for disjoint ranges.  */
+      (if (cmp <= 0
+	   && (code1 == LT_EXPR || code1 == LE_EXPR)
+	   && (code2 == GT_EXPR || code2 == GE_EXPR))
+       { constant_boolean_node (false, type); })
+      (if (cmp >= 0
+	   && (code1 == GT_EXPR || code1 == GE_EXPR)
+	   && (code2 == LT_EXPR || code2 == LE_EXPR))
+       { constant_boolean_node (false, type); })
+      ))))))
+
 /* We can't reassociate at all for saturating types.  */
 (if (!TYPE_SATURATING (type))
 
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index da67e39e03a..459cba2f752 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -437,7 +437,7 @@  fold_or_predicates (location_t loc, tree c1, tree c2)
   if (code1 != ERROR_MARK && code2 != ERROR_MARK)
     {
       tree t = maybe_fold_or_comparisons (code1, op1a, op1b,
-					  code2, op2a, op2b);
+					  code2, op2a, op2b, NULL);
       if (t)
 	return t;
     }
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index f30816ace7b..92542817604 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -555,15 +555,16 @@  ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
 	return false;
       /* Don't return false so fast, try maybe_fold_or_comparisons?  */
 
+      gimple_stmt_iterator gsi = gsi_for_stmt (inner_cond);
       if (!(t = maybe_fold_and_comparisons (inner_cond_code,
 					    gimple_cond_lhs (inner_cond),
 					    gimple_cond_rhs (inner_cond),
 					    outer_cond_code,
 					    gimple_cond_lhs (outer_cond),
-					    gimple_cond_rhs (outer_cond))))
+					    gimple_cond_rhs (outer_cond),
+					    &gsi)))
 	{
 	  tree t1, t2;
-	  gimple_stmt_iterator gsi;
 	  bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
 	  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
 	    logical_op_non_short_circuit
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index df76e66bccf..ae0752bb371 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -2091,11 +2091,13 @@  eliminate_redundant_comparison (enum tree_code opcode,
       if (opcode == BIT_IOR_EXPR)
 	t = maybe_fold_or_comparisons (lcode, op1, op2,
 				       rcode, gimple_assign_rhs1 (def2),
-				       gimple_assign_rhs2 (def2));
+				       gimple_assign_rhs2 (def2),
+				       NULL);
       else
 	t = maybe_fold_and_comparisons (lcode, op1, op2,
 					rcode, gimple_assign_rhs1 (def2),
-					gimple_assign_rhs2 (def2));
+					gimple_assign_rhs2 (def2),
+					NULL);
       if (!t)
 	continue;
 
@@ -3834,9 +3836,10 @@  optimize_vec_cond_expr (tree_code opcode, vec<operand_entry *> *ops)
 
 	  tree comb;
 	  if (opcode == BIT_AND_EXPR)
-	    comb = maybe_fold_and_comparisons (cmp0, x0, y0, cmp1, x1, y1);
+	    comb = maybe_fold_and_comparisons (cmp0, x0, y0, cmp1, x1, y1,
+					       NULL);
 	  else if (opcode == BIT_IOR_EXPR)
-	    comb = maybe_fold_or_comparisons (cmp0, x0, y0, cmp1, x1, y1);
+	    comb = maybe_fold_or_comparisons (cmp0, x0, y0, cmp1, x1, y1, NULL);
 	  else
 	    gcc_unreachable ();
 	  if (comb == NULL)
-- 
2.23.0