[llvm] [RISCV][TTI] Scale the cost of FP-Int conversion with LMUL (PR #87506)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 14 02:58:50 PDT 2024
================
@@ -1099,34 +1099,90 @@ InstructionCost RISCVTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst,
return Cost;
}
case ISD::FP_TO_SINT:
- case ISD::FP_TO_UINT:
- // For fp vector to mask, we use:
- // vfncvt.rtz.x.f.w v9, v8
- // vand.vi v8, v9, 1
- // vmsne.vi v0, v8, 0
- if (Dst->getScalarSizeInBits() == 1)
- return 3;
-
- if (std::abs(PowDiff) <= 1)
- return 1;
+ case ISD::FP_TO_UINT: {
+ unsigned IsSigned = ISD == ISD::FP_TO_SINT;
+ unsigned FCVT = IsSigned ? RISCV::VFCVT_RTZ_X_F_V : RISCV::VFCVT_RTZ_XU_F_V;
+ unsigned FWCVT =
+ IsSigned ? RISCV::VFWCVT_RTZ_X_F_V : RISCV::VFWCVT_RTZ_XU_F_V;
+ unsigned FNCVT =
+ IsSigned ? RISCV::VFNCVT_RTZ_X_F_W : RISCV::VFNCVT_RTZ_XU_F_W;
+ unsigned SrcEltSize = Src->getScalarSizeInBits();
+ unsigned DstEltSize = Dst->getScalarSizeInBits();
+ InstructionCost Cost = 0;
+ if ((SrcEltSize == 16) &&
+ (!ST->hasVInstructionsF16() || ((DstEltSize / 2) > SrcEltSize))) {
+ // If the target only supports vfhmin or it is fp16-to-i64 conversion
+ // pre-widening to f32 and then convert f32 to integer
+ VectorType *VecF32Ty =
+ VectorType::get(Type::getFloatTy(Dst->getContext()),
+ cast<VectorType>(Dst)->getElementCount());
+ std::pair<InstructionCost, MVT> VecF32LT =
+ getTypeLegalizationCost(VecF32Ty);
+ Cost +=
+ VecF32LT.first * getRISCVInstructionCost(RISCV::VFWCVT_F_F_V,
+ VecF32LT.second, CostKind);
+ Cost += getCastInstrCost(Opcode, Dst, VecF32Ty, CCH, CostKind, I);
+ return Cost;
+ }
+ if (DstEltSize == SrcEltSize)
+ Cost += getRISCVInstructionCost(FCVT, DstLT.second, CostKind);
+ else if (DstEltSize > SrcEltSize)
+ Cost += getRISCVInstructionCost(FWCVT, DstLT.second, CostKind);
+ else { // (SrcEltSize > DstEltSize)
+ // First do a narrowing conversion to an integer half the size, then
+ // truncate if needed.
+ MVT ElementVT = MVT::getIntegerVT(SrcEltSize / 2);
+ MVT VecVT = DstLT.second.changeVectorElementType(ElementVT);
+ Cost += getRISCVInstructionCost(FNCVT, VecVT, CostKind);
+ if ((SrcEltSize / 2) > DstEltSize) {
+ Type *VecTy = EVT(VecVT).getTypeForEVT(Dst->getContext());
+ Cost +=
+ getCastInstrCost(Instruction::Trunc, Dst, VecTy, CCH, CostKind, I);
----------------
lukel97 wrote:
Ah ok, so it looks like after #101047 the types should still never be split. Can we add an assert somewhere below the new check that SrcLT.first & DstLT.first are always one?
https://github.com/llvm/llvm-project/pull/87506
More information about the llvm-commits
mailing list