On 7/19/23 04:11, Xiao Zeng wrote:
This patch completes the recognition of the basic semantics
defined in the spec, namely:

Conditional zero, if condition is equal to zero
   rd = (rs2 == 0) ? 0 : rs1
Conditional zero, if condition is non zero
   rd = (rs2 != 0) ? 0 : rs1

gcc/ChangeLog:

        * config/riscv/riscv.md: Include zicond.md
        * config/riscv/zicond.md: New file.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/zicond-primitiveSemantics.c: New test.
So as I mentioned earlier today, adjusting the insn condition to use rtx_equal_p seems to be the right way to go. Attached is a V2 of this patch that implements that. It was trivial enough to do that there's no need to break this patch down further.

I've pushed V2 to the trunk.

Thanks,
Jeff
commit 74290c664d1d4c067a996253fe505555ec671668
Author: Xiao Zeng <zengx...@eswincomputing.com>
Date:   Wed Jul 26 11:59:59 2023 -0600

    [PATCH 2/5] [RISC-V] Generate Zicond instruction for basic semantics
    
    This patch completes the recognition of the basic semantics
    defined in the spec, namely:
    
    Conditional zero, if condition is equal to zero
      rd = (rs2 == 0) ? 0 : rs1
    Conditional zero, if condition is non zero
      rd = (rs2 != 0) ? 0 : rs1
    
    gcc/ChangeLog:
    
            * config/riscv/riscv.md: Include zicond.md
            * config/riscv/zicond.md: New file.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/zicond-primitiveSemantics.c: New test.
    
            Co-authored-by: Philipp Tomsich <philipp.toms...@vrull.eu>
            Co-authored-by: Raphael Zinsly <rzin...@ventanamicro.com>
            Co-authored-by: Jeff Law <j...@ventanamicro.com>

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 24515bcf706..8d8fc93bb14 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3319,3 +3319,4 @@ (define_expand "msubhisi4"
 (include "sifive-7.md")
 (include "thead.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..723a22422e1
--- /dev/null
+++ b/gcc/config/riscv/zicond.md
@@ -0,0 +1,84 @@
+;; 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_code_attr nez [(eq "eqz") (ne "nez")])
+
+;; Zicond
+(define_insn "*czero.<eqz>.<GPR:mode><ANYI:mode>"
+  [(set (match_operand:GPR 0 "register_operand"                      "=r")
+        (if_then_else:GPR (eq_or_ne (match_operand:ANYI 1 "register_operand" 
"r")
+                                    (const_int 0))
+                          (match_operand:GPR 2 "register_operand"    "r")
+                          (const_int 0)))]
+  "TARGET_ZICOND"
+  "czero.<eqz>\t%0,%2,%1"
+)
+
+(define_insn "*czero.<nez>.<GPR:mode><ANYI:mode>"
+  [(set (match_operand:GPR 0 "register_operand"                     "=r")
+        (if_then_else:GPR (eq_or_ne (match_operand:ANYI 1 "register_operand" 
"r")
+                                    (const_int 0))
+                          (const_int 0)
+                          (match_operand:GPR 2 "register_operand"   "r")))]
+  "TARGET_ZICOND"
+  "czero.<nez>\t%0,%2,%1"
+)
+
+;; Special optimization under eq/ne in primitive semantics
+(define_insn "*czero.eqz.<GPR:mode><ANYI:mode>.opt1"
+  [(set (match_operand:GPR 0 "register_operand"                   "=r")
+        (if_then_else:GPR (eq (match_operand:ANYI 1 "register_operand" "r")
+                              (const_int 0))
+                          (match_operand:GPR 2 "register_operand" "1")
+                          (match_operand:GPR 3 "register_operand" "r")))]
+  "TARGET_ZICOND && rtx_equal_p (operands[1], operands[2])"
+  "czero.eqz\t%0,%3,%1"
+)
+
+(define_insn "*czero.eqz.<GPR:mode><ANYI:mode>.opt2"
+  [(set (match_operand:GPR 0 "register_operand"                   "=r")
+        (if_then_else:GPR (eq (match_operand:ANYI 1 "register_operand" "r")
+                              (const_int 0))
+                          (match_operand:GPR 2 "register_operand" "r")
+                          (match_operand:GPR 3 "register_operand" "1")))]
+  "TARGET_ZICOND && rtx_equal_p (operands[1],  operands[3])"
+  "czero.nez\t%0,%2,%1"
+)
+
+(define_insn "*czero.nez.<GPR:mode><ANYI:mode>.opt3"
+  [(set (match_operand:GPR 0 "register_operand"                   "=r")
+        (if_then_else:GPR (ne (match_operand:ANYI 1 "register_operand" "r")
+                              (const_int 0))
+                          (match_operand:GPR 2 "register_operand" "r")
+                          (match_operand:GPR 3 "register_operand" "1")))]
+  "TARGET_ZICOND && rtx_equal_p (operands[1], operands[3])"
+  "czero.eqz\t%0,%2,%1"
+)
+
+(define_insn "*czero.nez.<GPR:mode><ANYI:mode>.opt4"
+  [(set (match_operand:GPR 0 "register_operand"                   "=r")
+        (if_then_else:GPR (ne (match_operand:ANYI 1 "register_operand" "r")
+                              (const_int 0))
+                          (match_operand:GPR 2 "register_operand" "1")
+                          (match_operand:GPR 3 "register_operand" "r")))]
+  "TARGET_ZICOND && rtx_equal_p (operands[1], operands[2])"
+  "czero.nez\t%0,%3,%1"
+)
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics.c 
b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics.c
new file mode 100644
index 00000000000..76c5019a992
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0"} } */
+
+long primitiveSemantics_00(long a, long b) { return a == 0 ? 0 : b; }
+
+long primitiveSemantics_01(long a, long b) { return a != 0 ? 0 : b; }
+
+long primitiveSemantics_02(long a, long b) { return a == 0 ? b : 0; }
+
+long primitiveSemantics_03(long a, long b) { return a != 0 ? b : 0; }
+
+long primitiveSemantics_04(long a, long b) {
+  if (a)
+    b = 0;
+  return b;
+}
+
+long primitiveSemantics_05(long a, long b) {
+  if (!a)
+    b = 0;
+  return b;
+}
+
+int primitiveSemantics_06(int a, int b) { return a == 0 ? 0 : b; }
+
+int primitiveSemantics_07(int a, int b) { return a != 0 ? 0 : b; }
+
+int primitiveSemantics_08(int a, int b) { return a == 0 ? b : 0; }
+
+int primitiveSemantics_09(int a, int b) { return a != 0 ? b : 0; }
+
+int primitiveSemantics_10(int a, int b) {
+  if (a)
+    b = 0;
+  return b;
+}
+
+int primitiveSemantics_11(int a, int b) {
+  if (!a)
+    b = 0;
+  return b;
+}
+
+/* { dg-final { scan-assembler-times "czero.eqz" 6 } } */
+/* { dg-final { scan-assembler-times "czero.nez" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */

Reply via email to