diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 32183d63180f1af058eddccc96fc096858760dc6..2620e3e7b7905172548e71b29f265efb090f1812 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3555,7 +3555,7 @@ riscv_noce_conversion_profitable_p (rtx_insn *seq, this redundant zero extend operation counts towards the cost of the replacement sequence. Compensate for that by incrementing the cost of the original sequence as well as the maximum sequence cost - accordingly. */ + accordingly. Likewise for sign extension. */ rtx last_dest = NULL_RTX; for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn)) { @@ -3567,8 +3567,9 @@ riscv_noce_conversion_profitable_p (rtx_insn *seq, && GET_CODE (x) == SET) { rtx src = SET_SRC (x); + enum rtx_code code = GET_CODE (src); if (last_dest != NULL_RTX - && GET_CODE (src) == ZERO_EXTEND + && (code == SIGN_EXTEND || code == ZERO_EXTEND) && REG_P (XEXP (src, 0)) && REGNO (XEXP (src, 0)) == REGNO (last_dest)) { diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c b/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c new file mode 100644 index 0000000000000000000000000000000000000000..1a3e7104bd8c1b5ab25bf811ad443efe5c83f556 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext-sfb.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ +/* { dg-options "-march=rv32gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc -mtune=sifive-7-series -mbranch-cost=1 -fdump-rtl-ce1" { target { rv64 } } } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect short forward branch assembly like: + + snez a0,a0 + bne a1,zero,1f # movcc + mv a0,zero +1: + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" { xfail { rv32 && { any-opts "-O1" } } } } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */ +/* { dg-final { scan-assembler-times "\\sbne\\s\[^\\s\]+\\s# movcc\\s" 1 { xfail { rv32 && { any-opts "-O1" } } } } } */ +/* { dg-final { scan-assembler-not "\\sbeq\\s" { xfail { rv32 && { any-opts "-O1" } } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c b/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c new file mode 100644 index 0000000000000000000000000000000000000000..45b94704aaf6f17948f751b3f5097517855f109b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext-thead.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ +/* { dg-options "-march=rv64gc_xtheadcondmov -mtune=thead-c906 -mbranch-cost=1 -fdump-rtl-ce1" } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect branchless assembly like: + + snez a0,a0 + th.mveqz a0,zero,a1 + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */ +/* { dg-final { scan-assembler-times "\\s(?:th\\.mveqz|th\\.mvnez)\\s" 1 } } */ +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c b/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c new file mode 100644 index 0000000000000000000000000000000000000000..eac1e1376cb4e119b7f7bb6fe11dda3fa4608cbe --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext-ventana.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ +/* { dg-options "-march=rv64gc_xventanacondops -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect branchless assembly like: + + snez a0,a0 + vt.maskc a0,a0,a1 + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */ +/* { dg-final { scan-assembler-times "\\svt\\.maskc\\s" 1 } } */ +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c b/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c new file mode 100644 index 0000000000000000000000000000000000000000..a526b0c3d5a68570354f7abf2ce316d0dd534805 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext-zicond.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ +/* { dg-options "-march=rv64gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_zicond -mtune=rocket -mbranch-cost=3 -fdump-rtl-ce1" { target { rv32 } } } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect branchless assembly like: + + snez a0,a0 + czero.eqz a0,a0,a1 + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" { xfail { rv32 && { any-opts "-O1" "-Os" "-Oz" } } } } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 1 } } */ +/* { dg-final { scan-assembler-times "\\sczero\\.eqz\\s" 1 { xfail { rv32 && { any-opts "-O1" "-Os" "-Oz" } } } } } */ +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail { rv32 && { any-opts "-O1" "-Os" "-Oz" } } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/cset-sext.c b/gcc/testsuite/gcc.target/riscv/cset-sext.c new file mode 100644 index 0000000000000000000000000000000000000000..a1293cd62ea7eae5fd262a8603dd0732d303d383 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/cset-sext.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */ +/* { dg-options "-march=rv32gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc -mtune=sifive-5-series -mbranch-cost=6 -mmovcc -fdump-rtl-ce1" { target { rv64 } } } */ + +int +foo (long a, long b) +{ + if (!b) + return 0; + else if (a) + return 1; + else + return 0; +} + +/* Expect branchless assembly like: + + snez a1,a1 + neg a1,a1 + snez a0,a0 + and a0,a1,a0 + */ + +/* { dg-final { scan-rtl-dump-times "if-conversion succeeded through noce_try_cmove_arith" 1 "ce1" { xfail { rv32 && { any-opts "-O1" } } } } } */ +/* { dg-final { scan-assembler-times "\\ssnez\\s" 2 { xfail { rv32 && { any-opts "-O1" } } } } } */ +/* { dg-final { scan-assembler-not "\\s(?:beq|bne)\\s" { xfail { rv32 && { any-opts "-O1" } } } } } */