Hi, I've come across a question regarding the branch cost of gcc. In the link https://gcc.godbolt.org/z/hnddevd5h, gcc fails to recognize the optimization branch judgment, while llvm does. I eventually discovered that the value of the branch cost was too small. Moreover, in that link, if I add "-mbranch-cost=4" (a larger number can also be used) for gcc, the zicond extension functions properly. So, is it necessary to modify the branch cost for gcc? According to the source code, the default mtun is rocket, which has a branch cost of 3. I think it should be set to 4.
gcc/ChangeLog: * config/riscv/riscv.cc: Change the branch cost. gcc/testsuite/ChangeLog: * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c: New test. --- gcc/config/riscv/riscv.cc | 2 +- ...Semantics_compare_reg_reg_return_reg_reg.c | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 74462cc76a59..ecb73be3cbd5 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -458,7 +458,7 @@ static const struct riscv_tune_param rocket_tune_info = { {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */ {COSTS_N_INSNS (33), COSTS_N_INSNS (65)}, /* int_div */ 1, /* issue_rate */ - 3, /* branch_cost */ + 4, /* branch_cost */ 5, /* memory_cost */ 8, /* fmv_cost */ true, /* slow_unaligned_access */ diff --git a/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c new file mode 100644 index 000000000000..04365b08c7d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_reg_return_reg_reg.c @@ -0,0 +1,21 @@ +/* { 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" "-Og" "-Os" "-Oz" } } */ + +#define N 10000 + +int condition_reduction (int *a, int min_v) +{ + int last = 0; + + for (int i = 0; i < N; i++) + { + if (a[i] < min_v) + last = a[i]; + } + return last; +} + +/* { dg-final { scan-assembler-times {\mczero\.nez\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mczero\.eqz\M} 1 } } */ -- 2.43.0