[RISC-V] optimize Zicond conditional select cases.

Message ID 20240415063317.29372-1-gaofei@eswincomputing.com
State Committed
Commit 6e925ba0a8b9619ed789a456b087755b488d66f1
Headers
Series [RISC-V] optimize Zicond conditional select cases. |

Checks

Context Check Description
rivoscibot/toolchain-ci-rivos-lint success Lint passed
rivoscibot/toolchain-ci-rivos-apply-patch success Patch applied
rivoscibot/toolchain-ci-rivos-build--newlib-rv64gcv-lp64d-multilib success Build passed
rivoscibot/toolchain-ci-rivos-build--linux-rv64gcv-lp64d-multilib success Build passed
rivoscibot/toolchain-ci-rivos-build--newlib-rv64gc-lp64d-multilib success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Testing passed
rivoscibot/toolchain-ci-rivos-build--linux-rv64gc_zba_zbb_zbc_zbs-lp64d-non-multilib success Build passed
rivoscibot/toolchain-ci-rivos-build--linux-rv32gc_zba_zbb_zbc_zbs-ilp32d-non-multilib success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Testing passed
rivoscibot/toolchain-ci-rivos-test success Testing passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Testing passed

Commit Message

Fei Gao April 15, 2024, 6:33 a.m. UTC
  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

riscv-gnu-toolchain regression tests have been passed with no new failure.
---
 gcc/config/riscv/riscv.cc                        |  2 +-
 .../gcc.target/riscv/zicond-prefer-add-to-or.c   | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-prefer-add-to-or.c
  

Comments

Kito Cheng April 15, 2024, 12:58 p.m. UTC | #1
It's simple enough, so LGTM for trunk :)

Fei Gao <gaofei@eswincomputing.com> 於 2024年4月15日 週一 14:38 寫道:

> 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
>
> riscv-gnu-toolchain regression tests have been passed with no new failure.
> ---
>  gcc/config/riscv/riscv.cc                        |  2 +-
>  .../gcc.target/riscv/zicond-prefer-add-to-or.c   | 16 ++++++++++++++++
>  2 files changed, 17 insertions(+), 1 deletion(-)
>  create mode 100644
> gcc/testsuite/gcc.target/riscv/zicond-prefer-add-to-or.c
>
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index e5f00806bb9..93c736549c9 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} } } */
> +
> --
> 2.17.1
>
>
  
Jeff Law April 15, 2024, 1:04 p.m. UTC | #2
On 4/15/24 6:58 AM, Kito Cheng wrote:
> It's simple enough, so LGTM for trunk :)
We're already doing this internally.  I just hadn't submitted it due to 
being deep into stage4.

Jeff
  
Fei Gao April 16, 2024, 1:27 a.m. UTC | #3
On 2024-04-15 21:04  Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
>On 4/15/24 6:58 AM, Kito Cheng wrote:
>> It's simple enough, so LGTM for trunk :)
>We're already doing this internally.  I just hadn't submitted it due to
>being deep into stage4.
>
>Jeff 

Hi Jeff

Would you like me to commit it now or leave it to you with your bunch of optimizations in Zicond?

BR
Fei
  
Jeff Law April 16, 2024, 2:05 a.m. UTC | #4
On 4/15/24 7:27 PM, Fei Gao wrote:
> On 2024-04-15 21:04  Jeff Law <jeffreyalaw@gmail.com> wrote:
>>
>>
>>
>> On 4/15/24 6:58 AM, Kito Cheng wrote:
>>> It's simple enough, so LGTM for trunk :)
>> We're already doing this internally.  I just hadn't submitted it due to
>> being deep into stage4.
>>
>> Jeff
> 
> Hi Jeff
> 
> Would you like me to commit it now or leave it to you with your bunch of optimizations in Zicond?
Go ahead and commit it.  It's extremely low risk.

jeff
  
Fei Gao April 16, 2024, 5:50 a.m. UTC | #5
Committed. Thanks Kito and Jeff for the reveiw. 

BR
Fei
>
>
>On 4/15/24 7:27 PM, Fei Gao wrote:
>> On 2024-04-15 21:04  Jeff Law <jeffreyalaw@gmail.com> wrote:
>>>
>>>
>>>
>>> On 4/15/24 6:58 AM, Kito Cheng wrote:
>>>> It's simple enough, so LGTM for trunk :)
>>> We're already doing this internally.  I just hadn't submitted it due to
>>> being deep into stage4.
>>>
>>> Jeff
>>
>> Hi Jeff
>>
>> Would you like me to commit it now or leave it to you with your bunch of optimizations in Zicond?
>Go ahead and commit it.  It's extremely low risk.
>
>jeff
  

Patch

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index e5f00806bb9..93c736549c9 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} } } */
+