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. --- gcc/config/loongarch/loongarch.md | 23 ++++++++++++++----- .../loongarch/bstrpick_alsl_paired.c | 21 +++++++++++++++++ .../gcc.target/loongarch/bytepick_combine.c | 11 +++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/bstrpick_alsl_paired.c create mode 100644 gcc/testsuite/gcc.target/loongarch/bytepick_combine.c diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 7a110ca9de6..1c294d8088a 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -3111,13 +3111,14 @@ (define_insn "zero_extend_ashift" (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 @@ (define_insn "bytepick_d_<bytepick_imm>" "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 00000000000..0bca3886c32 --- /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 00000000000..2a880829ca5 --- /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; +} -- 2.20.1