diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index ca4a655f06587..442a6d23795ad 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -386,6 +386,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM, setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom); setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom); } + // We want to legalize this to an f64 load rather than an i64 load. + setOperationAction(ISD::LOAD, MVT::v2f32, Custom); } // Set operations for 'LASX' feature. @@ -4668,6 +4670,32 @@ void LoongArchTargetLowering::ReplaceNodeResults( "Unexpected custom legalisation"); Results.push_back(customLegalizeToWOp(N, DAG, 2)); break; + case ISD::LOAD: { + // Use an f64 load and a scalar_to_vector for v2f32 loads. This avoids + // scalarizing in 32-bit mode. In 64-bit mode this avoids a int->fp + // cast since type legalization will try to use an i64 load. + MVT VT = N->getSimpleValueType(0); + assert(VT == MVT::v2f32 && "Unexpected VT"); + assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector && + "Unexpected type action!"); + if (!ISD::isNON_EXTLoad(N)) + return; + auto *Ld = cast(N); + if (Subtarget.hasExtLSX()) { + MVT LdVT = MVT::f64; + SDValue Res = DAG.getLoad(LdVT, DL, Ld->getChain(), Ld->getBasePtr(), + Ld->getPointerInfo(), Ld->getBaseAlign(), + Ld->getMemOperand()->getFlags()); + SDValue Chain = Res.getValue(1); + MVT VecVT = MVT::getVectorVT(LdVT, 2); + Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, Res); + EVT WideVT = getTypeToTransformTo(*DAG.getContext(), VT); + Res = DAG.getBitcast(WideVT, Res); + Results.push_back(Res); + Results.push_back(Chain); + } + break; + } case ISD::FP_TO_SINT: { assert(VT == MVT::i32 && Subtarget.is64Bit() && "Unexpected custom legalisation"); diff --git a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll b/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll index 16c9e754fb94d..48dd0b9e03bca 100644 --- a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll +++ b/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll @@ -123,8 +123,7 @@ define void @test_f2(ptr %P, ptr %S) nounwind { ; ; LA64D-LABEL: test_f2: ; LA64D: # %bb.0: -; LA64D-NEXT: ld.d $a0, $a0, 0 -; LA64D-NEXT: vinsgr2vr.d $vr0, $a0, 0 +; LA64D-NEXT: fld.d $fa0, $a0, 0 ; LA64D-NEXT: lu12i.w $a0, 260096 ; LA64D-NEXT: lu52i.d $a0, $a0, 1024 ; LA64D-NEXT: vreplgr2vr.d $vr1, $a0