[RFC,v1,03/10] RISC-V: Generate czero.eqz/nez on noce_try_store_flag_mask if-conversion

Message ID 20230210224150.2801962-4-philipp.tomsich@vrull.eu
State Changes Requested, archived
Delegated to: Jeff Law
Headers
Series RISC-V: Support the Zicond (conditional-operations) extension |

Commit Message

Philipp Tomsich Feb. 10, 2023, 10:41 p.m. UTC
  Adds a pattern to map the output of noce_try_store_flag_mask
if-conversion in the combiner onto vt.maskc<n>; the input patterns
supported are similar to the following:
  (set (reg/v/f:DI 75 [ <retval> ])
       (and:DI (neg:DI (ne:DI (reg:DI 82)
		       (const_int 0 [0])))
	       (reg/v/f:DI 75 [ <retval> ])))

To ensure that the combine-pass doesn't get confused about
profitability, we recognize the idiom as requiring a single
instruction when the Zicond extension is present.

gcc/ChangeLog:

	* config/riscv/riscv.cc (riscv_rtx_costs): Recongnize the idiom
	for conditional-zero as a single instruction for TARGET_ZICOND
	* config/riscv/riscv.md: Include zicond.md.
	* config/riscv/zicond.md: New file.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/zicond-ne-03.c: New test.
	* gcc.target/riscv/zicond-ne-04.c: New test.

Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
---

 gcc/config/riscv/riscv.cc                     | 15 ++++++++++
 gcc/config/riscv/riscv.md                     |  1 +
 gcc/config/riscv/zicond.md                    | 30 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/zicond-ne-03.c | 13 ++++++++
 gcc/testsuite/gcc.target/riscv/zicond-ne-04.c | 13 ++++++++
 5 files changed, 72 insertions(+)
 create mode 100644 gcc/config/riscv/zicond.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-ne-03.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-ne-04.c
  

Comments

Jeff Law April 20, 2023, 5:53 p.m. UTC | #1
On 2/10/23 15:41, Philipp Tomsich wrote:
> Adds a pattern to map the output of noce_try_store_flag_mask
> if-conversion in the combiner onto vt.maskc<n>; the input patterns
> supported are similar to the following:
>    (set (reg/v/f:DI 75 [ <retval> ])
>         (and:DI (neg:DI (ne:DI (reg:DI 82)
> 		       (const_int 0 [0])))
> 	       (reg/v/f:DI 75 [ <retval> ])))
> 
> To ensure that the combine-pass doesn't get confused about
> profitability, we recognize the idiom as requiring a single
> instruction when the Zicond extension is present.
> 
> gcc/ChangeLog:
> 
> 	* config/riscv/riscv.cc (riscv_rtx_costs): Recongnize the idiom
> 	for conditional-zero as a single instruction for TARGET_ZICOND
> 	* config/riscv/riscv.md: Include zicond.md.
> 	* config/riscv/zicond.md: New file.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/riscv/zicond-ne-03.c: New test.
> 	* gcc.target/riscv/zicond-ne-04.c: New test.
So as we've discussed earlier on the list.  Conceptually I think we've 
agreed that an if-then-else style of conditional zero is probably a 
better model.

So that will have some impact on this patch since it digs into the RTL 
looking for the (and (neg ...)) form.   But I don't think it changes 
anything conceptually in this patch, just the implementation details.

So I'm OK with this patch once it's updated for the updated form we want 
to be using.

jeff
  

Patch

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index e4d3e1a3229..7e69a652fc5 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2331,6 +2331,21 @@  riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
       return false;
 
     case AND:
+      /* czero.eqz/nez */
+      if ((TARGET_ZICOND)
+	  && mode == word_mode
+	  && GET_CODE (XEXP (x, 0)) == NEG)
+	{
+	  rtx inner = XEXP (XEXP (x, 0), 0);
+
+	  if ((GET_CODE (inner) == EQ || GET_CODE (inner) == NE)
+	      && CONST_INT_P (XEXP (inner, 1))
+	      && INTVAL (XEXP (inner, 1)) == 0)
+	    {
+	      *total = COSTS_N_INSNS (1);
+	      return true;
+	    }
+	}
       /* slli.uw pattern for zba.  */
       if (TARGET_ZBA && TARGET_64BIT && mode == DImode
 	  && GET_CODE (XEXP (x, 0)) == ASHIFT)
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index e8b5fc6644d..7c632bb4d65 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3228,3 +3228,4 @@  (define_insn "riscv_prefetchi_<mode>"
 (include "generic.md")
 (include "sifive-7.md")
 (include "vector.md")
+(include "zicond.md")
diff --git a/gcc/config/riscv/zicond.md b/gcc/config/riscv/zicond.md
new file mode 100644
index 00000000000..278e3a67802
--- /dev/null
+++ b/gcc/config/riscv/zicond.md
@@ -0,0 +1,30 @@ 
+;; Machine description for the RISC-V Zicond extension
+;; Copyright (C) 2022-23 Free Software Foundation, Inc.
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_code_iterator eq_or_ne [eq ne])
+(define_code_attr eqz [(eq "nez") (ne "eqz")])
+
+(define_insn "*czero.<eqz>"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(and:DI (neg:DI (eq_or_ne:DI
+			(match_operand:DI 1 "register_operand" "r")
+			(const_int 0)))
+		(match_operand:DI 2 "register_operand" "r")))]
+  "TARGET_ZICOND"
+  "czero.<eqz>\t%0,%2,%1")
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-ne-03.c b/gcc/testsuite/gcc.target/riscv/zicond-ne-03.c
new file mode 100644
index 00000000000..887b1273ce7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-ne-03.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64 -mtune=thead-c906" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" "-Os" "-Oz" } } */
+
+long long ne3(long long a, long long b)
+{
+  if (a != 0)
+    return b;
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-ne-04.c b/gcc/testsuite/gcc.target/riscv/zicond-ne-04.c
new file mode 100644
index 00000000000..6f6df06b4b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-ne-04.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64 -mtune=thead-c906" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+
+long long ne4(long long a, long long b)
+{
+  if (a != 0)
+    return 0;
+
+  return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.nez" 1 } } */