diff mbox series

simplify-rtx: simplify_logical_relational_operation

Message ID 41f35fcfc6a223396c9183019e981a302192576d.1573051916.git.segher@kernel.crashing.org
State New
Headers show
Series simplify-rtx: simplify_logical_relational_operation | expand

Commit Message

Segher Boessenkool Nov. 6, 2019, 3 p.m. UTC
This introduces simplify_logical_relational_operation.  Currently the
only thing implemented it can simplify is the IOR of two CONDs of the
same arguments.

Tested on powerpc64-linux {-m32,-m64}.

Is this okay for trunk?


Segher


2018-11-06  Segher Boessenkool  <segher@kernel.crashing.org>

	* simplify-rtx.c (comparison_to_mask): New function.
	(mask_to_comparison): New function.
	(simplify_logical_relational_operation): New function.
	(simplify_binary_operation_1): Call
	simplify_logical_relational_operation.

---
 gcc/simplify-rtx.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)

Comments

Jeff Law Nov. 6, 2019, 5:46 p.m. UTC | #1
On 11/6/19 8:00 AM, Segher Boessenkool wrote:
> This introduces simplify_logical_relational_operation.  Currently the
> only thing implemented it can simplify is the IOR of two CONDs of the
> same arguments.
> 
> Tested on powerpc64-linux {-m32,-m64}.
> 
> Is this okay for trunk?
> 
> 
> Segher
> 
> 
> 2018-11-06  Segher Boessenkool  <segher@kernel.crashing.org>
> 
> 	* simplify-rtx.c (comparison_to_mask): New function.
> 	(mask_to_comparison): New function.
> 	(simplify_logical_relational_operation): New function.
> 	(simplify_binary_operation_1): Call
> 	simplify_logical_relational_operation.
OK.

BTW, I think there's enough overlap between simplify-rtx and combine
that if you wanted to maintain simplify-rtx as well that I'd fully
support it.  Thoughts?

jeff
Segher Boessenkool Nov. 7, 2019, 10:10 p.m. UTC | #2
On Wed, Nov 06, 2019 at 10:46:06AM -0700, Jeff Law wrote:
> BTW, I think there's enough overlap between simplify-rtx and combine
> that if you wanted to maintain simplify-rtx as well that I'd fully
> support it.  Thoughts?

I'd be honoured, thanks for the offer!


Segher
diff mbox series

Patch

diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 9a70720..b2ba922 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2125,6 +2125,132 @@  simplify_associative_operation (enum rtx_code code, machine_mode mode,
   return 0;
 }
 
+/* Return a mask describing the COMPARISON.  */
+static int
+comparison_to_mask (enum rtx_code comparison)
+{
+  switch (comparison)
+    {
+    case LT:
+      return 8;
+    case GT:
+      return 4;
+    case EQ:
+      return 2;
+    case UNORDERED:
+      return 1;
+
+    case LTGT:
+      return 12;
+    case LE:
+      return 10;
+    case GE:
+      return 6;
+    case UNLT:
+      return 9;
+    case UNGT:
+      return 5;
+    case UNEQ:
+      return 3;
+
+    case ORDERED:
+      return 14;
+    case NE:
+      return 13;
+    case UNLE:
+      return 11;
+    case UNGE:
+      return 7;
+
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Return a comparison corresponding to the MASK.  */
+static enum rtx_code
+mask_to_comparison (int mask)
+{
+  switch (mask)
+    {
+    case 8:
+      return LT;
+    case 4:
+      return GT;
+    case 2:
+      return EQ;
+    case 1:
+      return UNORDERED;
+
+    case 12:
+      return LTGT;
+    case 10:
+      return LE;
+    case 6:
+      return GE;
+    case 9:
+      return UNLT;
+    case 5:
+      return UNGT;
+    case 3:
+      return UNEQ;
+
+    case 14:
+      return ORDERED;
+    case 13:
+      return NE;
+    case 11:
+      return UNLE;
+    case 7:
+      return UNGE;
+
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Simplify a logical operation CODE with result mode MODE, operating on OP0
+   and OP1, which should be both relational operations.  Return 0 if no such
+   simplification is possible.  */
+rtx
+simplify_logical_relational_operation (enum rtx_code code, machine_mode mode,
+				       rtx op0, rtx op1)
+{
+  /* We only handle IOR of two relational operations.  */
+  if (code != IOR)
+    return 0;
+
+  if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
+    return 0;
+
+  if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
+	&& rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
+    return 0;
+
+  enum rtx_code code0 = GET_CODE (op0);
+  enum rtx_code code1 = GET_CODE (op1);
+
+  /* We don't handle unsigned comparisons currently.  */
+  if (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU)
+    return 0;
+  if (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU)
+    return 0;
+
+  int mask0 = comparison_to_mask (code0);
+  int mask1 = comparison_to_mask (code1);
+
+  int mask = mask0 | mask1;
+
+  if (mask == 15)
+    return const_true_rtx;
+
+  code = mask_to_comparison (mask);
+
+  op0 = XEXP (op1, 0);
+  op1 = XEXP (op1, 1);
+
+  return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
+}
 
 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
    and OP1.  Return 0 if no simplification is possible.
@@ -2888,6 +3014,10 @@  simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
       tem = simplify_associative_operation (code, mode, op0, op1);
       if (tem)
 	return tem;
+
+      tem = simplify_logical_relational_operation (code, mode, op0, op1);
+      if (tem)
+	return tem;
       break;
 
     case XOR: