https://github.com/zhaoqi5 created https://github.com/llvm/llvm-project/pull/169271
None >From 9ae33a6793ccb6004dc36dfcff4065d05d0d6e25 Mon Sep 17 00:00:00 2001 From: Qi Zhao <[email protected]> Date: Mon, 24 Nov 2025 10:52:09 +0800 Subject: [PATCH] [LoongArch] Legalize broadcasting the first element of 256-bit vector using `xvreplve0` --- .../LoongArch/LoongArchISelLowering.cpp | 19 +++++++++++++++++++ .../lasx/ir-instruction/shuffle-broadcast.ll | 16 ++++++---------- 2 files changed, 25 insertions(+), 10 deletions(-) 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: _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
