[llvm] 9fd6933 - [LoongArch] Use vector extend for sitofp/uitofp (#202496)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 28 18:48:11 PDT 2026
Author: lrzlin
Date: 2026-06-29T09:48:06+08:00
New Revision: 9fd6933cf03f7e46fd4b8ec579f7daa8ad26361d
URL: https://github.com/llvm/llvm-project/commit/9fd6933cf03f7e46fd4b8ec579f7daa8ad26361d
DIFF: https://github.com/llvm/llvm-project/commit/9fd6933cf03f7e46fd4b8ec579f7daa8ad26361d.diff
LOG: [LoongArch] Use vector extend for sitofp/uitofp (#202496)
Called sign/zero extend first in `performS[U]INT_TO_FPCombine` before
doing vector sitofp/uitofp, which avoid inefficient scalarization.
Added:
Modified:
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sitofp.ll
llvm/test/CodeGen/LoongArch/lasx/ir-instruction/uitofp.ll
llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll
llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 702006221934f..69b73b6f558d2 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -519,6 +519,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
setTargetDAGCombine(ISD::VSELECT);
setTargetDAGCombine(ISD::FP_TO_SINT);
setTargetDAGCombine(ISD::FP_TO_UINT);
+ setTargetDAGCombine(ISD::UINT_TO_FP);
}
// Set DAG combine for 'LASX' feature.
@@ -8072,12 +8073,36 @@ static SDValue performVANDNCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+static SDValue ExtendSrcToDst(SDNode *N, SelectionDAG &DAG, unsigned ExtendOp) {
+ SDLoc DL(N);
+ EVT VT = N->getValueType(0);
+ SDValue Src = N->getOperand(0);
+ EVT SrcVT = Src.getValueType();
+
+ unsigned DstElts = VT.getVectorNumElements();
+ unsigned SrcEltBits = SrcVT.getScalarSizeInBits();
+ unsigned DstEltBits = VT.getScalarSizeInBits();
+
+ if (SrcEltBits >= DstEltBits)
+ return SDValue();
+
+ MVT WidenEltVT = MVT::getIntegerVT(DstEltBits);
+ MVT WidenSrcVT = MVT::getVectorVT(WidenEltVT, DstElts);
+
+ SDValue Extend = DAG.getNode(ExtendOp, DL, WidenSrcVT, Src);
+ return DAG.getNode(N->getOpcode(), DL, VT, Extend);
+}
+
static SDValue performSINT_TO_FPCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const LoongArchSubtarget &Subtarget) {
SDLoc DL(N);
EVT VT = N->getValueType(0);
+ // Sign-extend src to avoid scalarization.
+ if (VT.isVector())
+ return ExtendSrcToDst(N, DAG, ISD::SIGN_EXTEND);
+
if (VT != MVT::f32 && VT != MVT::f64)
return SDValue();
if (VT == MVT::f32 && !Subtarget.hasBasicF())
@@ -8111,6 +8136,19 @@ static SDValue performSINT_TO_FPCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+static SDValue performUINT_TO_FPCombine(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const LoongArchSubtarget &Subtarget) {
+ SDLoc DL(N);
+ EVT VT = N->getValueType(0);
+
+ // Zero-extend src to avoid scalarization.
+ if (VT.isVector())
+ return ExtendSrcToDst(N, DAG, ISD::ZERO_EXTEND);
+
+ return SDValue();
+}
+
// Using [X]VFTINTRZ_W_D for double to signed 32-bit integer conversion.
// For example:
// v4i32 = fp_to_sint (concat_vectors v2f64, v2f64)
@@ -8491,6 +8529,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
return performEXTENDCombine(N, DAG, DCI, Subtarget);
case ISD::SINT_TO_FP:
return performSINT_TO_FPCombine(N, DAG, DCI, Subtarget);
+ case ISD::UINT_TO_FP:
+ return performUINT_TO_FPCombine(N, DAG, DCI, Subtarget);
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
return performFP_TO_INTCombine(N, DAG, DCI, Subtarget);
diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sitofp.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sitofp.ll
index 3673f594094be..5e3261a22c404 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sitofp.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/sitofp.ll
@@ -56,3 +56,138 @@ define void @sitofp_v4i32_v4f64(ptr %res, ptr %in){
store <4 x double> %v1, ptr %res
ret void
}
+
+define <2 x float> @sitofp_v2i32_v2f32(<2 x i32> %a) {
+; CHECK-LABEL: sitofp_v2i32_v2f32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vffint.s.w $vr0, $vr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <2 x i32> %a to <2 x float>
+ ret <2 x float> %cvt
+}
+
+define <2 x double> @sitofp_v4i32_v2f64(<4 x i32> %a) {
+; CHECK-LABEL: sitofp_v4i32_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.d.w $xr0, $xr0
+; CHECK-NEXT: xvffint.d.l $xr0, $xr0
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <4 x i32> %a to <4 x double>
+ %shuf = shufflevector <4 x double> %cvt, <4 x double> poison, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %shuf
+}
+
+define <2 x double> @sitofp_v2i16_v2f64(<8 x i16> %a) {
+; CHECK-LABEL: sitofp_v2i16_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.d.h $xr0, $xr0
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: ret
+ %shuf = shufflevector <8 x i16> %a, <8 x i16> poison, <2 x i32> <i32 0, i32 1>
+ %cvt = sitofp <2 x i16> %shuf to <2 x double>
+ ret <2 x double> %cvt
+}
+
+define <2 x double> @sitofp_v8i16_v2f64(<8 x i16> %a) {
+; CHECK-LABEL: sitofp_v8i16_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.w.h $xr0, $xr0
+; CHECK-NEXT: vext2xv.d.w $xr0, $xr0
+; CHECK-NEXT: xvffint.d.l $xr0, $xr0
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <8 x i16> %a to <8 x double>
+ %shuf = shufflevector <8 x double> %cvt, <8 x double> poison, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %shuf
+}
+
+define <2 x double> @sitofp_v2i8_v2f64(<16 x i8> %a) {
+; CHECK-LABEL: sitofp_v2i8_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.d.b $xr0, $xr0
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: ret
+ %shuf = shufflevector <16 x i8> %a, <16 x i8> poison, <2 x i32> <i32 0, i32 1>
+ %cvt = sitofp <2 x i8> %shuf to <2 x double>
+ ret <2 x double> %cvt
+}
+
+define <2 x double> @sitofp_v16i8_v2f64(<16 x i8> %a) {
+; CHECK-LABEL: sitofp_v16i8_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.h.b $xr0, $xr0
+; CHECK-NEXT: vext2xv.w.h $xr0, $xr0
+; CHECK-NEXT: vext2xv.d.w $xr0, $xr0
+; CHECK-NEXT: xvffint.d.l $xr0, $xr0
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <16 x i8> %a to <16 x double>
+ %shuf = shufflevector <16 x double> %cvt, <16 x double> poison, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %shuf
+}
+
+define <4 x double> @sitofp_v4i64_v4f64(<4 x i64> %a) {
+; CHECK-LABEL: sitofp_v4i64_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xvffint.d.l $xr0, $xr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <4 x i64> %a to <4 x double>
+ ret <4 x double> %cvt
+}
+
+define <4 x double> @sitofp_v4i16_v4f64(<8 x i16> %a) {
+; CHECK-LABEL: sitofp_v4i16_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.d.h $xr0, $xr0
+; CHECK-NEXT: xvffint.d.l $xr0, $xr0
+; CHECK-NEXT: ret
+ %shuf = shufflevector <8 x i16> %a, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %cvt = sitofp <4 x i16> %shuf to <4 x double>
+ ret <4 x double> %cvt
+}
+
+define <4 x double> @sitofp_v8i16_v4f64(<8 x i16> %a) {
+; CHECK-LABEL: sitofp_v8i16_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.w.h $xr0, $xr0
+; CHECK-NEXT: vext2xv.d.w $xr0, $xr0
+; CHECK-NEXT: xvffint.d.l $xr0, $xr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <8 x i16> %a to <8 x double>
+ %shuf = shufflevector <8 x double> %cvt, <8 x double> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ ret <4 x double> %shuf
+}
+
+define <4 x double> @sitofp_v4i8_v4f64(<16 x i8> %a) {
+; CHECK-LABEL: sitofp_v4i8_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.d.b $xr0, $xr0
+; CHECK-NEXT: xvffint.d.l $xr0, $xr0
+; CHECK-NEXT: ret
+ %shuf = shufflevector <16 x i8> %a, <16 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %cvt = sitofp <4 x i8> %shuf to <4 x double>
+ ret <4 x double> %cvt
+}
+
+define <4 x double> @sitofp_v16i8_v4f64(<16 x i8> %a) {
+; CHECK-LABEL: sitofp_v16i8_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.h.b $xr0, $xr0
+; CHECK-NEXT: vext2xv.w.h $xr0, $xr0
+; CHECK-NEXT: vext2xv.d.w $xr0, $xr0
+; CHECK-NEXT: xvffint.d.l $xr0, $xr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <16 x i8> %a to <16 x double>
+ %shuf = shufflevector <16 x double> %cvt, <16 x double> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ ret <4 x double> %shuf
+}
diff --git a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/uitofp.ll b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/uitofp.ll
index 6e417032acff5..8d5ec3f64ebcf 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/uitofp.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/ir-instruction/uitofp.ll
@@ -56,3 +56,56 @@ define void @uitofp_v4i32_v4f64(ptr %res, ptr %in){
store <4 x double> %v1, ptr %res
ret void
}
+
+define <2 x double> @uitofp_v2i8_v2f64(<16 x i8> %a) {
+; CHECK-LABEL: uitofp_v2i8_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.du.bu $xr0, $xr0
+; CHECK-NEXT: vffint.d.lu $vr0, $vr0
+; CHECK-NEXT: ret
+ %shuf = shufflevector <16 x i8> %a, <16 x i8> poison, <2 x i32> <i32 0, i32 1>
+ %cvt = uitofp <2 x i8> %shuf to <2 x double>
+ ret <2 x double> %cvt
+}
+
+define <2 x double> @uitofp_v16i8_v2f64(<16 x i8> %a) {
+; CHECK-LABEL: uitofp_v16i8_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.hu.bu $xr0, $xr0
+; CHECK-NEXT: vext2xv.wu.hu $xr0, $xr0
+; CHECK-NEXT: vext2xv.du.wu $xr0, $xr0
+; CHECK-NEXT: xvffint.d.lu $xr0, $xr0
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
+; CHECK-NEXT: ret
+ %cvt = uitofp <16 x i8> %a to <16 x double>
+ %shuf = shufflevector <16 x double> %cvt, <16 x double> poison, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %shuf
+}
+
+define <4 x double> @uitofp_v4i8_v4f64(<16 x i8> %a) {
+; CHECK-LABEL: uitofp_v4i8_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.du.bu $xr0, $xr0
+; CHECK-NEXT: xvffint.d.lu $xr0, $xr0
+; CHECK-NEXT: ret
+ %shuf = shufflevector <16 x i8> %a, <16 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %cvt = uitofp <4 x i8> %shuf to <4 x double>
+ ret <4 x double> %cvt
+}
+
+define <4 x double> @uitofp_v16i8_v4f64(<16 x i8> %a) {
+; CHECK-LABEL: uitofp_v16i8_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $vr0 killed $vr0 def $xr0
+; CHECK-NEXT: vext2xv.hu.bu $xr0, $xr0
+; CHECK-NEXT: vext2xv.wu.hu $xr0, $xr0
+; CHECK-NEXT: vext2xv.du.wu $xr0, $xr0
+; CHECK-NEXT: xvffint.d.lu $xr0, $xr0
+; CHECK-NEXT: ret
+ %cvt = uitofp <16 x i8> %a to <16 x double>
+ %shuf = shufflevector <16 x double> %cvt, <16 x double> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ ret <4 x double> %shuf
+}
diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll
index 37eb9e7e8dc49..18a3bcd70b465 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/sitofp.ll
@@ -27,3 +27,172 @@ define void @sitofp_v2i64_v2f64(ptr %res, ptr %in){
store <2 x double> %v1, ptr %res
ret void
}
+
+define <4 x double> @sitofp_v4i64_v4f64(<4 x i64> %a) {
+; CHECK-LABEL: sitofp_v4i64_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: vffint.d.l $vr1, $vr1
+; CHECK-NEXT: ret
+ %cvt = sitofp <4 x i64> %a to <4 x double>
+ ret <4 x double> %cvt
+}
+
+define <4 x double> @sitofp_v4i32_v4f64(<4 x i32> %a) {
+; CHECK-LABEL: sitofp_v4i32_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vslti.w $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.w $vr2, $vr1, $vr0
+; CHECK-NEXT: vffint.d.l $vr2, $vr2
+; CHECK-NEXT: vilvh.w $vr0, $vr1, $vr0
+; CHECK-NEXT: vffint.d.l $vr1, $vr0
+; CHECK-NEXT: vori.b $vr0, $vr2, 0
+; CHECK-NEXT: ret
+ %cvt = sitofp <4 x i32> %a to <4 x double>
+ ret <4 x double> %cvt
+}
+
+define <2 x float> @sitofp_v2i32_v2f32(<2 x i32> %a) {
+; CHECK-LABEL: sitofp_v2i32_v2f32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vffint.s.w $vr0, $vr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <2 x i32> %a to <2 x float>
+ ret <2 x float> %cvt
+}
+
+define <2 x double> @sitofp_v4i32_v2f64(<4 x i32> %a) {
+; CHECK-LABEL: sitofp_v4i32_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vslti.w $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.w $vr0, $vr1, $vr0
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <4 x i32> %a to <4 x double>
+ %shuf = shufflevector <4 x double> %cvt, <4 x double> poison, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %shuf
+}
+
+define <2 x double> @sitofp_v2i16_v2f64(<8 x i16> %a) {
+; CHECK-LABEL: sitofp_v2i16_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vextrins.h $vr0, $vr0, 65
+; CHECK-NEXT: vslli.d $vr0, $vr0, 48
+; CHECK-NEXT: vsrai.d $vr0, $vr0, 48
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: ret
+ %shuf = shufflevector <8 x i16> %a, <8 x i16> poison, <2 x i32> <i32 0, i32 1>
+ %cvt = sitofp <2 x i16> %shuf to <2 x double>
+ ret <2 x double> %cvt
+}
+
+define <2 x double> @sitofp_v8i16_v2f64(<8 x i16> %a) {
+; CHECK-LABEL: sitofp_v8i16_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vslti.h $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.h $vr0, $vr1, $vr0
+; CHECK-NEXT: vslti.w $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.w $vr0, $vr1, $vr0
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <8 x i16> %a to <8 x double>
+ %shuf = shufflevector <8 x double> %cvt, <8 x double> poison, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %shuf
+}
+
+define <2 x double> @sitofp_v2i8_v2f64(<16 x i8> %a) {
+; CHECK-LABEL: sitofp_v2i8_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vextrins.b $vr0, $vr0, 129
+; CHECK-NEXT: vslli.d $vr0, $vr0, 56
+; CHECK-NEXT: vsrai.d $vr0, $vr0, 56
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: ret
+ %shuf = shufflevector <16 x i8> %a, <16 x i8> poison, <2 x i32> <i32 0, i32 1>
+ %cvt = sitofp <2 x i8> %shuf to <2 x double>
+ ret <2 x double> %cvt
+}
+
+define <2 x double> @sitofp_v16i8_v2f64(<16 x i8> %a) {
+; CHECK-LABEL: sitofp_v16i8_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vslti.b $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.b $vr0, $vr1, $vr0
+; CHECK-NEXT: vslti.h $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.h $vr0, $vr1, $vr0
+; CHECK-NEXT: vslti.w $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.w $vr0, $vr1, $vr0
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: ret
+ %cvt = sitofp <16 x i8> %a to <16 x double>
+ %shuf = shufflevector <16 x double> %cvt, <16 x double> poison, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %shuf
+}
+
+define <4 x double> @sitofp_v4i16_v4f64(<8 x i16> %a) {
+; CHECK-LABEL: sitofp_v4i16_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vslti.h $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.h $vr1, $vr1, $vr0
+; CHECK-NEXT: vslti.w $vr2, $vr1, 0
+; CHECK-NEXT: vilvl.w $vr0, $vr2, $vr1
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: vilvh.w $vr1, $vr2, $vr1
+; CHECK-NEXT: vffint.d.l $vr1, $vr1
+; CHECK-NEXT: ret
+ %shuf = shufflevector <8 x i16> %a, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %cvt = sitofp <4 x i16> %shuf to <4 x double>
+ ret <4 x double> %cvt
+}
+
+define <4 x double> @sitofp_v8i16_v4f64(<8 x i16> %a) {
+; CHECK-LABEL: sitofp_v8i16_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vslti.h $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.h $vr1, $vr1, $vr0
+; CHECK-NEXT: vslti.w $vr2, $vr1, 0
+; CHECK-NEXT: vilvl.w $vr0, $vr2, $vr1
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: vilvh.w $vr1, $vr2, $vr1
+; CHECK-NEXT: vffint.d.l $vr1, $vr1
+; CHECK-NEXT: ret
+ %cvt = sitofp <8 x i16> %a to <8 x double>
+ %shuf = shufflevector <8 x double> %cvt, <8 x double> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ ret <4 x double> %shuf
+}
+
+define <4 x double> @sitofp_v4i8_v4f64(<16 x i8> %a) {
+; CHECK-LABEL: sitofp_v4i8_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vilvl.b $vr0, $vr0, $vr0
+; CHECK-NEXT: vilvl.h $vr0, $vr0, $vr0
+; CHECK-NEXT: vslli.w $vr0, $vr0, 24
+; CHECK-NEXT: vsrai.w $vr1, $vr0, 24
+; CHECK-NEXT: vslti.w $vr2, $vr1, 0
+; CHECK-NEXT: vilvl.w $vr0, $vr2, $vr1
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: vilvh.w $vr1, $vr2, $vr1
+; CHECK-NEXT: vffint.d.l $vr1, $vr1
+; CHECK-NEXT: ret
+ %shuf = shufflevector <16 x i8> %a, <16 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %cvt = sitofp <4 x i8> %shuf to <4 x double>
+ ret <4 x double> %cvt
+}
+
+define <4 x double> @sitofp_v16i8_v4f64(<16 x i8> %a) {
+; CHECK-LABEL: sitofp_v16i8_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vslti.b $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.b $vr0, $vr1, $vr0
+; CHECK-NEXT: vslti.h $vr1, $vr0, 0
+; CHECK-NEXT: vilvl.h $vr1, $vr1, $vr0
+; CHECK-NEXT: vslti.w $vr2, $vr1, 0
+; CHECK-NEXT: vilvl.w $vr0, $vr2, $vr1
+; CHECK-NEXT: vffint.d.l $vr0, $vr0
+; CHECK-NEXT: vilvh.w $vr1, $vr2, $vr1
+; CHECK-NEXT: vffint.d.l $vr1, $vr1
+; CHECK-NEXT: ret
+ %cvt = sitofp <16 x i8> %a to <16 x double>
+ %shuf = shufflevector <16 x double> %cvt, <16 x double> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ ret <4 x double> %shuf
+}
diff --git a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll
index 3ae1119435eff..6d7a1b1554563 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/ir-instruction/uitofp.ll
@@ -27,3 +27,63 @@ define void @uitofp_v2i64_v2f64(ptr %res, ptr %in){
store <2 x double> %v1, ptr %res
ret void
}
+
+define <2 x double> @uitofp_v2i8_v2f64(<16 x i8> %a) {
+; CHECK-LABEL: uitofp_v2i8_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vrepli.b $vr1, 0
+; CHECK-NEXT: vilvl.b $vr0, $vr1, $vr0
+; CHECK-NEXT: vilvl.h $vr0, $vr1, $vr0
+; CHECK-NEXT: vilvl.w $vr0, $vr1, $vr0
+; CHECK-NEXT: vffint.d.lu $vr0, $vr0
+; CHECK-NEXT: ret
+ %shuf = shufflevector <16 x i8> %a, <16 x i8> poison, <2 x i32> <i32 0, i32 1>
+ %cvt = uitofp <2 x i8> %shuf to <2 x double>
+ ret <2 x double> %cvt
+}
+
+define <2 x double> @uitofp_v16i8_v2f64(<16 x i8> %a) {
+; CHECK-LABEL: uitofp_v16i8_v2f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vrepli.b $vr1, 0
+; CHECK-NEXT: vilvl.b $vr0, $vr1, $vr0
+; CHECK-NEXT: vilvl.h $vr0, $vr1, $vr0
+; CHECK-NEXT: vilvl.w $vr0, $vr1, $vr0
+; CHECK-NEXT: vffint.d.lu $vr0, $vr0
+; CHECK-NEXT: ret
+ %cvt = uitofp <16 x i8> %a to <16 x double>
+ %shuf = shufflevector <16 x double> %cvt, <16 x double> poison, <2 x i32> <i32 0, i32 1>
+ ret <2 x double> %shuf
+}
+
+define <4 x double> @uitofp_v4i8_v4f64(<16 x i8> %a) {
+; CHECK-LABEL: uitofp_v4i8_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vrepli.b $vr1, 0
+; CHECK-NEXT: vilvl.b $vr0, $vr1, $vr0
+; CHECK-NEXT: vilvl.h $vr2, $vr1, $vr0
+; CHECK-NEXT: vilvl.w $vr0, $vr1, $vr2
+; CHECK-NEXT: vffint.d.lu $vr0, $vr0
+; CHECK-NEXT: vilvh.w $vr1, $vr1, $vr2
+; CHECK-NEXT: vffint.d.lu $vr1, $vr1
+; CHECK-NEXT: ret
+ %shuf = shufflevector <16 x i8> %a, <16 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %cvt = uitofp <4 x i8> %shuf to <4 x double>
+ ret <4 x double> %cvt
+}
+
+define <4 x double> @uitofp_v16i8_v4f64(<16 x i8> %a) {
+; CHECK-LABEL: uitofp_v16i8_v4f64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vrepli.b $vr1, 0
+; CHECK-NEXT: vilvl.b $vr0, $vr1, $vr0
+; CHECK-NEXT: vilvl.h $vr2, $vr1, $vr0
+; CHECK-NEXT: vilvl.w $vr0, $vr1, $vr2
+; CHECK-NEXT: vffint.d.lu $vr0, $vr0
+; CHECK-NEXT: vilvh.w $vr1, $vr1, $vr2
+; CHECK-NEXT: vffint.d.lu $vr1, $vr1
+; CHECK-NEXT: ret
+ %cvt = uitofp <16 x i8> %a to <16 x double>
+ %shuf = shufflevector <16 x double> %cvt, <16 x double> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ ret <4 x double> %shuf
+}
More information about the llvm-commits
mailing list