[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