Due to RISC-V limitations on operations with big constants combine is failing to match such operations and is not being able to produce optimal code as it keeps splitting them. By pretending we can do those operations we can get more opportunities for simplification of surrounding instructions.
2022-12-06 Raphael Moreira Zinsly <rzin...@ventanamicro.com> Jeff Law <j...@ventanamicro.com> gcc/Changelog: PR target/95632 PR target/106602 * config/riscv/riscv.md: New pattern to simulate complex const_int loads. gcc/testsuite/ChangeLog: * gcc.target/riscv/pr95632.c: New test. * gcc.target/riscv/pr106602.c: Likewise. --- gcc/config/riscv/riscv.md | 16 ++++++++++++++++ gcc/testsuite/gcc.target/riscv/pr106602.c | 14 ++++++++++++++ gcc/testsuite/gcc.target/riscv/pr95632.c | 15 +++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/pr106602.c create mode 100644 gcc/testsuite/gcc.target/riscv/pr95632.c diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index df57e2b0b4a..0a9b5ec22b0 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1667,6 +1667,22 @@ MAX_MACHINE_MODE, &operands[3], TRUE); }) +;; Pretend to have the ability to load complex const_int in order to get +;; better code generation around them. +(define_insn_and_split "" + [(set (match_operand:GPR 0 "register_operand" "=r") + (match_operand:GPR 1 "splittable_const_int_operand" "i"))] + "cse_not_expected" + "#" + "&& 1" + [(const_int 0)] + +{ + riscv_move_integer (operands[0], operands[0], INTVAL (operands[1]), + <GPR:MODE>mode, TRUE); + DONE; +}) + ;; 64-bit integer moves (define_expand "movdi" diff --git a/gcc/testsuite/gcc.target/riscv/pr106602.c b/gcc/testsuite/gcc.target/riscv/pr106602.c new file mode 100644 index 00000000000..83b70877012 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr106602.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc" } */ + +unsigned long +foo2 (unsigned long a) +{ + return (unsigned long)(unsigned int) a << 6; +} + +/* { dg-final { scan-assembler-times "slli\t" 1 } } */ +/* { dg-final { scan-assembler-times "srli\t" 1 } } */ +/* { dg-final { scan-assembler-not "\tli\t" } } */ +/* { dg-final { scan-assembler-not "addi\t" } } */ +/* { dg-final { scan-assembler-not "and\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/pr95632.c b/gcc/testsuite/gcc.target/riscv/pr95632.c new file mode 100644 index 00000000000..bd316ab1d7b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr95632.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv32imafc -mabi=ilp32f" } */ + +unsigned short +foo (unsigned short crc) +{ + crc ^= 0x4002; + crc >>= 1; + crc |= 0x8000; + + return crc; +} + +/* { dg-final { scan-assembler-times "srli\t" 1 } } */ +/* { dg-final { scan-assembler-not "slli\t" } } */ -- 2.38.1