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.
This commit is contained in:
parent
c39dc5bb65
commit
6e925ba0a8
2 changed files with 17 additions and 1 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
16
gcc/testsuite/gcc.target/riscv/zicond-prefer-add-to-or.c
Normal file
16
gcc/testsuite/gcc.target/riscv/zicond-prefer-add-to-or.c
Normal file
|
@ -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} } } */
|
||||
|
Loading…
Add table
Reference in a new issue