https://gcc.gnu.org/g:6e925ba0a8b9619ed789a456b087755b488d66f1

commit r14-9986-g6e925ba0a8b9619ed789a456b087755b488d66f1
Author: Fei Gao <gao...@eswincomputing.com>
Date:   Mon Apr 15 06:33:17 2024 +0000

    optimize Zicond conditional select cases.
    
    When one of the two input operands is 0, ADD and IOR are functionally
    equivalent.
    ADD is slightly preferred over IOR because ADD has a higher likelihood
    of being implemented as a compressed instruction when compared to IOR.
    C.ADD uses the CR format with any of the 32 RVI registers availble,
    while C.OR uses the CA format with limit to just 8 of them.
    
    Conditional select, if zero case:
    rd = (rc == 0) ? rs1 : rs2
    
    before patch:
    
      czero.nez rd, rs1, rc
      czero.eqz rtmp, rs2, rc
      or rd, rd, rtmp
    
    after patch:
    
      czero.eqz rd, rs1, rc
      czero.nez rtmp, rs2, rc
      add rd, rd, rtmp
    
    Same trick applies for the conditional select, if non-zero case:
    rd = (rc != 0) ? rs1 : rs2
    
    gcc/ChangeLog:
    
            * config/riscv/riscv.cc (riscv_expand_conditional_move):
            replace or with add when expanding zicond if possible.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/zicond-prefer-add-to-or.c: New test.

Diff:
---
 gcc/config/riscv/riscv.cc                                |  2 +-
 gcc/testsuite/gcc.target/riscv/zicond-prefer-add-to-or.c | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 74445bc977c..0519e0679ed 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4709,7 +4709,7 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx 
cons, rtx alt)
                                  gen_rtx_IF_THEN_ELSE (mode, cond1,
                                                        CONST0_RTX (mode),
                                                        alt)));
-         riscv_emit_binary (IOR, dest, reg1, reg2);
+         riscv_emit_binary (PLUS, dest, reg1, reg2);
          return true;
        }
     }
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-prefer-add-to-or.c 
b/gcc/testsuite/gcc.target/riscv/zicond-prefer-add-to-or.c
new file mode 100644
index 00000000000..f3f7beb0b5e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-prefer-add-to-or.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d -mbranch-cost=4" { target { 
rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f -mbranch-cost=4" { target { 
rv32 } } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Og" "-Os" "-Oz"} } */
+
+long cond_select_if_zero(long a, long b, long c) {
+  return a == 0 ? c : b;
+}
+
+long cond_select_if_non_zero(long a, long b, long c) {
+  return a != 0 ? c : b;
+}
+
+/* { dg-final { scan-assembler-times {add\t}  2 } } */
+/* { dg-final { scan-assembler-not {or\t} } } */
+

Reply via email to