If SImode reg is continuous left shifted twice, combine related
instruction to one.

gcc/ChangeLog:

        * config/loongarch/loongarch.md (extsv_ashlsi3):
          New template

gcc/testsuite/ChangeLog:

        * gcc.target/loongarch/slli-1.c: New test.
---
 gcc/config/loongarch/loongarch.md           | 13 +++++++++++++
 gcc/testsuite/gcc.target/loongarch/slli-1.c | 10 ++++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/slli-1.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index 19a22a93de3..1c62e5c02a1 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3048,6 +3048,19 @@ (define_insn "<optab>si3_extend"
   [(set_attr "type" "shift")
    (set_attr "mode" "SI")])
 
+(define_insn "extsv_ashlsi3"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (ashift:DI
+          (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
+                           (match_operand:SI 2 "const_uimm5_operand")
+                           (const_int 0))
+          (match_operand:SI 3 "const_uimm5_operand")))]
+  "TARGET_64BIT
+    &&(INTVAL (operands[2]) + INTVAL (operands[3])) == 0x20"
+  "slli.w\t%0,%1,%3"
+  [(set_attr "type" "shift")
+   (set_attr "mode" "SI")])
+
 (define_insn "*rotr<mode>3"
   [(set (match_operand:GPR 0 "register_operand" "=r,r")
        (rotatert:GPR (match_operand:GPR 1 "register_operand" "r,r")
diff --git a/gcc/testsuite/gcc.target/loongarch/slli-1.c 
b/gcc/testsuite/gcc.target/loongarch/slli-1.c
new file mode 100644
index 00000000000..891d6457b12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/slli-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (int x)
+{
+  return (x << 2) * 8;
+}
+
+/* { dg-final { scan-assembler-times "slli\.\[dw\]" 1} } */
-- 
2.20.1

Reply via email to