[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