]> gcc.gnu.org Git - gcc.git/commitdiff
pru: Add cstore expansion patterns
authorDimitar Dimitrov <dimitar@dinux.eu>
Tue, 13 Jun 2023 19:20:13 +0000 (22:20 +0300)
committerDimitar Dimitrov <dimitar@dinux.eu>
Wed, 30 Aug 2023 18:55:56 +0000 (21:55 +0300)
Add cstore patterns for the two specific operations which can be
efficiently expanded using the UMIN instruction:
  X != 0
  X == 0
The rest of the operations are rejected, and left to be expanded
by the common expansion code.

PR target/106562

gcc/ChangeLog:

* config/pru/predicates.md (const_0_operand): New predicate.
(pru_cstore_comparison_operator): Ditto.
* config/pru/pru.md (cstore<mode>4): New pattern.
(cstoredi4): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/pru/pr106562-10.c: New test.
* gcc.target/pru/pr106562-11.c: New test.
* gcc.target/pru/pr106562-5.c: New test.
* gcc.target/pru/pr106562-6.c: New test.
* gcc.target/pru/pr106562-7.c: New test.
* gcc.target/pru/pr106562-8.c: New test.
* gcc.target/pru/pr106562-9.c: New test.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
gcc/config/pru/predicates.md
gcc/config/pru/pru.md
gcc/testsuite/gcc.target/pru/pr106562-10.c [new file with mode: 0644]
gcc/testsuite/gcc.target/pru/pr106562-11.c [new file with mode: 0644]
gcc/testsuite/gcc.target/pru/pr106562-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/pru/pr106562-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/pru/pr106562-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/pru/pr106562-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/pru/pr106562-9.c [new file with mode: 0644]

index e4a7fcf259bda7e007e28a90d50f65c7cc90bf31..faa0dbf9fb4119ac366210e9f9a6afd7c1d1ce2f 100644 (file)
   (and (match_code "const_int")
        (match_test "INTVAL (op) == 1")))
 
+(define_predicate "const_0_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) == 0")))
+
 ; Note: Always pass a valid mode!
 (define_predicate "const_ubyte_operand"
   (match_code "const_int")
 (define_predicate "pru_fp_comparison_operator"
   (match_code "eq,ne,lt,gt,le,ge"))
 
+;; TRUE for comparisons supported by PRU's cstore.
+(define_predicate "pru_cstore_comparison_operator"
+  (match_code "eq,ne,gtu"))
+
 ;; Return true if OP is a constant that contains only one 1 in its
 ;; binary representation.
 (define_predicate "single_one_operand"
index 6deb5ecfecb3687e4746d0ee0e25477492b3a20e..93ad7b6ad7e73e1b8a2db99edc4bbcb025765c22 100644 (file)
     gcc_unreachable ();
 })
 
+;; Emit efficient code for two specific cstore cases:
+;;   X == 0
+;;   X != 0
+;;
+;; These can be efficiently compiled on the PRU using the umin
+;; instruction.
+;;
+;; This expansion does not handle "X > 0 unsigned" and "X >= 1 unsigned"
+;; because it is assumed that those would have been replaced with the
+;; canonical "X != 0".
+(define_expand "cstore<mode>4"
+  [(set (match_operand:QISI 0 "register_operand")
+       (match_operator:QISI 1 "pru_cstore_comparison_operator"
+         [(match_operand:QISI 2 "register_operand")
+          (match_operand:QISI 3 "const_0_operand")]))]
+  ""
+{
+  const enum rtx_code op1code = GET_CODE (operands[1]);
+
+  /* Crash if OP1 is GTU.  It would mean that "X > 0 unsigned"
+     had not been canonicalized before calling this expansion.  */
+  gcc_assert (op1code == NE || op1code == EQ);
+  gcc_assert (CONST_INT_P (operands[3]) && INTVAL (operands[3]) == 0);
+
+  if (op1code == NE)
+    {
+      emit_insn (gen_umin<mode>3 (operands[0], operands[2], const1_rtx));
+      DONE;
+    }
+  else if (op1code == EQ)
+    {
+      rtx tmpval = gen_reg_rtx (<MODE>mode);
+      emit_insn (gen_umin<mode>3 (tmpval, operands[2], const1_rtx));
+      emit_insn (gen_xor<mode>3 (operands[0], tmpval, const1_rtx));
+      DONE;
+    }
+
+  gcc_unreachable ();
+})
+
+(define_expand "cstoredi4"
+  [(set (match_operand:SI 0 "register_operand")
+       (match_operator:SI 1 "pru_cstore_comparison_operator"
+         [(match_operand:DI 2 "register_operand")
+          (match_operand:DI 3 "const_0_operand")]))]
+  ""
+{
+  /* Combining the two SImode suboperands with IOR works only for
+     the currently supported set of cstoresi3 operations.  */
+  const enum rtx_code op1code = GET_CODE (operands[1]);
+  gcc_assert (op1code == NE || op1code == EQ);
+  gcc_assert (CONST_INT_P (operands[3]) && INTVAL (operands[3]) == 0);
+
+  rtx tmpval = gen_reg_rtx (SImode);
+  rtx src_lo = simplify_gen_subreg (SImode, operands[2], DImode, 0);
+  rtx src_hi = simplify_gen_subreg (SImode, operands[2], DImode, 4);
+  emit_insn (gen_iorsi3 (tmpval, src_lo, src_hi));
+  emit_insn (gen_cstoresi4 (operands[0], operands[1], tmpval, const0_rtx));
+
+  DONE;
+})
+
 ;
 ; Bit test branch
 
diff --git a/gcc/testsuite/gcc.target/pru/pr106562-10.c b/gcc/testsuite/gcc.target/pru/pr106562-10.c
new file mode 100644 (file)
index 0000000..7f0224c
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do assemble } */
+/* { dg-options "-Os" } */
+/* { dg-final { object-size text <= 16 } } */
+
+int test(long long a)
+{
+        return a == 0;
+}
diff --git a/gcc/testsuite/gcc.target/pru/pr106562-11.c b/gcc/testsuite/gcc.target/pru/pr106562-11.c
new file mode 100644 (file)
index 0000000..017aa49
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do assemble } */
+/* { dg-options "-Os" } */
+/* { dg-final { object-size text <= 12 } } */
+
+int test(unsigned long long a)
+{
+        return a > 0;
+}
diff --git a/gcc/testsuite/gcc.target/pru/pr106562-5.c b/gcc/testsuite/gcc.target/pru/pr106562-5.c
new file mode 100644 (file)
index 0000000..16d9dfa
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do assemble } */
+/* { dg-options "-Os" } */
+/* { dg-final { object-size text <= 8 } } */
+
+int test(int a)
+{
+        return a != 0;
+}
diff --git a/gcc/testsuite/gcc.target/pru/pr106562-6.c b/gcc/testsuite/gcc.target/pru/pr106562-6.c
new file mode 100644 (file)
index 0000000..59510d3
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do assemble } */
+/* { dg-options "-Os" } */
+/* { dg-final { object-size text <= 8 } } */
+
+int test(unsigned a)
+{
+        return a > 0;
+}
diff --git a/gcc/testsuite/gcc.target/pru/pr106562-7.c b/gcc/testsuite/gcc.target/pru/pr106562-7.c
new file mode 100644 (file)
index 0000000..ca833ef
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do assemble } */
+/* { dg-options "-Os" } */
+/* { dg-final { object-size text <= 8 } } */
+
+int test(unsigned a)
+{
+        return a >= 1;
+}
diff --git a/gcc/testsuite/gcc.target/pru/pr106562-8.c b/gcc/testsuite/gcc.target/pru/pr106562-8.c
new file mode 100644 (file)
index 0000000..2911d84
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do assemble } */
+/* { dg-options "-Os" } */
+/* { dg-final { object-size text <= 12 } } */
+
+int test(int a)
+{
+        return a == 0;
+}
diff --git a/gcc/testsuite/gcc.target/pru/pr106562-9.c b/gcc/testsuite/gcc.target/pru/pr106562-9.c
new file mode 100644 (file)
index 0000000..25ece1c
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do assemble } */
+/* { dg-options "-Os" } */
+/* { dg-final { object-size text <= 12 } } */
+
+int test(long long a)
+{
+        return a != 0;
+}
This page took 0.066178 seconds and 5 git commands to generate.