Re: [PATCH 4/5] Rewrite first part of or_comparisons_1 into match.pd.

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

> Hi.
> 
> Updated version of the patch that drops GENERIC
> support in TREE codes.

OK.

Thanks,
Richard.

Re: [PATCH 4/5] Rewrite first part of or_comparisons_1 into match.pd.

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

Updated version of the patch that drops GENERIC
support in TREE codes.

Martin
>From 725f04c781c3d9cc2108b075201fc9ac7afb9a44 Mon Sep 17 00:00:00 2001
From: Martin Liska 
Date: Fri, 6 Sep 2019 12:47:01 +0200
Subject: [PATCH 4/5] Rewrite first part of or_comparisons_1 into match.pd.

gcc/ChangeLog:

2019-09-09  Martin Liska  

	* gimple-fold.c (or_comparisons_1): Remove rules
	moved to ...
	* match.pd: ... here.
---
 gcc/gimple-fold.c | 87 +--
 gcc/match.pd  | 28 +++
 2 files changed, 29 insertions(+), 86 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 23891fed930..dc8e8eef45c 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6051,93 +6051,8 @@ or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
 {
   int cmp = tree_int_cst_compare (op1b, op2b);
 
-  /* If we have (op1a != op1b), we should either be able to
-	 return that or TRUE, depending on whether the constant op1b
-	 also satisfies the other comparison against op2b.  */
-  if (code1 == NE_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 boolean_true_node;
-	  else
-		return fold_build2 (code1, boolean_type_node, op1a, op1b);
-	}
-	}
-  /* Likewise if the second comparison is a != comparison.  */
-  else if (code2 == NE_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 boolean_true_node;
-	  else
-		return fold_build2 (code2, boolean_type_node, op2a, op2b);
-	}
-	}
-
-  /* See if an equality test is redundant with the other comparison.  */
-  else if (code1 == EQ_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 == EQ_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 less restrictive of two < or <= comparisons.  */
-  else if ((code1 == LT_EXPR || code1 == LE_EXPR)
+  if ((code1 == LT_EXPR || code1 == LE_EXPR)
 	   && (code2 == LT_EXPR || code2 == LE_EXPR))
 	{
 	  if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR))
diff --git a/gcc/match.pd b/gcc/match.pd
index ac80dd7dd15..c465eabbb89 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2024,6 +2024,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   { constant_boolean_node (false, 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)
+  (simplify
+   (bit_ior:c (code1@3 @0 INTEGER_CST@1) (code2@4 @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) @4)
+  (if (code1 == NE_EXPR && val) { constant_boolean_node (true, type); })
+  (if (code1 == NE_EXPR && !val) @3))
+
+
 /* We can't reassociate at all for saturating types.  */
 (if (!TYPE_SATURATING (type))
 
-- 
2.23.0



Re: [PATCH 4/5] Rewrite first part of or_comparisons_1 into match.pd.

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

There's slightly updated version of the patch where
I use @3 and @4 in match.pd.

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

Ready to be installed?
Thanks,
Martin
>From 997ed7390bb2897cf880b29d14d0e28e5f8873c2 Mon Sep 17 00:00:00 2001
From: Martin Liska 
Date: Fri, 6 Sep 2019 12:47:01 +0200
Subject: [PATCH 4/5] Rewrite first part of or_comparisons_1 into match.pd.

gcc/ChangeLog:

2019-09-09  Martin Liska  

	* gimple-fold.c (or_comparisons_1): Remove rules
	moved to ...
	* match.pd: ... here.
---
 gcc/gimple-fold.c | 87 +--
 gcc/match.pd  | 29 
 2 files changed, 30 insertions(+), 86 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 58235d613d3..5931cf3df0a 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6064,93 +6064,8 @@ or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
 {
   int cmp = tree_int_cst_compare (op1b, op2b);
 
-  /* If we have (op1a != op1b), we should either be able to
-	 return that or TRUE, depending on whether the constant op1b
-	 also satisfies the other comparison against op2b.  */
-  if (code1 == NE_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 boolean_true_node;
-	  else
-		return fold_build2 (code1, boolean_type_node, op1a, op1b);
-	}
-	}
-  /* Likewise if the second comparison is a != comparison.  */
-  else if (code2 == NE_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 boolean_true_node;
-	  else
-		return fold_build2 (code2, boolean_type_node, op2a, op2b);
-	}
-	}
-
-  /* See if an equality test is redundant with the other comparison.  */
-  else if (code1 == EQ_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 == EQ_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 less restrictive of two < or <= comparisons.  */
-  else if ((code1 == LT_EXPR || code1 == LE_EXPR)
+  if ((code1 == LT_EXPR || code1 == LE_EXPR)
 	   && (code2 == LT_EXPR || code2 == LE_EXPR))
 	{
 	  if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR))
diff --git a/gcc/match.pd b/gcc/match.pd
index 008b93d906f..0c706060055 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2035,6 +2035,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{ constant_boolean_node (false, 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 or (truth_or bit_ior)
+   (simplify
+(or:c (code1@3 @0 INTEGER_CST@1) (code2@4 @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) @4)
+   (if (code1 == NE_EXPR && val) { constant_boolean_node (true, type); })
+   (if (code1 == NE_EXPR && !val) @3)))
+
+
 /* We can't reassociate at all for saturating types.  */
 (if (!TYPE_SATURATING (type))
 
-- 
2.23.0



[PATCH 4/5] Rewrite first part of or_comparisons_1 into match.pd.

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

Next part if about transition of part of the OR patterns
into match.pd.

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

Ready to be installed?
Thanks,
Martin
>From 0cc83b72025d243e9e6ebaa9a85c68c17f9cd09a Mon Sep 17 00:00:00 2001
From: Martin Liska 
Date: Fri, 6 Sep 2019 12:47:01 +0200
Subject: [PATCH 4/5] Rewrite first part of or_comparisons_1 into match.pd.

gcc/ChangeLog:

2019-09-09  Martin Liska  

	* gimple-fold.c (or_comparisons_1): Remove rules
	moved to ...
	* match.pd: ... here.
---
 gcc/gimple-fold.c | 87 +--
 gcc/match.pd  | 29 
 2 files changed, 30 insertions(+), 86 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index f9971c004b7..e691780591c 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6088,93 +6088,8 @@ or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 {
   int cmp = tree_int_cst_compare (op1b, op2b);
 
-  /* If we have (op1a != op1b), we should either be able to
-	 return that or TRUE, depending on whether the constant op1b
-	 also satisfies the other comparison against op2b.  */
-  if (code1 == NE_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 boolean_true_node;
-	  else
-		return fold_build2 (code1, boolean_type_node, op1a, op1b);
-	}
-	}
-  /* Likewise if the second comparison is a != comparison.  */
-  else if (code2 == NE_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 boolean_true_node;
-	  else
-		return fold_build2 (code2, boolean_type_node, op2a, op2b);
-	}
-	}
-
-  /* See if an equality test is redundant with the other comparison.  */
-  else if (code1 == EQ_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 == EQ_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 less restrictive of two < or <= comparisons.  */
-  else if ((code1 == LT_EXPR || code1 == LE_EXPR)
+  if ((code1 == LT_EXPR || code1 == LE_EXPR)
 	   && (code2 == LT_EXPR || code2 == LE_EXPR))
 	{
 	  if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR))
diff --git a/gcc/match.pd b/gcc/match.pd
index 2c64c460fda..2923f5b4cbe 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2017,6 +2017,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{ constant_boolean_node (false, 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 or (truth_or bit_ior)
+   (simplify
+(or: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) (code2 @0 @2))
+   (if (code1 == NE_EXPR && val) { constant_boolean_node (true, type); })
+   (if (code1 == NE_EXPR && !val) (code1 @0 @1
+
+
 /* We can't reassociate at all for saturating types.  */
 (if (!TYPE_SATURATING (type))
 
-- 
2.23.0