[llvm-branch-commits] [llvm] [LoongArch] Legalize broadcasting the first element of 256-bit vector using `xvreplve0` (PR #169271)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Nov 23 18:56:05 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: ZhaoQi (zhaoqi5)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/169271.diff
2 Files Affected:
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+19)
- (modified) llvm/test/CodeGen/LoongArch/lasx/ir-instruction/shuffle-broadcast.ll (+6-10)
``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index ac95ef5f30888..c461c304cf743 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -2157,6 +2157,23 @@ lowerVECTOR_SHUFFLE_XVSHUF4I(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
return lowerVECTOR_SHUFFLE_VSHUF4I(DL, Mask, VT, V1, V2, DAG, Subtarget);
}
+/// Lower VECTOR_SHUFFLE into XVREPLVE0 (if possible).
+///
+/// It is a XVREPLVE0 when the VECTOR_SHUFFLE is a broadcast of element 0,
+/// i.e. the mask is:
+/// <0, 0, 0, ...>
+///
+/// When undef's appear in the mask they are treated as if they were whatever
+/// value is necessary in order to fit the above form.
+static SDValue lowerVECTOR_SHUFFLE_XVREPLVE0(const SDLoc &DL,
+ ArrayRef<int> Mask, MVT VT,
+ SDValue V1, SelectionDAG &DAG) {
+ if (!ShuffleVectorInst::isZeroEltSplatMask(Mask, Mask.size()))
+ return SDValue();
+
+ return DAG.getNode(LoongArchISD::XVREPLVE0, DL, VT, V1);
+}
+
/// Lower VECTOR_SHUFFLE into XVPERMI (if possible).
static SDValue
lowerVECTOR_SHUFFLE_XVPERMI(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
@@ -2673,6 +2690,8 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
if ((Result = lowerVECTOR_SHUFFLE_XVSHUF4I(DL, Mask, VT, V1, V2, DAG,
Subtarget)))
return Result;
+ if ((Result = lowerVECTOR_SHUFFLE_XVREPLVE0(DL, Mask, VT, V1, DAG)))
+ return Result;
// Try to widen vectors to gain more optimization opportunities.
if (SDValue NewShuffle = widenShuffleMask(DL, Mask, VT, V1, V2, DAG))
return NewShuffle;
diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/shuffle-broadcast.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/shuffle-broadcast.ll
index 5eae364fd40cd..6d18d666dc172 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/shuffle-broadcast.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/shuffle-broadcast.ll
@@ -6,8 +6,7 @@ define void @broadcast0_v32i8(ptr %res, ptr %a) nounwind {
; CHECK-LABEL: broadcast0_v32i8:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 68
-; CHECK-NEXT: xvrepl128vei.b $xr0, $xr0, 0
+; CHECK-NEXT: xvreplve0.b $xr0, $xr0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -36,8 +35,7 @@ define void @broadcast0_v16i16(ptr %res, ptr %a) nounwind {
; CHECK-LABEL: broadcast0_v16i16:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 68
-; CHECK-NEXT: xvrepl128vei.h $xr0, $xr0, 0
+; CHECK-NEXT: xvreplve0.h $xr0, $xr0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -66,8 +64,7 @@ define void @broadcast0_v8i32(ptr %res, ptr %a) nounwind {
; CHECK-LABEL: broadcast0_v8i32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 68
-; CHECK-NEXT: xvrepl128vei.w $xr0, $xr0, 0
+; CHECK-NEXT: xvreplve0.w $xr0, $xr0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -96,8 +93,7 @@ define void @broadcast0_v8f32(ptr %res, ptr %a) nounwind {
; CHECK-LABEL: broadcast0_v8f32:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 68
-; CHECK-NEXT: xvrepl128vei.w $xr0, $xr0, 0
+; CHECK-NEXT: xvreplve0.w $xr0, $xr0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -126,7 +122,7 @@ define void @broadcast0_v4i64(ptr %res, ptr %a) nounwind {
; CHECK-LABEL: broadcast0_v4i64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 0
+; CHECK-NEXT: xvreplve0.d $xr0, $xr0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
@@ -154,7 +150,7 @@ define void @broadcast0_v4f64(ptr %res, ptr %a) nounwind {
; CHECK-LABEL: broadcast0_v4f64:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 0
+; CHECK-NEXT: xvreplve0.d $xr0, $xr0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
``````````
</details>
https://github.com/llvm/llvm-project/pull/169271
More information about the llvm-branch-commits
mailing list