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 00f3638c4ecf711edba9a92931a0835ab476c28c Mon Sep 17 00:00:00 2001
From: Martin Liska <mli...@suse.cz>
Date: Fri, 6 Sep 2019 12:59:36 +0200
Subject: [PATCH 5/5] Rewrite second part of or_comparisons_1 into match.pd.

gcc/ChangeLog:

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

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

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 5931cf3df0a..1c598564d5e 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6056,51 +6056,6 @@ or_comparisons_1 (tree type, 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);
-
-      /* Chose the less 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))
-	    return fold_build2 (code2, boolean_type_node, op2a, op2b);
-	  else
-	    return fold_build2 (code1, boolean_type_node, op1a, op1b);
-	}
-
-      /* Likewise chose the less 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 (code2, boolean_type_node, op2a, op2b);
-	  else
-	    return fold_build2 (code1, boolean_type_node, op1a, op1b);
-	}
-
-      /* Check for singleton ranges.  */
-      else if (cmp == 0
-	       && ((code1 == LT_EXPR && code2 == GT_EXPR)
-		   || (code1 == GT_EXPR && code2 == LT_EXPR)))
-	return fold_build2 (NE_EXPR, boolean_type_node, op1a, op2b);
-
-      /* Check for less/greater pairs that don't restrict the range at all.  */
-      else if (cmp >= 0
-	       && (code1 == LT_EXPR || code1 == LE_EXPR)
-	       && (code2 == GT_EXPR || code2 == GE_EXPR))
-	return boolean_true_node;
-      else if (cmp <= 0
-	       && (code1 == GT_EXPR || code1 == GE_EXPR)
-	       && (code2 == LT_EXPR || code2 == LE_EXPR))
-	return boolean_true_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.  */
diff --git a/gcc/match.pd b/gcc/match.pd
index 0c706060055..29486ee8ec9 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2063,6 +2063,45 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        (if (code1 == NE_EXPR && val) { constant_boolean_node (true, type); })
        (if (code1 == NE_EXPR && !val) @3)))))))
 
+/* Convert (X OP1 CST1) || (X OP2 CST2).  */
+
+(for code1 (lt le gt ge)
+ (for code2 (lt le gt ge)
+  (for or (truth_or bit_ior)
+   (simplify
+   (or (code1:c@3 @0 INTEGER_CST@1) (code2:c@4 @0 INTEGER_CST@2))
+    (with
+     {
+      int cmp = tree_int_cst_compare (@1, @2);
+     }
+     (switch
+      /* Choose 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))
+	@4
+	@3))
+      /* 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))
+	@4
+	@3))
+      /* Check for singleton ranges.  */
+      (if (cmp == 0
+	   && ((code1 == LT_EXPR && code2 == GT_EXPR)
+	       || (code1 == GT_EXPR && code2 == LT_EXPR)))
+       (ne @0 @2))
+      /* Check for disjoint ranges.  */
+      (if (cmp >= 0
+	   && (code1 == LT_EXPR || code1 == LE_EXPR)
+	   && (code2 == GT_EXPR || code2 == GE_EXPR))
+       { constant_boolean_node (true, type); })
+      (if (cmp <= 0
+	   && (code1 == GT_EXPR || code1 == GE_EXPR)
+	   && (code2 == LT_EXPR || code2 == LE_EXPR))
+       { constant_boolean_node (true, type); })
+      ))))))
 
 /* We can't reassociate at all for saturating types.  */
 (if (!TYPE_SATURATING (type))
-- 
2.23.0

Reply via email to