diff options
author | Xi Ruoyao <xry111@xry111.site> | 2024-02-25 20:44:34 +0800 |
---|---|---|
committer | Xi Ruoyao <xry111@xry111.site> | 2024-02-29 14:48:18 +0800 |
commit | aab1c5dcd23f014f39b127f74aecd04913945a7f (patch) | |
tree | 947c8edc3cebee9760d227ecc9f00d36fd456af2 /gcc | |
parent | c556ea076dcbfe2a3059dd0ad2e06a0b1d1fa89b (diff) | |
download | gcc-aab1c5dcd23f014f39b127f74aecd04913945a7f.zip gcc-aab1c5dcd23f014f39b127f74aecd04913945a7f.tar.gz gcc-aab1c5dcd23f014f39b127f74aecd04913945a7f.tar.bz2 |
LoongArch: Remove unneeded sign extension after crc/crcc instructions
The specification of crc/crcc instructions is clear that the output is
sign-extended to GRLEN. Add a define_insn to tell the compiler this
fact and allow it to remove the unneeded sign extension on crc/crcc
output. As crc/crcc instructions are usually used in a tight loop,
this should produce a significant performance gain.
gcc/ChangeLog:
* config/loongarch/loongarch.md
(loongarch_<crc>_w_<size>_w_extended): New define_insn.
gcc/testsuite/ChangeLog:
* gcc.target/loongarch/crc-sext.c: New test;
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/loongarch/loongarch.md | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/loongarch/crc-sext.c | 13 |
2 files changed, 24 insertions, 0 deletions
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 9646fa90..f3b5c64 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -4264,6 +4264,17 @@ [(set_attr "type" "unknown") (set_attr "mode" "<MODE>")]) +(define_insn "loongarch_<crc>_w_<size>_w_extended" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI + (unspec:SI [(match_operand:QHSD 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")] + CRC)))] + "TARGET_64BIT" + "<crc>.w.<size>.w\t%0,%1,%2" + [(set_attr "type" "unknown") + (set_attr "mode" "<MODE>")]) + ;; With normal or medium code models, if the only use of a pc-relative ;; address is for loading or storing a value, then relying on linker ;; relaxation is not better than emitting the machine instruction directly. diff --git a/gcc/testsuite/gcc.target/loongarch/crc-sext.c b/gcc/testsuite/gcc.target/loongarch/crc-sext.c new file mode 100644 index 0000000..9ade5a8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/crc-sext.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +/* +**my_crc: +** crc.w.d.w \$r4,\$r4,\$r5 +** jr \$r1 +*/ +int my_crc(long long dword, int crc) +{ + return __builtin_loongarch_crc_w_d_w(dword, crc); +} |