[llvm] 7d48a9e - [LoongArch] Support register-register-addressed GPR loads/stores

Weining Lu via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 9 04:18:52 PDT 2022


Author: WANG Xuerui
Date: 2022-08-09T19:13:36+08:00
New Revision: 7d48a9e1ae53ecdbb9a21c5cc0443aecb64479b4

URL: https://github.com/llvm/llvm-project/commit/7d48a9e1ae53ecdbb9a21c5cc0443aecb64479b4
DIFF: https://github.com/llvm/llvm-project/commit/7d48a9e1ae53ecdbb9a21c5cc0443aecb64479b4.diff

LOG: [LoongArch] Support register-register-addressed GPR loads/stores

Differential Revision: https://reviews.llvm.org/D131380

Added: 
    

Modified: 
    llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
    llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index de91086080665..3be06614871fc 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -857,6 +857,24 @@ defm : LdPat<zextloadi32, LD_WU, i64>;
 defm : LdPat<load, LD_D, i64>;
 } // Predicates = [IsLA64]
 
+// LA64 register-register-addressed loads
+let Predicates = [IsLA64] in {
+class RegRegLdPat<PatFrag LoadOp, LAInst Inst>
+  : Pat<(i64 (LoadOp (add BaseAddr:$rj, GPR:$rk))),
+        (Inst BaseAddr:$rj, GPR:$rk)>;
+
+def : RegRegLdPat<extloadi8, LDX_B>;
+def : RegRegLdPat<sextloadi8, LDX_B>;
+def : RegRegLdPat<zextloadi8, LDX_BU>;
+def : RegRegLdPat<extloadi16, LDX_H>;
+def : RegRegLdPat<sextloadi16, LDX_H>;
+def : RegRegLdPat<zextloadi16, LDX_HU>;
+def : RegRegLdPat<extloadi32, LDX_W>;
+def : RegRegLdPat<sextloadi32, LDX_W>;
+def : RegRegLdPat<zextloadi32, LDX_WU>;
+def : RegRegLdPat<load, LDX_D>;
+} // Predicates = [IsLA64]
+
 /// Stores
 
 multiclass StPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy,
@@ -875,6 +893,18 @@ defm : StPat<truncstorei32, ST_W, GPR, i64>;
 defm : StPat<store, ST_D, GPR, i64>;
 } // Predicates = [IsLA64]
 
+// LA64 register-register-addressed stores
+let Predicates = [IsLA64] in {
+class RegRegStPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy>
+  : Pat<(StoreOp (i64 StTy:$rd), (add BaseAddr:$rj, GPR:$rk)),
+        (Inst StTy:$rd, BaseAddr:$rj, GPR:$rk)>;
+
+def : RegRegStPat<truncstorei8, STX_B, GPR>;
+def : RegRegStPat<truncstorei16, STX_H, GPR>;
+def : RegRegStPat<truncstorei32, STX_W, GPR>;
+def : RegRegStPat<store, STX_D, GPR>;
+} // Predicates = [IsLA64]
+
 /// Atomic loads and stores
 
 def : Pat<(atomic_fence timm, timm), (DBAR 0)>;

diff  --git a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll
index 8894e3cac3fb3..e7b8769670552 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll
@@ -226,6 +226,183 @@ define i64 @ld_wu(ptr %a) nounwind {
   ret i64 %6
 }
 
+define i64 @ldx_b(ptr %a, i64 %idx) nounwind {
+; LA32-LABEL: ldx_b:
+; LA32:       # %bb.0:
+; LA32-NEXT:    add.w $a1, $a0, $a1
+; LA32-NEXT:    ld.b $a2, $a1, 0
+; LA32-NEXT:    ld.b $a0, $a0, 0
+; LA32-NEXT:    srai.w $a1, $a2, 31
+; LA32-NEXT:    move $a0, $a2
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: ldx_b:
+; LA64:       # %bb.0:
+; LA64-NEXT:    ldx.b $a1, $a0, $a1
+; LA64-NEXT:    ld.b $a0, $a0, 0
+; LA64-NEXT:    move $a0, $a1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i8, ptr %a, i64 %idx
+  %2 = load i8, ptr %1
+  %3 = sext i8 %2 to i64
+  %4 = load volatile i8, ptr %a
+  ret i64 %3
+}
+
+define i64 @ldx_h(ptr %a, i64 %idx) nounwind {
+; LA32-LABEL: ldx_h:
+; LA32:       # %bb.0:
+; LA32-NEXT:    slli.w $a1, $a1, 1
+; LA32-NEXT:    add.w $a1, $a0, $a1
+; LA32-NEXT:    ld.h $a2, $a1, 0
+; LA32-NEXT:    ld.h $a0, $a0, 0
+; LA32-NEXT:    srai.w $a1, $a2, 31
+; LA32-NEXT:    move $a0, $a2
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: ldx_h:
+; LA64:       # %bb.0:
+; LA64-NEXT:    slli.d $a1, $a1, 1
+; LA64-NEXT:    ldx.h $a1, $a0, $a1
+; LA64-NEXT:    ld.h $a0, $a0, 0
+; LA64-NEXT:    move $a0, $a1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i16, ptr %a, i64 %idx
+  %2 = load i16, ptr %1
+  %3 = sext i16 %2 to i64
+  %4 = load volatile i16, ptr %a
+  ret i64 %3
+}
+
+define i64 @ldx_w(ptr %a, i64 %idx) nounwind {
+; LA32-LABEL: ldx_w:
+; LA32:       # %bb.0:
+; LA32-NEXT:    slli.w $a1, $a1, 2
+; LA32-NEXT:    add.w $a1, $a0, $a1
+; LA32-NEXT:    ld.w $a2, $a1, 0
+; LA32-NEXT:    ld.w $a0, $a0, 0
+; LA32-NEXT:    srai.w $a1, $a2, 31
+; LA32-NEXT:    move $a0, $a2
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: ldx_w:
+; LA64:       # %bb.0:
+; LA64-NEXT:    slli.d $a1, $a1, 2
+; LA64-NEXT:    ldx.w $a1, $a0, $a1
+; LA64-NEXT:    ld.w $a0, $a0, 0
+; LA64-NEXT:    move $a0, $a1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i32, ptr %a, i64 %idx
+  %2 = load i32, ptr %1
+  %3 = sext i32 %2 to i64
+  %4 = load volatile i32, ptr %a
+  ret i64 %3
+}
+
+define i64 @ldx_d(ptr %a, i64 %idx) nounwind {
+; LA32-LABEL: ldx_d:
+; LA32:       # %bb.0:
+; LA32-NEXT:    slli.w $a1, $a1, 3
+; LA32-NEXT:    add.w $a1, $a0, $a1
+; LA32-NEXT:    ld.w $a2, $a1, 0
+; LA32-NEXT:    ld.w $a3, $a0, 0
+; LA32-NEXT:    ld.w $a1, $a1, 4
+; LA32-NEXT:    ld.w $a0, $a0, 4
+; LA32-NEXT:    move $a0, $a2
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: ldx_d:
+; LA64:       # %bb.0:
+; LA64-NEXT:    slli.d $a1, $a1, 3
+; LA64-NEXT:    ldx.d $a1, $a0, $a1
+; LA64-NEXT:    ld.d $a0, $a0, 0
+; LA64-NEXT:    move $a0, $a1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i64, ptr %a, i64 %idx
+  %2 = load i64, ptr %1
+  %3 = load volatile i64, ptr %a
+  ret i64 %2
+}
+
+define i64 @ldx_bu(ptr %a, i64 %idx) nounwind {
+; LA32-LABEL: ldx_bu:
+; LA32:       # %bb.0:
+; LA32-NEXT:    add.w $a1, $a0, $a1
+; LA32-NEXT:    ld.bu $a1, $a1, 0
+; LA32-NEXT:    ld.bu $a0, $a0, 0
+; LA32-NEXT:    add.w $a0, $a1, $a0
+; LA32-NEXT:    sltu $a1, $a0, $a1
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: ldx_bu:
+; LA64:       # %bb.0:
+; LA64-NEXT:    ldx.bu $a1, $a0, $a1
+; LA64-NEXT:    ld.bu $a0, $a0, 0
+; LA64-NEXT:    add.d $a0, $a1, $a0
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i8, ptr %a, i64 %idx
+  %2 = load i8, ptr %1
+  %3 = zext i8 %2 to i64
+  %4 = load volatile i8, ptr %a
+  %5 = zext i8 %4 to i64
+  %6 = add i64 %3, %5
+  ret i64 %6
+}
+
+define i64 @ldx_hu(ptr %a, i64 %idx) nounwind {
+; LA32-LABEL: ldx_hu:
+; LA32:       # %bb.0:
+; LA32-NEXT:    slli.w $a1, $a1, 1
+; LA32-NEXT:    add.w $a1, $a0, $a1
+; LA32-NEXT:    ld.hu $a1, $a1, 0
+; LA32-NEXT:    ld.hu $a0, $a0, 0
+; LA32-NEXT:    add.w $a0, $a1, $a0
+; LA32-NEXT:    sltu $a1, $a0, $a1
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: ldx_hu:
+; LA64:       # %bb.0:
+; LA64-NEXT:    slli.d $a1, $a1, 1
+; LA64-NEXT:    ldx.hu $a1, $a0, $a1
+; LA64-NEXT:    ld.hu $a0, $a0, 0
+; LA64-NEXT:    add.d $a0, $a1, $a0
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i16, ptr %a, i64 %idx
+  %2 = load i16, ptr %1
+  %3 = zext i16 %2 to i64
+  %4 = load volatile i16, ptr %a
+  %5 = zext i16 %4 to i64
+  %6 = add i64 %3, %5
+  ret i64 %6
+}
+
+define i64 @ldx_wu(ptr %a, i64 %idx) nounwind {
+; LA32-LABEL: ldx_wu:
+; LA32:       # %bb.0:
+; LA32-NEXT:    slli.w $a1, $a1, 2
+; LA32-NEXT:    add.w $a1, $a0, $a1
+; LA32-NEXT:    ld.w $a1, $a1, 0
+; LA32-NEXT:    ld.w $a0, $a0, 0
+; LA32-NEXT:    add.w $a0, $a1, $a0
+; LA32-NEXT:    sltu $a1, $a0, $a1
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: ldx_wu:
+; LA64:       # %bb.0:
+; LA64-NEXT:    slli.d $a1, $a1, 2
+; LA64-NEXT:    ldx.wu $a1, $a0, $a1
+; LA64-NEXT:    ld.wu $a0, $a0, 0
+; LA64-NEXT:    add.d $a0, $a1, $a0
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i32, ptr %a, i64 %idx
+  %2 = load i32, ptr %1
+  %3 = zext i32 %2 to i64
+  %4 = load volatile i32, ptr %a
+  %5 = zext i32 %4 to i64
+  %6 = add i64 %3, %5
+  ret i64 %6
+}
+
 ;; Check indexed and unindexed stores.
 
 define void @st_b(ptr %a, i8 %b) nounwind {
@@ -284,6 +461,77 @@ define void @st_d(ptr %a, i64 %b) nounwind {
   ret void
 }
 
+define void @stx_b(ptr %dst, i64 %idx, i8 %val) nounwind {
+; LA32-LABEL: stx_b:
+; LA32:       # %bb.0:
+; LA32-NEXT:    add.w $a0, $a0, $a1
+; LA32-NEXT:    st.b $a3, $a0, 0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: stx_b:
+; LA64:       # %bb.0:
+; LA64-NEXT:    stx.b $a2, $a0, $a1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i8, ptr %dst, i64 %idx
+  store i8 %val, ptr %1
+  ret void
+}
+
+define void @stx_h(ptr %dst, i64 %idx, i16 %val) nounwind {
+; LA32-LABEL: stx_h:
+; LA32:       # %bb.0:
+; LA32-NEXT:    slli.w $a1, $a1, 1
+; LA32-NEXT:    add.w $a0, $a0, $a1
+; LA32-NEXT:    st.h $a3, $a0, 0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: stx_h:
+; LA64:       # %bb.0:
+; LA64-NEXT:    slli.d $a1, $a1, 1
+; LA64-NEXT:    stx.h $a2, $a0, $a1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i16, ptr %dst, i64 %idx
+  store i16 %val, ptr %1
+  ret void
+}
+
+define void @stx_w(ptr %dst, i64 %idx, i32 %val) nounwind {
+; LA32-LABEL: stx_w:
+; LA32:       # %bb.0:
+; LA32-NEXT:    slli.w $a1, $a1, 2
+; LA32-NEXT:    add.w $a0, $a0, $a1
+; LA32-NEXT:    st.w $a3, $a0, 0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: stx_w:
+; LA64:       # %bb.0:
+; LA64-NEXT:    slli.d $a1, $a1, 2
+; LA64-NEXT:    stx.w $a2, $a0, $a1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i32, ptr %dst, i64 %idx
+  store i32 %val, ptr %1
+  ret void
+}
+
+define void @stx_d(ptr %dst, i64 %idx, i64 %val) nounwind {
+; LA32-LABEL: stx_d:
+; LA32:       # %bb.0:
+; LA32-NEXT:    slli.w $a1, $a1, 3
+; LA32-NEXT:    add.w $a0, $a0, $a1
+; LA32-NEXT:    st.w $a4, $a0, 4
+; LA32-NEXT:    st.w $a3, $a0, 0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: stx_d:
+; LA64:       # %bb.0:
+; LA64-NEXT:    slli.d $a1, $a1, 3
+; LA64-NEXT:    stx.d $a2, $a0, $a1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = getelementptr i64, ptr %dst, i64 %idx
+  store i64 %val, ptr %1
+  ret void
+}
+
 ;; Check load from and store to an i1 location.
 define i64 @load_sext_zext_anyext_i1(ptr %a) nounwind {
   ;; sextload i1


        


More information about the llvm-commits mailing list