[llvm-branch-commits] [llvm] [LoongArch] Load scalars into vector lane 0 with FLD/VLDREPL (PR #234119)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Oct 21 02:05:14 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-loongarch

Author: hev (heiher)

<details>
<summary>Changes</summary>

Inserting a loaded integer into lane 0 of an undefined vector, which is also how sub-128-bit vector loads are legalized, was lowered to a scalar load plus [X]VINSGR2VR. VINSGR2VR merges into its destination, so it carries a false dependency on the previous value of that register, and it needs a GPR-to-vector move.

Use FLD.{S/D} for 32/64-bit elements and [X]VLDREPL.{B/H} for 8/16-bit elements instead. They write the whole register in one instruction.

When the register allocator reuses one vector register for several such loads, the false dependency serializes otherwise independent chains. In the GSM autocorrelation loop (9 x i64 multiply-accumulate over i16 taps) on LA664:

  VF2: 0.953s -> 0.724s
  VF4: 1.446s -> 0.856s

---

Patch is 102.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/234119.diff


27 Files Affected:

- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+39) 
- (modified) llvm/test/CodeGen/LoongArch/lasx/broadcast-load.ll (+9-12) 
- (modified) llvm/test/CodeGen/LoongArch/lasx/build-vector.ll (+76-80) 
- (modified) llvm/test/CodeGen/LoongArch/lasx/scalar-load-to-vector.ll (+22-23) 
- (modified) llvm/test/CodeGen/LoongArch/lasx/vec-sext-invec-mask.ll (+20-32) 
- (modified) llvm/test/CodeGen/LoongArch/lasx/vec-sext.ll (+15-24) 
- (modified) llvm/test/CodeGen/LoongArch/lasx/vec-trunc-combine.ll (+4-6) 
- (modified) llvm/test/CodeGen/LoongArch/lasx/vec-zext.ll (+15-24) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/broadcast-load.ll (+9-12) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll (+32-36) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll (+30-36) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/scalar-load-to-vector.ll (+28-33) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-reduce-add.ll (+18-30) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-reduce-and.ll (+13-22) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-reduce-or.ll (+13-22) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-reduce-smax.ll (+15-24) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-reduce-smin.ll (+15-24) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-reduce-umax.ll (+15-24) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-reduce-umin.ll (+15-24) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-reduce-xor.ll (+13-22) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-sext.ll (+15-24) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-shuffle-any-ext.ll (+15-24) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-shuffle-sign-ext.ll (+12-20) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-trunc.ll (+14-22) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vec-zext.ll (+12-20) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vhaddw.ll (+8-12) 
- (modified) llvm/test/CodeGen/LoongArch/lsx/vhsubw.ll (+8-12) 


``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 1d01e76a5ebd2d..c5a390cf163ee9 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -4024,6 +4024,45 @@ LoongArchTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
   SDValue Op1 = Op.getOperand(1);
   SDValue Op2 = Op.getOperand(2);
 
+  // Lower inserting a loaded integer into lane 0 of an undefined vector as a
+  // vector load that writes the whole register: FLD.{S/D} for 32/64-bit
+  // elements and [X]VLDREPL.{B/H} for 8/16-bit ones. Unlike a scalar load +
+  // [X]VINSGR2VR, it has no false dependency on the previous value of the
+  // destination and doesn't need to move the value from a GPR.
+  // For example:
+  //   %a = load i64, ptr %ptr
+  //   %b = insert_vector_elt undef, %a, 0
+  // is lowered to:
+  //   (FLD_D $a0, 0)
+  if (Op0.isUndef() && isNullConstant(Op2) && EltVT.isInteger() &&
+      Op1.getOpcode() == ISD::LOAD && Op1.hasOneUse()) {
+    auto *LN = cast<LoadSDNode>(Op1);
+    auto ExtType = LN->getExtensionType();
+    if (LN->isSimple() &&
+        (ExtType == ISD::EXTLOAD || ExtType == ISD::NON_EXTLOAD) &&
+        LN->getMemoryVT().getSizeInBits() == EltSizeInBits) {
+      // Indexed loads and stores are not supported on LoongArch.
+      assert(LN->isUnindexed() && "Unexpected indexed load.");
+      SDValue Res;
+      if (EltSizeInBits >= 32) {
+        MVT FltVT = MVT::getFloatingPointVT(EltSizeInBits);
+        SDValue Ld = DAG.getLoad(FltVT, DL, LN->getChain(), LN->getBasePtr(),
+                                 LN->getMemOperand());
+        Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL,
+                          MVT::getVectorVT(FltVT, NumElts), Ld);
+        Res = DAG.getBitcast(VT, Res);
+        DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), Ld.getValue(1));
+      } else {
+        SDVTList Tys = DAG.getVTList(VT, MVT::Other);
+        SDValue Ops[] = {LN->getChain(), LN->getBasePtr()};
+        Res = DAG.getMemIntrinsicNode(LoongArchISD::VLDREPL, DL, Tys, Ops,
+                                      LN->getMemoryVT(), LN->getMemOperand());
+        DAG.ReplaceAllUsesOfValueWith(SDValue(LN, 1), Res.getValue(1));
+      }
+      return Res;
+    }
+  }
+
   if (isa<ConstantSDNode>(Op2))
     return Op;
 
diff --git a/llvm/test/CodeGen/LoongArch/lasx/broadcast-load.ll b/llvm/test/CodeGen/LoongArch/lasx/broadcast-load.ll
index 7407e0d5f4195d..7b622ee62bb540 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/broadcast-load.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/broadcast-load.ll
@@ -57,10 +57,9 @@ define <16 x i16> @should_not_be_optimized_zext_load(ptr %ptr) {
 define <4 x i64> @xvldrepl_d_unaligned_offset(ptr %ptr) {
 ; LA32-LABEL: xvldrepl_d_unaligned_offset:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ld.w $a1, $a0, 4
-; LA32-NEXT:    ld.w $a0, $a0, 8
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 0
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT:    ld.w $a1, $a0, 8
+; LA32-NEXT:    fld.s $fa0, $a0, 4
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 1
 ; LA32-NEXT:    xvreplve0.d $xr0, $xr0
 ; LA32-NEXT:    ret
 ;
@@ -150,10 +149,9 @@ define <8 x i32> @xvldrepl_w_offset(ptr %ptr) {
 define <4 x i64> @xvldrepl_d(ptr %ptr) {
 ; LA32-LABEL: xvldrepl_d:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ld.w $a1, $a0, 0
-; LA32-NEXT:    ld.w $a0, $a0, 4
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 0
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT:    ld.w $a1, $a0, 4
+; LA32-NEXT:    fld.s $fa0, $a0, 0
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 1
 ; LA32-NEXT:    xvreplve0.d $xr0, $xr0
 ; LA32-NEXT:    ret
 ;
@@ -170,10 +168,9 @@ define <4 x i64> @xvldrepl_d(ptr %ptr) {
 define <4 x i64> @xvldrepl_d_offset(ptr %ptr) {
 ; LA32-LABEL: xvldrepl_d_offset:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ld.w $a1, $a0, 264
-; LA32-NEXT:    ld.w $a0, $a0, 268
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 0
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT:    ld.w $a1, $a0, 268
+; LA32-NEXT:    fld.s $fa0, $a0, 264
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 1
 ; LA32-NEXT:    xvreplve0.d $xr0, $xr0
 ; LA32-NEXT:    ret
 ;
diff --git a/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll b/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll
index d09ef0e2c6ac0d..9da1ca4e80aa1b 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll
@@ -380,38 +380,37 @@ entry:
 define void @buildvector_v32i8(ptr %dst, i8 %a0, i8 %a1, i8 %a2, i8 %a3, i8 %a4, i8 %a5, i8 %a6, i8 %a7, i8 %a8, i8 %a9, i8 %a10, i8 %a11, i8 %a12, i8 %a13, i8 %a14, i8 %a15, i8 %a16, i8 %a17, i8 %a18, i8 %a19, i8 %a20, i8 %a21, i8 %a22, i8 %a23, i8 %a24, i8 %a25, i8 %a26, i8 %a27, i8 %a28, i8 %a29, i8 %a30, i8 %a31) nounwind {
 ; LA32-LABEL: buildvector_v32i8:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    ld.b $t0, $sp, 36
+; LA32-NEXT:    ld.b $t0, $sp, 40
+; LA32-NEXT:    vldrepl.b $vr0, $sp, 36
 ; LA32-NEXT:    ld.b $t1, $sp, 92
-; LA32-NEXT:    ld.b $t2, $sp, 40
-; LA32-NEXT:    ld.b $t3, $sp, 44
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 0
-; LA32-NEXT:    ld.b $t0, $sp, 48
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 1
-; LA32-NEXT:    ld.b $t2, $sp, 52
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t3, 2
-; LA32-NEXT:    ld.b $t3, $sp, 56
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 3
-; LA32-NEXT:    ld.b $t0, $sp, 60
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 4
-; LA32-NEXT:    ld.b $t2, $sp, 64
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t3, 5
-; LA32-NEXT:    ld.b $t3, $sp, 68
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 6
-; LA32-NEXT:    ld.b $t0, $sp, 72
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 7
-; LA32-NEXT:    ld.b $t2, $sp, 76
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t3, 8
-; LA32-NEXT:    ld.b $t3, $sp, 80
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 9
-; LA32-NEXT:    ld.b $t0, $sp, 84
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 10
-; LA32-NEXT:    ld.b $t2, $sp, 88
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t3, 11
-; LA32-NEXT:    ld.b $t3, $sp, 96
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 12
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 13
+; LA32-NEXT:    ld.b $t2, $sp, 44
+; LA32-NEXT:    ld.b $t3, $sp, 48
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 1
+; LA32-NEXT:    ld.b $t0, $sp, 52
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 2
+; LA32-NEXT:    ld.b $t2, $sp, 56
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t3, 3
+; LA32-NEXT:    ld.b $t3, $sp, 60
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 4
+; LA32-NEXT:    ld.b $t0, $sp, 64
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 5
+; LA32-NEXT:    ld.b $t2, $sp, 68
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t3, 6
+; LA32-NEXT:    ld.b $t3, $sp, 72
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 7
+; LA32-NEXT:    ld.b $t0, $sp, 76
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 8
+; LA32-NEXT:    ld.b $t2, $sp, 80
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t3, 9
+; LA32-NEXT:    ld.b $t3, $sp, 84
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 10
+; LA32-NEXT:    ld.b $t0, $sp, 88
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 11
+; LA32-NEXT:    ld.b $t2, $sp, 96
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t3, 12
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t0, 13
 ; LA32-NEXT:    vinsgr2vr.b $vr0, $t1, 14
-; LA32-NEXT:    vinsgr2vr.b $vr0, $t3, 15
+; LA32-NEXT:    vinsgr2vr.b $vr0, $t2, 15
 ; LA32-NEXT:    vinsgr2vr.b $vr1, $a1, 0
 ; LA32-NEXT:    vinsgr2vr.b $vr1, $a2, 1
 ; LA32-NEXT:    vinsgr2vr.b $vr1, $a3, 2
@@ -443,38 +442,37 @@ define void @buildvector_v32i8(ptr %dst, i8 %a0, i8 %a1, i8 %a2, i8 %a3, i8 %a4,
 ;
 ; LA64-LABEL: buildvector_v32i8:
 ; LA64:       # %bb.0: # %entry
-; LA64-NEXT:    ld.b $t0, $sp, 72
+; LA64-NEXT:    ld.b $t0, $sp, 80
+; LA64-NEXT:    vldrepl.b $vr0, $sp, 72
 ; LA64-NEXT:    ld.b $t1, $sp, 184
-; LA64-NEXT:    ld.b $t2, $sp, 80
-; LA64-NEXT:    ld.b $t3, $sp, 88
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 0
-; LA64-NEXT:    ld.b $t0, $sp, 96
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 1
-; LA64-NEXT:    ld.b $t2, $sp, 104
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t3, 2
-; LA64-NEXT:    ld.b $t3, $sp, 112
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 3
-; LA64-NEXT:    ld.b $t0, $sp, 120
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 4
-; LA64-NEXT:    ld.b $t2, $sp, 128
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t3, 5
-; LA64-NEXT:    ld.b $t3, $sp, 136
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 6
-; LA64-NEXT:    ld.b $t0, $sp, 144
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 7
-; LA64-NEXT:    ld.b $t2, $sp, 152
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t3, 8
-; LA64-NEXT:    ld.b $t3, $sp, 160
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 9
-; LA64-NEXT:    ld.b $t0, $sp, 168
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 10
-; LA64-NEXT:    ld.b $t2, $sp, 176
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t3, 11
-; LA64-NEXT:    ld.b $t3, $sp, 192
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 12
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 13
+; LA64-NEXT:    ld.b $t2, $sp, 88
+; LA64-NEXT:    ld.b $t3, $sp, 96
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 1
+; LA64-NEXT:    ld.b $t0, $sp, 104
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 2
+; LA64-NEXT:    ld.b $t2, $sp, 112
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t3, 3
+; LA64-NEXT:    ld.b $t3, $sp, 120
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 4
+; LA64-NEXT:    ld.b $t0, $sp, 128
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 5
+; LA64-NEXT:    ld.b $t2, $sp, 136
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t3, 6
+; LA64-NEXT:    ld.b $t3, $sp, 144
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 7
+; LA64-NEXT:    ld.b $t0, $sp, 152
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 8
+; LA64-NEXT:    ld.b $t2, $sp, 160
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t3, 9
+; LA64-NEXT:    ld.b $t3, $sp, 168
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 10
+; LA64-NEXT:    ld.b $t0, $sp, 176
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 11
+; LA64-NEXT:    ld.b $t2, $sp, 192
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t3, 12
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t0, 13
 ; LA64-NEXT:    vinsgr2vr.b $vr0, $t1, 14
-; LA64-NEXT:    vinsgr2vr.b $vr0, $t3, 15
+; LA64-NEXT:    vinsgr2vr.b $vr0, $t2, 15
 ; LA64-NEXT:    vinsgr2vr.b $vr1, $a1, 0
 ; LA64-NEXT:    vinsgr2vr.b $vr1, $a2, 1
 ; LA64-NEXT:    vinsgr2vr.b $vr1, $a3, 2
@@ -1040,16 +1038,15 @@ define void @buildvector_v16i16(ptr %dst, i16 %a0, i16 %a1, i16 %a2, i16 %a3, i1
 ; LA32-NEXT:    ld.h $t1, $sp, 32
 ; LA32-NEXT:    ld.h $t2, $sp, 28
 ; LA32-NEXT:    ld.h $t3, $sp, 24
-; LA32-NEXT:    ld.h $t4, $sp, 20
-; LA32-NEXT:    ld.h $t5, $sp, 4
-; LA32-NEXT:    ld.h $t6, $sp, 8
-; LA32-NEXT:    ld.h $t7, $sp, 12
-; LA32-NEXT:    ld.h $t8, $sp, 16
-; LA32-NEXT:    vinsgr2vr.h $vr0, $t5, 0
-; LA32-NEXT:    vinsgr2vr.h $vr0, $t6, 1
-; LA32-NEXT:    vinsgr2vr.h $vr0, $t7, 2
-; LA32-NEXT:    vinsgr2vr.h $vr0, $t8, 3
-; LA32-NEXT:    vinsgr2vr.h $vr0, $t4, 4
+; LA32-NEXT:    ld.h $t4, $sp, 8
+; LA32-NEXT:    vldrepl.h $vr0, $sp, 4
+; LA32-NEXT:    ld.h $t5, $sp, 12
+; LA32-NEXT:    ld.h $t6, $sp, 16
+; LA32-NEXT:    ld.h $t7, $sp, 20
+; LA32-NEXT:    vinsgr2vr.h $vr0, $t4, 1
+; LA32-NEXT:    vinsgr2vr.h $vr0, $t5, 2
+; LA32-NEXT:    vinsgr2vr.h $vr0, $t6, 3
+; LA32-NEXT:    vinsgr2vr.h $vr0, $t7, 4
 ; LA32-NEXT:    vinsgr2vr.h $vr0, $t3, 5
 ; LA32-NEXT:    vinsgr2vr.h $vr0, $t2, 6
 ; LA32-NEXT:    vinsgr2vr.h $vr0, $t1, 7
@@ -1071,16 +1068,15 @@ define void @buildvector_v16i16(ptr %dst, i16 %a0, i16 %a1, i16 %a2, i16 %a3, i1
 ; LA64-NEXT:    ld.h $t1, $sp, 64
 ; LA64-NEXT:    ld.h $t2, $sp, 56
 ; LA64-NEXT:    ld.h $t3, $sp, 48
-; LA64-NEXT:    ld.h $t4, $sp, 40
-; LA64-NEXT:    ld.h $t5, $sp, 8
-; LA64-NEXT:    ld.h $t6, $sp, 16
-; LA64-NEXT:    ld.h $t7, $sp, 24
-; LA64-NEXT:    ld.h $t8, $sp, 32
-; LA64-NEXT:    vinsgr2vr.h $vr0, $t5, 0
-; LA64-NEXT:    vinsgr2vr.h $vr0, $t6, 1
-; LA64-NEXT:    vinsgr2vr.h $vr0, $t7, 2
-; LA64-NEXT:    vinsgr2vr.h $vr0, $t8, 3
-; LA64-NEXT:    vinsgr2vr.h $vr0, $t4, 4
+; LA64-NEXT:    ld.h $t4, $sp, 16
+; LA64-NEXT:    vldrepl.h $vr0, $sp, 8
+; LA64-NEXT:    ld.h $t5, $sp, 24
+; LA64-NEXT:    ld.h $t6, $sp, 32
+; LA64-NEXT:    ld.h $t7, $sp, 40
+; LA64-NEXT:    vinsgr2vr.h $vr0, $t4, 1
+; LA64-NEXT:    vinsgr2vr.h $vr0, $t5, 2
+; LA64-NEXT:    vinsgr2vr.h $vr0, $t6, 3
+; LA64-NEXT:    vinsgr2vr.h $vr0, $t7, 4
 ; LA64-NEXT:    vinsgr2vr.h $vr0, $t3, 5
 ; LA64-NEXT:    vinsgr2vr.h $vr0, $t2, 6
 ; LA64-NEXT:    vinsgr2vr.h $vr0, $t1, 7
diff --git a/llvm/test/CodeGen/LoongArch/lasx/scalar-load-to-vector.ll b/llvm/test/CodeGen/LoongArch/lasx/scalar-load-to-vector.ll
index 34aba5aa829258..4a750298e5ccca 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/scalar-load-to-vector.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/scalar-load-to-vector.ll
@@ -7,8 +7,7 @@
 define <32 x i8> @load_to_32xi8(ptr %p) {
 ; CHECK-LABEL: load_to_32xi8:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    ld.b $a0, $a0, 0
-; CHECK-NEXT:    vinsgr2vr.b $vr0, $a0, 0
+; CHECK-NEXT:    vldrepl.b $vr0, $a0, 0
 ; CHECK-NEXT:    ret
   %v = load i8, ptr %p
   %ret = insertelement <32 x i8> poison, i8 %v, i32 0
@@ -18,8 +17,7 @@ define <32 x i8> @load_to_32xi8(ptr %p) {
 define <16 x i16> @load_to_16xi16(ptr %p) {
 ; CHECK-LABEL: load_to_16xi16:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    ld.h $a0, $a0, 0
-; CHECK-NEXT:    vinsgr2vr.h $vr0, $a0, 0
+; CHECK-NEXT:    vldrepl.h $vr0, $a0, 0
 ; CHECK-NEXT:    ret
   %v = load i16, ptr %p
   %ret = insertelement <16 x i16> poison, i16 %v, i32 0
@@ -29,8 +27,7 @@ define <16 x i16> @load_to_16xi16(ptr %p) {
 define <8 x i32> @load_to_8xi32(ptr %p) {
 ; CHECK-LABEL: load_to_8xi32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    ld.w $a0, $a0, 0
-; CHECK-NEXT:    vinsgr2vr.w $vr0, $a0, 0
+; CHECK-NEXT:    fld.s $fa0, $a0, 0
 ; CHECK-NEXT:    ret
   %v = load i32, ptr %p
   %ret = insertelement <8 x i32> poison, i32 %v, i32 0
@@ -40,16 +37,14 @@ define <8 x i32> @load_to_8xi32(ptr %p) {
 define <4 x i64> @load_to_4xi64(ptr %p) {
 ; LA32-LABEL: load_to_4xi64:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ld.w $a1, $a0, 0
-; LA32-NEXT:    ld.w $a0, $a0, 4
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 0
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT:    ld.w $a1, $a0, 4
+; LA32-NEXT:    fld.s $fa0, $a0, 0
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 1
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_to_4xi64:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ld.d $a0, $a0, 0
-; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0
+; LA64-NEXT:    fld.d $fa0, $a0, 0
 ; LA64-NEXT:    ret
   %v = load i64, ptr %p
   %ret = insertelement <4 x i64> poison, i64 %v, i32 0
@@ -58,11 +53,17 @@ define <4 x i64> @load_to_4xi64(ptr %p) {
 
 ;; Offsets that aren't a multiple of the element size.
 define <16 x i16> @load_to_16xi16_offset(ptr %p) {
-; CHECK-LABEL: load_to_16xi16_offset:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    ld.h $a0, $a0, -3
-; CHECK-NEXT:    vinsgr2vr.h $vr0, $a0, 0
-; CHECK-NEXT:    ret
+; LA32-LABEL: load_to_16xi16_offset:
+; LA32:       # %bb.0:
+; LA32-NEXT:    addi.w $a0, $a0, -3
+; LA32-NEXT:    vldrepl.h $vr0, $a0, 0
+; LA32-NEXT:    ret
+;
+; LA64-LABEL: load_to_16xi16_offset:
+; LA64:       # %bb.0:
+; LA64-NEXT:    addi.d $a0, $a0, -3
+; LA64-NEXT:    vldrepl.h $vr0, $a0, 0
+; LA64-NEXT:    ret
   %gep = getelementptr i8, ptr %p, i64 -3
   %v = load i16, ptr %gep
   %ret = insertelement <16 x i16> poison, i16 %v, i32 0
@@ -72,16 +73,14 @@ define <16 x i16> @load_to_16xi16_offset(ptr %p) {
 define <4 x i64> @load_to_4xi64_offset(ptr %p) {
 ; LA32-LABEL: load_to_4xi64_offset:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ld.w $a1, $a0, 6
-; LA32-NEXT:    ld.w $a0, $a0, 10
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 0
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT:    ld.w $a1, $a0, 10
+; LA32-NEXT:    fld.s $fa0, $a0, 6
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a1, 1
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_to_4xi64_offset:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ld.d $a0, $a0, 6
-; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0
+; LA64-NEXT:    fld.d $fa0, $a0, 6
 ; LA64-NEXT:    ret
   %gep = getelementptr i8, ptr %p, i64 6
   %v = load i64, ptr %gep
diff --git a/llvm/test/CodeGen/LoongArch/lasx/vec-sext-invec-mask.ll b/llvm/test/CodeGen/LoongArch/lasx/vec-sext-invec-mask.ll
index 4536027edc3aa2..172962a8cc0e84 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/vec-sext-invec-mask.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/vec-sext-invec-mask.ll
@@ -10,8 +10,7 @@
 define void @zext_or_masks_v4i8_to_v4i64(ptr %ptr, ptr %dst) {
 ; CHECK-LABEL: zext_or_masks_v4i8_to_v4i64:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    ld.w $a0, $a0, 0
-; CHECK-NEXT:    vinsgr2vr.w $vr0, $a0, 0
+; CHECK-NEXT:    fld.s $fa0, $a0, 0
 ; CHECK-NEXT:    vrepli.b $vr1, 1
 ; CHECK-NEXT:    vslt.b $vr1, $vr1, $vr0
 ; CHECK-NEXT:    vseqi.b $vr0, $vr0, 0
@@ -33,10 +32,9 @@ define void @zext_or_masks_v4i8_to_v4i64(ptr %ptr, ptr %dst) {
 define void @zext_or_masks_v4i16_to_v4i64(ptr %ptr, ptr %dst) {
 ; LA32-LABEL: zext_or_masks_v4i16_to_v4i64:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ld.w $a2, $a0, 0
-; LA32-NEXT:    ld.w $a0, $a0, 4
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a2, 0
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT:    ld.w $a2, $a0, 4
+; LA32-NEXT:    fld.s $fa0, $a0, 0
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a2, 1
 ; LA32-NEXT:    vrepli.h $vr1, 1
 ; LA32-NEXT:    vslt.h $vr1, $vr1, $vr0
 ; LA32-NEXT:    vseqi.h $vr0, $vr0, 0
@@ -49,8 +47,7 @@ define void @zext_or_masks_v4i16_to_v4i64(ptr %ptr, ptr %dst) {
 ;
 ; LA64-LABEL: zext_or_masks_v4i16_to_v4i64:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ld.d $a0, $a0, 0
-; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0
+; LA64-NEXT:    fld.d $fa0, $a0, 0
 ; LA64-NEXT:    vrepli.h $vr1, 1
 ; LA64-NEXT:    vslt.h $vr1, $vr1, $vr0
 ; LA64-NEXT:    vseqi.h $vr0, $vr0, 0
@@ -72,10 +69,9 @@ define void @zext_or_masks_v4i16_to_v4i64(ptr %ptr, ptr %dst) {
 define void @zext_or_masks_v8i8_to_v8i32(ptr %ptr, ptr %dst) {
 ; LA32-LABEL: zext_or_masks_v8i8_to_v8i32:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ld.w $a2, $a0, 0
-; LA32-NEXT:    ld.w $a0, $a0, 4
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a2, 0
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT:    ld.w $a2, $a0, 4
+; LA32-NEXT:    fld.s $fa0, $a0, 0
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a2, 1
 ; LA32-NEXT:    vrepli.b $vr1, 1
 ; LA32-NEXT:    vslt.b $vr1, $vr1, $vr0
 ; LA32-NEXT:    vseqi.b $vr0, $vr0, 0
@@ -88,8 +84,7 @@ define void @zext_or_masks_v8i8_to_v8i32(ptr %ptr, ptr %dst) {
 ;
 ; LA64-LABEL: zext_or_masks_v8i8_to_v8i32:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ld.d $a0, $a0, 0
-; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0
+; LA64-NEXT:    fld.d $fa0, $a0, 0
 ; LA64-NEXT:    vrepli.b $vr1, 1
 ; LA64-NEXT:    vslt.b $vr1, $vr1, $vr0
 ; LA64-NEXT:    vseqi.b $vr0, $vr0, 0
@@ -111,8 +106,7 @@ define void @zext_or_masks_v8i8_to_v8i32(ptr %ptr, ptr %dst) {
 define void @sext_or_masks_v4i8_to_v4i64(ptr %ptr, ptr %dst) {
 ; CHECK-LABEL: sext_or_masks_v4i8_to_v4i64:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    ld.w $a0, $a0, 0
-; CHECK-NEXT:    vinsgr2vr.w $vr0, $a0, 0
+; CHECK-NEXT:    fld.s $fa0, $a0, 0
 ; CHECK-NEXT:    vrepli.b $vr1, 1
 ; CHECK-NEXT:    vslt.b $vr1, $vr1, $vr0
 ; CHECK-NEXT:    vseqi.b $vr0, $vr0, 0
@@ -132,10 +126,9 @@ define void @sext_or_masks_v4i8_to_v4i64(ptr %ptr, ptr %dst) {
 define void @sext_or_masks_v4i16_to_v4i64(ptr %ptr, ptr %dst) {
 ; LA32-LABEL: sext_or_masks_v4i16_to_v4i64:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ld.w $a2, $a0, 0
-; LA32-NEXT:    ld.w $a0, $a0, 4
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a2, 0
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT:    ld.w $a2, $a0, 4
+; LA32-NEXT:    fld.s $fa0, $a0, 0
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a2, 1
 ; LA32-NEXT:    vrepli.h $vr1, 1
 ; LA32-NEXT:    vslt.h $vr1, $vr1, $vr0
 ; LA32-NEXT:    vseqi.h $vr0, $vr0, 0
@@ -146,8 +139,7 @@ define void @sext_or_masks_v4i16_to_v4i64(ptr %ptr, ptr %dst) {
 ;
 ; LA64-LABEL: sext_or_masks_v4i16_to_v4i64:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ld.d $a0, $a0, 0
-; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0
+; LA64-NEXT:    fld.d $fa0, $a0, 0
 ; LA64-NEXT:    vrepli.h $vr1, 1
 ; LA64-NEXT:    vslt.h $vr1, $vr1, $vr0
 ; LA64-NEXT:    vseqi.h $vr0, $vr0, 0
@@ -167,10 +159,9 @@ define void @sext_or_masks_v4i16_to_v4i64(ptr %ptr, ptr %dst) {
 define void @sext_or_masks_v8i8_to_v8i32(ptr %ptr, ptr %dst) {
 ; LA32-LABEL: sext_or_masks_v8i8_to_v8i32:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ld.w $a2, $a0, 0
-; LA32-NEXT:    ld.w $a0, $a0, 4
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a2, 0
-; LA32-NEXT:    vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT:    ld.w $a2, $a0, 4
+; LA32-NEXT:    fld.s $fa0, $a0, 0
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a2, 1
 ; LA32-NEXT:    vrepli.b $vr1, 1
 ; LA32-NEXT:    vslt.b $vr1, $vr1, $vr0
 ; LA32-NEXT:    vseqi.b $vr0, $vr0, 0
@@ -18...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/234119


More information about the llvm-branch-commits mailing list