diff options
author | Guo Jie <guojie@loongson.cn> | 2024-12-30 10:38:35 +0800 |
---|---|---|
committer | Lulu Cheng <chenglulu@loongson.cn> | 2025-01-02 10:09:42 +0800 |
commit | 66b6e578d99ea20e2c67593be7a772d7710e05b2 (patch) | |
tree | 0db4275f0b7b9eb00b2f73a00d3ca3bba24388e4 | |
parent | 18d3b87b17fd6157e3aff64099a5bf84ea5f82f3 (diff) | |
download | gcc-66b6e578d99ea20e2c67593be7a772d7710e05b2.zip gcc-66b6e578d99ea20e2c67593be7a772d7710e05b2.tar.gz gcc-66b6e578d99ea20e2c67593be7a772d7710e05b2.tar.bz2 |
LoongArch: Adjust insn patterns for better combine
For some instruction patterns with commutative operands,
the order of operands needs to be adjusted to match the rules.
gcc/ChangeLog:
* config/loongarch/loongarch.md
(bytepick_d_<bytepick_imm>_rev): New combiner.
(bstrpick_alsl_paired): Reorder input operands.
gcc/testsuite/ChangeLog:
* gcc.target/loongarch/bstrpick_alsl_paired.c: New test.
* gcc.target/loongarch/bytepick_combine.c: New test.
-rw-r--r-- | gcc/config/loongarch/loongarch.md | 23 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/loongarch/bstrpick_alsl_paired.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/loongarch/bytepick_combine.c | 11 |
3 files changed, 49 insertions, 6 deletions
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 7a110ca..1c294d8 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -3111,13 +3111,14 @@ (define_insn "bstrpick_alsl_paired" [(set (match_operand:DI 0 "register_operand" "=&r") - (plus:DI (match_operand:DI 1 "register_operand" "r") - (and:DI (ashift:DI (match_operand:DI 2 "register_operand" "r") - (match_operand 3 "const_immalsl_operand" "")) - (match_operand 4 "immediate_operand" ""))))] + (plus:DI + (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r") + (match_operand 2 "const_immalsl_operand" "")) + (match_operand 3 "immediate_operand" "")) + (match_operand:DI 4 "register_operand" "r")))] "TARGET_64BIT - && ((INTVAL (operands[4]) >> INTVAL (operands[3])) == 0xffffffff)" - "bstrpick.d\t%0,%2,31,0\n\talsl.d\t%0,%0,%1,%3" + && ((INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff)" + "bstrpick.d\t%0,%1,31,0\n\talsl.d\t%0,%0,%4,%2" [(set_attr "type" "arith") (set_attr "mode" "DI") (set_attr "insn_count" "2")]) @@ -4221,6 +4222,16 @@ "bytepick.d\t%0,%1,%2,<bytepick_imm>" [(set_attr "mode" "DI")]) +(define_insn "bytepick_d_<bytepick_imm>_rev" + [(set (match_operand:DI 0 "register_operand" "=r") + (ior:DI (ashift (match_operand:DI 1 "register_operand" "r") + (const_int bytepick_d_ashift_amount)) + (lshiftrt (match_operand:DI 2 "register_operand" "r") + (const_int <bytepick_d_lshiftrt_amount>))))] + "TARGET_64BIT" + "bytepick.d\t%0,%2,%1,<bytepick_imm>" + [(set_attr "mode" "DI")]) + (define_insn "bitrev_4b" [(set (match_operand:SI 0 "register_operand" "=r") (unspec:SI [(match_operand:SI 1 "register_operand" "r")] diff --git a/gcc/testsuite/gcc.target/loongarch/bstrpick_alsl_paired.c b/gcc/testsuite/gcc.target/loongarch/bstrpick_alsl_paired.c new file mode 100644 index 0000000..0bca388 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/bstrpick_alsl_paired.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fdump-rtl-combine" } */ +/* { dg-final { scan-rtl-dump "{bstrpick_alsl_paired}" "combine" } } */ +/* { dg-final { scan-assembler-not "alsl.d\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,\\\$r0" } } */ + +struct SA +{ + const char *a; + unsigned int b : 16; + unsigned int c : 16; +}; + +extern struct SA SAs[]; + +void +test () +{ + unsigned int i; + for (i = 0; i < 100; i++) + SAs[i].c = i; +} diff --git a/gcc/testsuite/gcc.target/loongarch/bytepick_combine.c b/gcc/testsuite/gcc.target/loongarch/bytepick_combine.c new file mode 100644 index 0000000..2a88082 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/bytepick_combine.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "slli\\.d" } } */ +/* { dg-final { scan-assembler-not "srli\\.d" } } */ +/* { dg-final { scan-assembler-times "bytepick\\.d" 1 } } */ + +unsigned long +bytepick_d_n (unsigned long a, unsigned long b) +{ + return a >> 56 | b << 8; +} |