[RFC,v1,03/10] RISC-V: Generate czero.eqz/nez on noce_try_store_flag_mask if-conversion
Checks
Commit Message
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
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
@@ -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)
@@ -3228,3 +3228,4 @@ (define_insn "riscv_prefetchi_<mode>"
(include "generic.md")
(include "sifive-7.md")
(include "vector.md")
+(include "zicond.md")
new file mode 100644
@@ -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")
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */