[llvm-branch-commits] [llvm] [LoongArch] Legalize BUILD_VECTOR into a broadcast when all non-undef elements are identical (PR #169755)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Oct 14 23:26:17 PDT 2026
https://github.com/zhaoqi5 updated https://github.com/llvm/llvm-project/pull/169755
>From e315fbd3728554c38f7a2ff1dfb4e7655ad6af83 Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Thu, 27 Nov 2025 11:04:05 +0800
Subject: [PATCH 1/4] [LoongArch] Legalize BUILD_VECTOR into a broadcast when
all non-undef elements are identical
When a BUILD_VECTOR consists of the same element (ignoring undefs),
it is better emitting a broadcast instead of multiple insertions.
Some floating-point cases suffer performance regressions, those
specific cases are excluded in this commit. Including when:
- only one element is non-undef,
- only two elements are non-undef, and one of them must at index 0,
- for v8f32 vector type, specially exclude the cases when the only
two non-undefs are at index (1,2)/(1,3)/(2,3).
---
.../LoongArch/LoongArchISelLowering.cpp | 36 ++++++++++++++++---
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 1d01e76a5ebd2..a13b51c6ae84b 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -3797,6 +3797,36 @@ SDValue LoongArchTargetLowering::lowerBUILD_VECTOR(SDValue Op,
}
if (!IsConstant) {
+ SmallVector<SDValue> Sequence;
+ BitVector UndefElements;
+ bool IsRepeated = Node->getRepeatedSequence(Sequence, &UndefElements);
+ unsigned SeqLen = Sequence.size();
+ unsigned NumUndefElts = UndefElements.count();
+
+ // When a BUILD_VECTOR consists of the same element (ignoring undefs),
+ // prefer emitting a broadcast instead of multiple insertions.
+ if (IsRepeated && SeqLen == 1) {
+ // Integer vectors benefit from splat unconditionally.
+ if (ResTy.isInteger())
+ return DAG.getSplatBuildVector(ResTy, DL, Sequence[0]);
+
+ // Only certain floating-point cases suffer performance regressions,
+ // exclude those specific cases.
+ bool IsSplatBetter = true;
+ if (NumUndefElts == NumElts - 1)
+ IsSplatBetter = false;
+ if (NumUndefElts == NumElts - 2 && !UndefElements[0])
+ IsSplatBetter = false;
+ if (ResTy == MVT::v8f32 && NumUndefElts == NumElts - 2 &&
+ ((!UndefElements[1] && !UndefElements[2]) ||
+ (!UndefElements[1] && !UndefElements[3]) ||
+ (!UndefElements[2] && !UndefElements[3])))
+ IsSplatBetter = false;
+
+ if (IsSplatBetter)
+ return DAG.getSplatBuildVector(ResTy, DL, Sequence[0]);
+ }
+
// If the BUILD_VECTOR has a repeated pattern, use INSERT_VECTOR_ELT to fill
// the sub-sequence of the vector and then broadcast the sub-sequence.
//
@@ -3804,10 +3834,7 @@ SDValue LoongArchTargetLowering::lowerBUILD_VECTOR(SDValue Op,
// back to use INSERT_VECTOR_ELT to materialize the vector, because it
// generates worse code in some cases. This could be further optimized
// with more consideration.
- SmallVector<SDValue> Sequence;
- BitVector UndefElements;
- if (Node->getRepeatedSequence(Sequence, &UndefElements) &&
- UndefElements.count() == 0) {
+ if (IsRepeated && NumUndefElts == 0) {
// Using LSX instructions to fill the sub-sequence of 256-bits vector,
// because the high part can be simply treated as undef.
SDValue Vector = DAG.getUNDEF(ResTy);
@@ -3819,7 +3846,6 @@ SDValue LoongArchTargetLowering::lowerBUILD_VECTOR(SDValue Op,
fillVector(Sequence, DAG, DL, Subtarget, FillVec, FillTy);
- unsigned SeqLen = Sequence.size();
unsigned SplatLen = NumElts / SeqLen;
MVT SplatEltTy = MVT::getIntegerVT(VT.getScalarSizeInBits() * SeqLen);
MVT SplatTy = MVT::getVectorVT(SplatEltTy, SplatLen);
>From f3c21eba0f625dc53c2364093ae55ffddf753894 Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Thu, 27 Nov 2025 11:13:06 +0800
Subject: [PATCH 2/4] update tests
---
.../CodeGen/LoongArch/lasx/build-vector.ll | 50 ++++---------------
.../lasx/ir-instruction/insertelement.ll | 10 ++--
.../LoongArch/lasx/scalar-to-vector.ll | 8 +--
.../CodeGen/LoongArch/lsx/build-vector.ll | 26 +++-------
.../CodeGen/LoongArch/lsx/scalar-to-vector.ll | 8 +--
5 files changed, 29 insertions(+), 73 deletions(-)
diff --git a/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll b/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll
index f753ac3f6f623..d04cabb4ddf8e 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/build-vector.ll
@@ -93,22 +93,7 @@ entry:
define void @buildvector_v32i8_splat_with_undef(ptr %dst, i8 %a0) nounwind {
; CHECK-LABEL: buildvector_v32i8_splat_with_undef:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 1
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 3
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 5
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 7
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 9
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 11
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 13
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 14
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 15
+; CHECK-NEXT: xvreplgr2vr.b $xr0, $a1
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -135,15 +120,7 @@ entry:
define void @buildvector_v16i16_splat_with_undef(ptr %dst, i16 %a0) nounwind {
; CHECK-LABEL: buildvector_v16i16_splat_with_undef:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 0
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 1
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 2
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 3
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 4
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 5
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 6
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 7
-; CHECK-NEXT: xvpermi.q $xr0, $xr0, 2
+; CHECK-NEXT: xvreplgr2vr.h $xr0, $a1
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -162,9 +139,7 @@ entry:
define void @buildvector_v8i32_splat_with_undef(ptr %dst, i32 %a0) nounwind {
; CHECK-LABEL: buildvector_v8i32_splat_with_undef:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a1, 0
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a1, 2
-; CHECK-NEXT: xvpermi.q $xr0, $xr0, 2
+; CHECK-NEXT: xvreplgr2vr.w $xr0, $a1
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -189,8 +164,7 @@ define void @buildvector_v4i64_splat_with_undef(ptr %dst, i64 %a0) nounwind {
;
; LA64-LABEL: buildvector_v4i64_splat_with_undef:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: xvinsgr2vr.d $xr0, $a1, 0
-; LA64-NEXT: xvinsgr2vr.d $xr0, $a1, 3
+; LA64-NEXT: xvreplgr2vr.d $xr0, $a1
; LA64-NEXT: xvst $xr0, $a0, 0
; LA64-NEXT: ret
entry:
@@ -232,9 +206,8 @@ define void @buildvector_v8f32_splat_with_undef_2(ptr %dst, float %a0) nounwind
; CHECK-LABEL: buildvector_v8f32_splat_with_undef_2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: # kill: def $f0 killed $f0 def $xr0
-; CHECK-NEXT: xvinsve0.w $xr1, $xr0, 1
-; CHECK-NEXT: xvinsve0.w $xr1, $xr0, 4
-; CHECK-NEXT: xvst $xr1, $a0, 0
+; CHECK-NEXT: xvreplve0.w $xr0, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%ins1 = insertelement <8 x float> undef, float %a0, i32 1
@@ -246,11 +219,9 @@ entry:
define void @buildvector_v8f32_splat_with_undef_3(ptr %dst, float %a0) nounwind {
; CHECK-LABEL: buildvector_v8f32_splat_with_undef_3:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: # kill: def $f0 killed $f0 def $vr0
-; CHECK-NEXT: vextrins.w $vr1, $vr0, 16
-; CHECK-NEXT: vextrins.w $vr1, $vr0, 48
-; CHECK-NEXT: xvpermi.q $xr1, $xr1, 2
-; CHECK-NEXT: xvst $xr1, $a0, 0
+; CHECK-NEXT: # kill: def $f0 killed $f0 def $xr0
+; CHECK-NEXT: xvreplve0.w $xr0, $xr0
+; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%ins1 = insertelement <8 x float> undef, float %a0, i32 1
@@ -292,8 +263,7 @@ define void @buildvector_v4f64_splat_with_undef_2(ptr %dst, double %a0) nounwind
; CHECK-LABEL: buildvector_v4f64_splat_with_undef_2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: # kill: def $f0_64 killed $f0_64 def $xr0
-; CHECK-NEXT: vextrins.d $vr0, $vr0, 16
-; CHECK-NEXT: xvpermi.q $xr0, $xr0, 2
+; CHECK-NEXT: xvreplve0.d $xr0, $xr0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/insertelement.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/insertelement.ll
index a13bdf9aeaf9f..e6442fbbc77dd 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/insertelement.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/insertelement.ll
@@ -35,7 +35,7 @@ define void @insert_32xi8_upper(ptr %src, ptr %dst, i8 %in) nounwind {
define void @insert_32xi8_undef(ptr %dst, i8 %in) nounwind {
; CHECK-LABEL: insert_32xi8_undef:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 1
+; CHECK-NEXT: xvreplgr2vr.b $xr0, $a1
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
%v = insertelement <32 x i8> poison, i8 %in, i32 1
@@ -46,8 +46,7 @@ define void @insert_32xi8_undef(ptr %dst, i8 %in) nounwind {
define void @insert_32xi8_undef_upper(ptr %dst, i8 %in) nounwind {
; CHECK-LABEL: insert_32xi8_undef_upper:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 6
-; CHECK-NEXT: xvpermi.q $xr0, $xr0, 2
+; CHECK-NEXT: xvreplgr2vr.b $xr0, $a1
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
%v = insertelement <32 x i8> poison, i8 %in, i32 22
@@ -88,7 +87,7 @@ define void @insert_16xi16_upper(ptr %src, ptr %dst, i16 %in) nounwind {
define void @insert_16xi16_undef(ptr %dst, i16 %in) nounwind {
; CHECK-LABEL: insert_16xi16_undef:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 1
+; CHECK-NEXT: xvreplgr2vr.h $xr0, $a1
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
%v = insertelement <16 x i16> poison, i16 %in, i32 1
@@ -99,8 +98,7 @@ define void @insert_16xi16_undef(ptr %dst, i16 %in) nounwind {
define void @insert_16xi16_undef_upper(ptr %dst, i16 %in) nounwind {
; CHECK-LABEL: insert_16xi16_undef_upper:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 2
-; CHECK-NEXT: xvpermi.q $xr0, $xr0, 2
+; CHECK-NEXT: xvreplgr2vr.h $xr0, $a1
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
%v = insertelement <16 x i16> poison, i16 %in, i32 10
diff --git a/llvm/test/CodeGen/LoongArch/lasx/scalar-to-vector.ll b/llvm/test/CodeGen/LoongArch/lasx/scalar-to-vector.ll
index bba269279937a..39533cff7c868 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/scalar-to-vector.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/scalar-to-vector.ll
@@ -7,7 +7,7 @@
define <32 x i8> @scalar_to_32xi8(i8 %val) {
; CHECK-LABEL: scalar_to_32xi8:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 0
+; CHECK-NEXT: xvreplgr2vr.b $xr0, $a0
; CHECK-NEXT: ret
%ret = insertelement <32 x i8> poison, i8 %val, i32 0
ret <32 x i8> %ret
@@ -16,7 +16,7 @@ define <32 x i8> @scalar_to_32xi8(i8 %val) {
define <16 x i16> @scalar_to_16xi16(i16 %val) {
; CHECK-LABEL: scalar_to_16xi16:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 0
+; CHECK-NEXT: xvreplgr2vr.h $xr0, $a0
; CHECK-NEXT: ret
%ret = insertelement <16 x i16> poison, i16 %val, i32 0
ret <16 x i16> %ret
@@ -25,7 +25,7 @@ define <16 x i16> @scalar_to_16xi16(i16 %val) {
define <8 x i32> @scalar_to_8xi32(i32 %val) {
; CHECK-LABEL: scalar_to_8xi32:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 0
+; CHECK-NEXT: xvreplgr2vr.w $xr0, $a0
; CHECK-NEXT: ret
%ret = insertelement <8 x i32> poison, i32 %val, i32 0
ret <8 x i32> %ret
@@ -40,7 +40,7 @@ define <4 x i64> @scalar_to_4xi64(i64 %val) {
;
; LA64-LABEL: scalar_to_4xi64:
; LA64: # %bb.0:
-; LA64-NEXT: vinsgr2vr.d $vr0, $a0, 0
+; LA64-NEXT: xvreplgr2vr.d $xr0, $a0
; LA64-NEXT: ret
%ret = insertelement <4 x i64> poison, i64 %val, i32 0
ret <4 x i64> %ret
diff --git a/llvm/test/CodeGen/LoongArch/lsx/build-vector.ll b/llvm/test/CodeGen/LoongArch/lsx/build-vector.ll
index 1fe289cdaaccb..eb1a843bb42d8 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/build-vector.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/build-vector.ll
@@ -93,14 +93,7 @@ entry:
define void @buildvector_v16i8_splat_with_undef(ptr %dst, i8 %a0) nounwind {
; CHECK-LABEL: buildvector_v16i8_splat_with_undef:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a1, 14
+; CHECK-NEXT: vreplgr2vr.b $vr0, $a1
; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -119,10 +112,7 @@ entry:
define void @buildvector_v8i16_splat_with_undef(ptr %dst, i16 %a0) nounwind {
; CHECK-LABEL: buildvector_v8i16_splat_with_undef:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 1
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 3
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 5
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a1, 7
+; CHECK-NEXT: vreplgr2vr.h $vr0, $a1
; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -137,8 +127,7 @@ entry:
define void @buildvector_v4i32_splat_with_undef(ptr %dst, i32 %a0) nounwind {
; CHECK-LABEL: buildvector_v4i32_splat_with_undef:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a1, 1
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a1, 2
+; CHECK-NEXT: vreplgr2vr.w $vr0, $a1
; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -158,7 +147,7 @@ define void @buildvector_v2i64_splat_with_undef(ptr %dst, i64 %a0) nounwind {
;
; LA64-LABEL: buildvector_v2i64_splat_with_undef:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: vinsgr2vr.d $vr0, $a1, 0
+; LA64-NEXT: vreplgr2vr.d $vr0, $a1
; LA64-NEXT: vst $vr0, $a0, 0
; LA64-NEXT: ret
entry:
@@ -197,9 +186,8 @@ define void @buildvector_v4f32_splat_with_undef_2(ptr %dst, float %a0) nounwind
; CHECK-LABEL: buildvector_v4f32_splat_with_undef_2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: # kill: def $f0 killed $f0 def $vr0
-; CHECK-NEXT: vextrins.w $vr1, $vr0, 16
-; CHECK-NEXT: vextrins.w $vr1, $vr0, 32
-; CHECK-NEXT: vst $vr1, $a0, 0
+; CHECK-NEXT: vreplvei.w $vr0, $vr0, 0
+; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
%ins1 = insertelement <4 x float> undef, float %a0, i32 1
@@ -969,7 +957,7 @@ define void @buildvector_v2i64_partial(ptr %dst, i64 %a0) nounwind {
;
; LA64-LABEL: buildvector_v2i64_partial:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: vinsgr2vr.d $vr0, $a1, 0
+; LA64-NEXT: vreplgr2vr.d $vr0, $a1
; LA64-NEXT: vst $vr0, $a0, 0
; LA64-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/LoongArch/lsx/scalar-to-vector.ll b/llvm/test/CodeGen/LoongArch/lsx/scalar-to-vector.ll
index d2a506dd98547..be1a8206c2418 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/scalar-to-vector.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/scalar-to-vector.ll
@@ -7,7 +7,7 @@
define <16 x i8> @scalar_to_16xi8(i8 %val) {
; CHECK-LABEL: scalar_to_16xi8:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 0
+; CHECK-NEXT: vreplgr2vr.b $vr0, $a0
; CHECK-NEXT: ret
%ret = insertelement <16 x i8> poison, i8 %val, i32 0
ret <16 x i8> %ret
@@ -16,7 +16,7 @@ define <16 x i8> @scalar_to_16xi8(i8 %val) {
define <8 x i16> @scalar_to_8xi16(i16 %val) {
; CHECK-LABEL: scalar_to_8xi16:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 0
+; CHECK-NEXT: vreplgr2vr.h $vr0, $a0
; CHECK-NEXT: ret
%ret = insertelement <8 x i16> poison, i16 %val, i32 0
ret <8 x i16> %ret
@@ -25,7 +25,7 @@ define <8 x i16> @scalar_to_8xi16(i16 %val) {
define <4 x i32> @scalar_to_4xi32(i32 %val) {
; CHECK-LABEL: scalar_to_4xi32:
; CHECK: # %bb.0:
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 0
+; CHECK-NEXT: vreplgr2vr.w $vr0, $a0
; CHECK-NEXT: ret
%ret = insertelement <4 x i32> poison, i32 %val, i32 0
ret <4 x i32> %ret
@@ -40,7 +40,7 @@ define <2 x i64> @scalar_to_2xi64(i64 %val) {
;
; LA64-LABEL: scalar_to_2xi64:
; LA64: # %bb.0:
-; LA64-NEXT: vinsgr2vr.d $vr0, $a0, 0
+; LA64-NEXT: vreplgr2vr.d $vr0, $a0
; LA64-NEXT: ret
%ret = insertelement <2 x i64> poison, i64 %val, i32 0
ret <2 x i64> %ret
>From 58f260be0834b78cb0731cc6653b6b01f69df6e4 Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Wed, 29 Apr 2026 17:12:04 +0800
Subject: [PATCH 3/4] update tests
---
llvm/test/CodeGen/LoongArch/lasx/rotl-rotr.ll | 8 ++------
llvm/test/CodeGen/LoongArch/lsx/rotl-rotr.ll | 6 ++----
2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/llvm/test/CodeGen/LoongArch/lasx/rotl-rotr.ll b/llvm/test/CodeGen/LoongArch/lasx/rotl-rotr.ll
index cde567366ad74..12d5bf868a974 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/rotl-rotr.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/rotl-rotr.ll
@@ -168,9 +168,7 @@ define void @rotl_v4i64(ptr %dst, ptr %src, i64 %a0) nounwind {
; LA32-LABEL: rotl_v4i64:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a1, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 2
-; LA32-NEXT: xvpermi.q $xr1, $xr1, 2
+; LA32-NEXT: xvreplgr2vr.w $xr1, $a2
; LA32-NEXT: xvneg.d $xr1, $xr1
; LA32-NEXT: xvrotr.d $xr0, $xr0, $xr1
; LA32-NEXT: xvst $xr0, $a0, 0
@@ -199,9 +197,7 @@ define void @rotr_v4i64(ptr %dst, ptr %src, i64 %a0) nounwind {
; LA32-LABEL: rotr_v4i64:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a1, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 2
-; LA32-NEXT: xvpermi.q $xr1, $xr1, 2
+; LA32-NEXT: xvreplgr2vr.w $xr1, $a2
; LA32-NEXT: xvrotr.d $xr0, $xr0, $xr1
; LA32-NEXT: xvst $xr0, $a0, 0
; LA32-NEXT: ret
diff --git a/llvm/test/CodeGen/LoongArch/lsx/rotl-rotr.ll b/llvm/test/CodeGen/LoongArch/lsx/rotl-rotr.ll
index 11c31af27211d..709fdb800b0f5 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/rotl-rotr.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/rotl-rotr.ll
@@ -168,8 +168,7 @@ define void @rotl_v2i64(ptr %dst, ptr %src, i64 %a0) nounwind {
; LA32-LABEL: rotl_v2i64:
; LA32: # %bb.0:
; LA32-NEXT: vld $vr0, $a1, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 2
+; LA32-NEXT: vreplgr2vr.w $vr1, $a2
; LA32-NEXT: vneg.d $vr1, $vr1
; LA32-NEXT: vrotr.d $vr0, $vr0, $vr1
; LA32-NEXT: vst $vr0, $a0, 0
@@ -198,8 +197,7 @@ define void @rotr_v2i64(ptr %dst, ptr %src, i64 %a0) nounwind {
; LA32-LABEL: rotr_v2i64:
; LA32: # %bb.0:
; LA32-NEXT: vld $vr0, $a1, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 2
+; LA32-NEXT: vreplgr2vr.w $vr1, $a2
; LA32-NEXT: vrotr.d $vr0, $vr0, $vr1
; LA32-NEXT: vst $vr0, $a0, 0
; LA32-NEXT: ret
>From 96f8aa5164fb81be834b3821705d887ee953597a Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Thu, 15 Oct 2026 14:23:29 +0800
Subject: [PATCH 4/4] update after rebase
---
.../LoongArch/lsx/ir-instruction/sitofp.ll | 58 +++++++++----------
.../LoongArch/lsx/ir-instruction/uitofp.ll | 42 +++++++-------
2 files changed, 48 insertions(+), 52 deletions(-)
diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll
index d6177d5ca0969..38edad0a80643 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll
@@ -230,51 +230,49 @@ define <4 x double> @sitofp_v16i8_v4f64(<16 x i8> %a) {
define <5 x double> @sitofp_v5i32_v5f64(<5 x i32> %a) {
; LA32-LABEL: sitofp_v5i32_v5f64:
; LA32: # %bb.0:
-; LA32-NEXT: ld.w $a2, $a1, 16
-; LA32-NEXT: vinsgr2vr.w $vr0, $a2, 0
; LA32-NEXT: ld.w $a2, $a1, 0
; LA32-NEXT: ld.w $a3, $a1, 4
; LA32-NEXT: ld.w $a4, $a1, 8
-; LA32-NEXT: ld.w $a1, $a1, 12
-; LA32-NEXT: vinsgr2vr.w $vr1, $a2, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a3, 1
-; LA32-NEXT: vinsgr2vr.w $vr1, $a4, 2
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 3
-; LA32-NEXT: vslti.w $vr2, $vr1, 0
-; LA32-NEXT: vilvl.w $vr3, $vr2, $vr1
-; LA32-NEXT: vffint.d.l $vr3, $vr3
-; LA32-NEXT: vilvh.w $vr1, $vr2, $vr1
-; LA32-NEXT: vffint.d.l $vr1, $vr1
+; LA32-NEXT: ld.w $a5, $a1, 12
+; LA32-NEXT: vinsgr2vr.w $vr0, $a2, 0
+; LA32-NEXT: vinsgr2vr.w $vr0, $a3, 1
+; LA32-NEXT: vinsgr2vr.w $vr0, $a4, 2
+; LA32-NEXT: vinsgr2vr.w $vr0, $a5, 3
+; LA32-NEXT: vldrepl.w $vr1, $a1, 16
; LA32-NEXT: vslti.w $vr2, $vr0, 0
-; LA32-NEXT: vilvl.w $vr0, $vr2, $vr0
+; LA32-NEXT: vilvl.w $vr3, $vr2, $vr0
+; LA32-NEXT: vffint.d.l $vr3, $vr3
+; LA32-NEXT: vilvh.w $vr0, $vr2, $vr0
; LA32-NEXT: vffint.d.l $vr0, $vr0
-; LA32-NEXT: vstelm.d $vr0, $a0, 32, 0
-; LA32-NEXT: vst $vr1, $a0, 16
+; LA32-NEXT: vslti.w $vr2, $vr1, 0
+; LA32-NEXT: vilvl.w $vr1, $vr2, $vr1
+; LA32-NEXT: vffint.d.l $vr1, $vr1
+; LA32-NEXT: vstelm.d $vr1, $a0, 32, 0
+; LA32-NEXT: vst $vr0, $a0, 16
; LA32-NEXT: vst $vr3, $a0, 0
; LA32-NEXT: ret
;
; LA64-LABEL: sitofp_v5i32_v5f64:
; LA64: # %bb.0:
-; LA64-NEXT: ld.w $a2, $a1, 32
-; LA64-NEXT: vinsgr2vr.w $vr0, $a2, 0
; LA64-NEXT: ld.w $a2, $a1, 0
; LA64-NEXT: ld.w $a3, $a1, 8
; LA64-NEXT: ld.w $a4, $a1, 16
-; LA64-NEXT: ld.w $a1, $a1, 24
-; LA64-NEXT: vinsgr2vr.w $vr1, $a2, 0
-; LA64-NEXT: vinsgr2vr.w $vr1, $a3, 1
-; LA64-NEXT: vinsgr2vr.w $vr1, $a4, 2
-; LA64-NEXT: vinsgr2vr.w $vr1, $a1, 3
-; LA64-NEXT: vslti.w $vr2, $vr1, 0
-; LA64-NEXT: vilvl.w $vr3, $vr2, $vr1
-; LA64-NEXT: vffint.d.l $vr3, $vr3
-; LA64-NEXT: vilvh.w $vr1, $vr2, $vr1
-; LA64-NEXT: vffint.d.l $vr1, $vr1
+; LA64-NEXT: ld.w $a5, $a1, 24
+; LA64-NEXT: vinsgr2vr.w $vr0, $a2, 0
+; LA64-NEXT: vinsgr2vr.w $vr0, $a3, 1
+; LA64-NEXT: vinsgr2vr.w $vr0, $a4, 2
+; LA64-NEXT: vinsgr2vr.w $vr0, $a5, 3
+; LA64-NEXT: vldrepl.w $vr1, $a1, 32
; LA64-NEXT: vslti.w $vr2, $vr0, 0
-; LA64-NEXT: vilvl.w $vr0, $vr2, $vr0
+; LA64-NEXT: vilvl.w $vr3, $vr2, $vr0
+; LA64-NEXT: vffint.d.l $vr3, $vr3
+; LA64-NEXT: vilvh.w $vr0, $vr2, $vr0
; LA64-NEXT: vffint.d.l $vr0, $vr0
-; LA64-NEXT: vstelm.d $vr0, $a0, 32, 0
-; LA64-NEXT: vst $vr1, $a0, 16
+; LA64-NEXT: vslti.w $vr2, $vr1, 0
+; LA64-NEXT: vilvl.w $vr1, $vr2, $vr1
+; LA64-NEXT: vffint.d.l $vr1, $vr1
+; LA64-NEXT: vstelm.d $vr1, $a0, 32, 0
+; LA64-NEXT: vst $vr0, $a0, 16
; LA64-NEXT: vst $vr3, $a0, 0
; LA64-NEXT: ret
%v = sitofp <5 x i32> %a to <5 x double>
diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll
index dd526904af415..5174d47eb9989 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll
@@ -91,50 +91,48 @@ define <4 x double> @uitofp_v16i8_v4f64(<16 x i8> %a) {
define <5 x double> @uitofp_v5i32_v5f64(<5 x i32> %a) {
; LA32-LABEL: uitofp_v5i32_v5f64:
; LA32: # %bb.0:
-; LA32-NEXT: ld.w $a2, $a1, 16
-; LA32-NEXT: ld.w $a3, $a1, 0
-; LA32-NEXT: ld.w $a4, $a1, 4
+; LA32-NEXT: ld.w $a2, $a1, 0
+; LA32-NEXT: ld.w $a3, $a1, 4
; LA32-NEXT: vinsgr2vr.w $vr0, $a2, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a3, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a4, 1
+; LA32-NEXT: vinsgr2vr.w $vr0, $a3, 1
+; LA32-NEXT: vldrepl.w $vr1, $a1, 16
; LA32-NEXT: ld.w $a2, $a1, 12
; LA32-NEXT: ld.w $a1, $a1, 8
; LA32-NEXT: vrepli.b $vr2, 0
-; LA32-NEXT: vilvl.w $vr1, $vr2, $vr1
-; LA32-NEXT: vffint.d.lu $vr1, $vr1
+; LA32-NEXT: vilvl.w $vr0, $vr2, $vr0
+; LA32-NEXT: vffint.d.lu $vr0, $vr0
; LA32-NEXT: vinsgr2vr.w $vr3, $a1, 0
; LA32-NEXT: vinsgr2vr.w $vr3, $a2, 1
; LA32-NEXT: vilvl.w $vr3, $vr2, $vr3
; LA32-NEXT: vffint.d.lu $vr3, $vr3
-; LA32-NEXT: vilvl.w $vr0, $vr2, $vr0
-; LA32-NEXT: vffint.d.lu $vr0, $vr0
-; LA32-NEXT: vstelm.d $vr0, $a0, 32, 0
+; LA32-NEXT: vilvl.w $vr1, $vr2, $vr1
+; LA32-NEXT: vffint.d.lu $vr1, $vr1
+; LA32-NEXT: vstelm.d $vr1, $a0, 32, 0
; LA32-NEXT: vst $vr3, $a0, 16
-; LA32-NEXT: vst $vr1, $a0, 0
+; LA32-NEXT: vst $vr0, $a0, 0
; LA32-NEXT: ret
;
; LA64-LABEL: uitofp_v5i32_v5f64:
; LA64: # %bb.0:
-; LA64-NEXT: ld.w $a2, $a1, 32
-; LA64-NEXT: ld.w $a3, $a1, 0
-; LA64-NEXT: ld.w $a4, $a1, 8
+; LA64-NEXT: ld.w $a2, $a1, 0
+; LA64-NEXT: ld.w $a3, $a1, 8
; LA64-NEXT: vinsgr2vr.w $vr0, $a2, 0
-; LA64-NEXT: vinsgr2vr.w $vr1, $a3, 0
-; LA64-NEXT: vinsgr2vr.w $vr1, $a4, 1
+; LA64-NEXT: vinsgr2vr.w $vr0, $a3, 1
+; LA64-NEXT: vldrepl.w $vr1, $a1, 32
; LA64-NEXT: ld.w $a2, $a1, 24
; LA64-NEXT: ld.w $a1, $a1, 16
; LA64-NEXT: vrepli.b $vr2, 0
-; LA64-NEXT: vilvl.w $vr1, $vr2, $vr1
-; LA64-NEXT: vffint.d.lu $vr1, $vr1
+; LA64-NEXT: vilvl.w $vr0, $vr2, $vr0
+; LA64-NEXT: vffint.d.lu $vr0, $vr0
; LA64-NEXT: vinsgr2vr.w $vr3, $a1, 0
; LA64-NEXT: vinsgr2vr.w $vr3, $a2, 1
; LA64-NEXT: vilvl.w $vr3, $vr2, $vr3
; LA64-NEXT: vffint.d.lu $vr3, $vr3
-; LA64-NEXT: vilvl.w $vr0, $vr2, $vr0
-; LA64-NEXT: vffint.d.lu $vr0, $vr0
-; LA64-NEXT: vstelm.d $vr0, $a0, 32, 0
+; LA64-NEXT: vilvl.w $vr1, $vr2, $vr1
+; LA64-NEXT: vffint.d.lu $vr1, $vr1
+; LA64-NEXT: vstelm.d $vr1, $a0, 32, 0
; LA64-NEXT: vst $vr3, $a0, 16
-; LA64-NEXT: vst $vr1, $a0, 0
+; LA64-NEXT: vst $vr0, $a0, 0
; LA64-NEXT: ret
%v = uitofp <5 x i32> %a to <5 x double>
ret <5 x double> %v
More information about the llvm-branch-commits
mailing list