[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
Sun Aug 4 22:53:31 PDT 2024
================
@@ -1099,34 +1099,101 @@ 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 >> 1) > 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 >> 1);
+ MVT VecVT = DstLT.second.changeVectorElementType(ElementVT);
+ Cost += getRISCVInstructionCost(FNCVT, VecVT, CostKind);
+ }
+ if ((SrcEltSize >> 1) > DstEltSize) {
+ // For mask type, we use:
+ // vand.vi v8, v9, 1
+ // vmsne.vi v0, v8, 0
+ VectorType *VecTy =
+ VectorType::get(IntegerType::get(Dst->getContext(), SrcEltSize >> 1),
+ cast<VectorType>(Dst)->getElementCount());
+ Cost +=
+ getCastInstrCost(Instruction::Trunc, Dst, VecTy, CCH, CostKind, I);
+ }
----------------
lukel97 wrote:
Can this be moved into the `SrcEltSize > DstEltSize` branch above, so we can reuse VecVT? Also I'm happy if you want to leave out the mask type comment, thanks for clarifying it in the reply to my review.
https://github.com/llvm/llvm-project/pull/87506
More information about the llvm-commits
mailing list