aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuo Jie <guojie@loongson.cn>2024-12-30 10:38:35 +0800
committerLulu Cheng <chenglulu@loongson.cn>2025-01-02 10:09:42 +0800
commit66b6e578d99ea20e2c67593be7a772d7710e05b2 (patch)
tree0db4275f0b7b9eb00b2f73a00d3ca3bba24388e4
parent18d3b87b17fd6157e3aff64099a5bf84ea5f82f3 (diff)
downloadgcc-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.md23
-rw-r--r--gcc/testsuite/gcc.target/loongarch/bstrpick_alsl_paired.c21
-rw-r--r--gcc/testsuite/gcc.target/loongarch/bytepick_combine.c11
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;
+}