//===-- RISCVTargetTransformInfo.cpp - RISC-V specific TTI ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "RISCVTargetTransformInfo.h"
#include "MCTargetDesc/RISCVMatInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/BasicTTIImpl.h"
#include "llvm/CodeGen/CostTable.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include <cmath>
#include <optional>
using namespace llvm;
using namespace llvm::PatternMatch;

#define DEBUG_TYPE "riscvtti"

static cl::opt<unsigned> RVVRegisterWidthLMUL(
    "riscv-v-register-bit-width-lmul",
    cl::desc(
        "The LMUL to use for getRegisterBitWidth queries. Affects LMUL used "
        "by autovectorized code. Fractional LMULs are not supported."),
    cl::init(2), cl::Hidden);

static cl::opt<unsigned> SLPMaxVF(
    "riscv-v-slp-max-vf",
    cl::desc(
        "Overrides result used for getMaximumVF query which is used "
        "exclusively by SLP vectorizer."),
    cl::Hidden);

static cl::opt<unsigned>
    RVVMinTripCount("riscv-v-min-trip-count",
                    cl::desc("Set the lower bound of a trip count to decide on "
                             "vectorization while tail-folding."),
                    cl::init(5), cl::Hidden);

static cl::opt<bool> EnableOrLikeSelectOpt("enable-riscv-or-like-select",
                                           cl::init(true), cl::Hidden);

InstructionCost
RISCVTTIImpl::getRISCVInstructionCost(ArrayRef<unsigned> OpCodes, MVT VT,
                                      TTI::TargetCostKind CostKind) const {
  // Check if the type is valid for all CostKind
  if (!VT.isVector())
    return InstructionCost::getInvalid();
  size_t NumInstr = OpCodes.size();
  if (CostKind == TTI::TCK_CodeSize)
    return NumInstr;
  InstructionCost LMULCost = TLI->getLMULCost(VT);
  if ((CostKind != TTI::TCK_RecipThroughput) && (CostKind != TTI::TCK_Latency))
    return LMULCost * NumInstr;
  InstructionCost Cost = 0;
  for (auto Op : OpCodes) {
    switch (Op) {
    case RISCV::VRGATHER_VI:
      Cost += TLI->getVRGatherVICost(VT);
      break;
    case RISCV::VRGATHER_VV:
      Cost += TLI->getVRGatherVVCost(VT);
      break;
    case RISCV::VSLIDEUP_VI:
    case RISCV::VSLIDEDOWN_VI:
      Cost += TLI->getVSlideVICost(VT);
      break;
    case RISCV::VSLIDEUP_VX:
    case RISCV::VSLIDEDOWN_VX:
      Cost += TLI->getVSlideVXCost(VT);
      break;
    case RISCV::VREDMAX_VS:
    case RISCV::VREDMIN_VS:
    case RISCV::VREDMAXU_VS:
    case RISCV::VREDMINU_VS:
    case RISCV::VREDSUM_VS:
    case RISCV::VREDAND_VS:
    case RISCV::VREDOR_VS:
    case RISCV::VREDXOR_VS:
    case RISCV::VFREDMAX_VS:
    case RISCV::VFREDMIN_VS:
    case RISCV::VFREDUSUM_VS: {
      unsigned VL = VT.getVectorMinNumElements();
      if (!VT.isFixedLengthVector())
        VL *= *getVScaleForTuning();
      Cost += Log2_32_Ceil(VL);
      break;
    }
    case RISCV::VFREDOSUM_VS: {
      unsigned VL = VT.getVectorMinNumElements();
      if (!VT.isFixedLengthVector())
        VL *= *getVScaleForTuning();
      Cost += VL;
      break;
    }
    case RISCV::VMV_X_S:
    case RISCV::VMV_S_X:
    case RISCV::VFMV_F_S:
    case RISCV::VFMV_S_F:
    case RISCV::VMOR_MM:
    case RISCV::VMXOR_MM:
    case RISCV::VMAND_MM:
    case RISCV::VMANDN_MM:
    case RISCV::VMNAND_MM:
    case RISCV::VCPOP_M:
    case RISCV::VFIRST_M:
      Cost += 1;
      break;
    case RISCV::VDIV_VV:
    case RISCV::VREM_VV:
      Cost += LMULCost * TTI::TCC_Expensive;
      break;
    default:
      Cost += LMULCost;
    }
  }
  return Cost;
}

static InstructionCost getIntImmCostImpl(const DataLayout &DL,
                                         const RISCVSubtarget *ST,
                                         const APInt &Imm, Type *Ty,
                                         TTI::TargetCostKind CostKind,
                                         bool FreeZeroes) {
  assert(Ty->isIntegerTy() &&
         "getIntImmCost can only estimate cost of materialising integers");

  // We have a Zero register, so 0 is always free.
  if (Imm == 0)
    return TTI::TCC_Free;

  // Otherwise, we check how many instructions it will take to materialise.
  return RISCVMatInt::getIntMatCost(Imm, DL.getTypeSizeInBits(Ty), *ST,
                                    /*CompressionCost=*/false, FreeZeroes);
}

InstructionCost
RISCVTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
                            TTI::TargetCostKind CostKind) const {
  return getIntImmCostImpl(getDataLayout(), getST(), Imm, Ty, CostKind, false);
}

// Look for patterns of shift followed by AND that can be turned into a pair of
// shifts. We won't need to materialize an immediate for the AND so these can
// be considered free.
static bool canUseShiftPair(Instruction *Inst, const APInt &Imm) {
  uint64_t Mask = Imm.getZExtValue();
  auto *BO = dyn_cast<BinaryOperator>(Inst->getOperand(0));
  if (!BO || !BO->hasOneUse())
    return false;

  if (BO->getOpcode() != Instruction::Shl)
    return false;

  if (!isa<ConstantInt>(BO->getOperand(1)))
    return false;

  unsigned ShAmt = cast<ConstantInt>(BO->getOperand(1))->getZExtValue();
  // (and (shl x, c2), c1) will be matched to (srli (slli x, c2+c3), c3) if c1
  // is a mask shifted by c2 bits with c3 leading zeros.
  if (isShiftedMask_64(Mask)) {
    unsigned Trailing = llvm::countr_zero(Mask);
    if (ShAmt == Trailing)
      return true;
  }

  return false;
}

// If this is i64 AND is part of (X & -(1 << C1) & 0xffffffff) == C2 << C1),
// DAGCombiner can convert this to (sraiw X, C1) == sext(C2) for RV64. On RV32,
// the type will be split so only the lower 32 bits need to be compared using
// (srai/srli X, C) == C2.
static bool canUseShiftCmp(Instruction *Inst, const APInt &Imm) {
  if (!Inst->hasOneUse())
    return false;

  // Look for equality comparison.
  auto *Cmp = dyn_cast<ICmpInst>(*Inst->user_begin());
  if (!Cmp || !Cmp->isEquality())
    return false;

  // Right hand side of comparison should be a constant.
  auto *C = dyn_cast<ConstantInt>(Cmp->getOperand(1));
  if (!C)
    return false;

  uint64_t Mask = Imm.getZExtValue();

  // Mask should be of the form -(1 << C) in the lower 32 bits.
  if (!isUInt<32>(Mask) || !isPowerOf2_32(-uint32_t(Mask)))
    return false;

  // Comparison constant should be a subset of Mask.
  uint64_t CmpC = C->getZExtValue();
  if ((CmpC & Mask) != CmpC)
    return false;

  // We'll need to sign extend the comparison constant and shift it right. Make
  // sure the new constant can use addi/xori+seqz/snez.
  unsigned ShiftBits = llvm::countr_zero(Mask);
  int64_t NewCmpC = SignExtend64<32>(CmpC) >> ShiftBits;
  return NewCmpC >= -2048 && NewCmpC <= 2048;
}

InstructionCost RISCVTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
                                                const APInt &Imm, Type *Ty,
                                                TTI::TargetCostKind CostKind,
                                                Instruction *Inst) const {
  assert(Ty->isIntegerTy() &&
         "getIntImmCost can only estimate cost of materialising integers");

  // We have a Zero register, so 0 is always free.
  if (Imm == 0)
    return TTI::TCC_Free;

  // Some instructions in RISC-V can take a 12-bit immediate. Some of these are
  // commutative, in others the immediate comes from a specific argument index.
  bool Takes12BitImm = false;
  unsigned ImmArgIdx = ~0U;

  switch (Opcode) {
  case Instruction::GetElementPtr:
    // Never hoist any arguments to a GetElementPtr. CodeGenPrepare will
    // split up large offsets in GEP into better parts than ConstantHoisting
    // can.
    return TTI::TCC_Free;
  case Instruction::Store: {
    // Use the materialization cost regardless of if it's the address or the
    // value that is constant, except for if the store is misaligned and
    // misaligned accesses are not legal (experience shows constant hoisting
    // can sometimes be harmful in such cases).
    if (Idx == 1 || !Inst)
      return getIntImmCostImpl(getDataLayout(), getST(), Imm, Ty, CostKind,
                               /*FreeZeroes=*/true);

    StoreInst *ST = cast<StoreInst>(Inst);
    if (!getTLI()->allowsMemoryAccessForAlignment(
            Ty->getContext(), DL, getTLI()->getValueType(DL, Ty),
            ST->getPointerAddressSpace(), ST->getAlign()))
      return TTI::TCC_Free;

    return getIntImmCostImpl(getDataLayout(), getST(), Imm, Ty, CostKind,
                             /*FreeZeroes=*/true);
  }
  case Instruction::Load:
    // If the address is a constant, use the materialization cost.
    return getIntImmCost(Imm, Ty, CostKind);
  case Instruction::And:
    // zext.h
    if (Imm == UINT64_C(0xffff) && ST->hasStdExtZbb())
      return TTI::TCC_Free;
    // zext.w
    if (Imm == UINT64_C(0xffffffff) &&
        ((ST->hasStdExtZba() && ST->isRV64()) || ST->isRV32()))
      return TTI::TCC_Free;
    // bclri
    if (ST->hasStdExtZbs() && (~Imm).isPowerOf2())
      return TTI::TCC_Free;
    if (Inst && Idx == 1 && Imm.getBitWidth() <= ST->getXLen() &&
        canUseShiftPair(Inst, Imm))
      return TTI::TCC_Free;
    if (Inst && Idx == 1 && Imm.getBitWidth() == 64 &&
        canUseShiftCmp(Inst, Imm))
      return TTI::TCC_Free;
    Takes12BitImm = true;
    break;
  case Instruction::Add:
    Takes12BitImm = true;
    break;
  case Instruction::Or:
  case Instruction::Xor:
    // bseti/binvi
    if (ST->hasStdExtZbs() && Imm.isPowerOf2())
      return TTI::TCC_Free;
    Takes12BitImm = true;
    break;
  case Instruction::Mul:
    // Power of 2 is a shift. Negated power of 2 is a shift and a negate.
    if (Imm.isPowerOf2() || Imm.isNegatedPowerOf2())
      return TTI::TCC_Free;
    // One more or less than a power of 2 can use SLLI+ADD/SUB.
    if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2())
      return TTI::TCC_Free;
    // FIXME: There is no MULI instruction.
    Takes12BitImm = true;
    break;
  case Instruction::Sub:
  case Instruction::Shl:
  case Instruction::LShr:
  case Instruction::AShr:
    Takes12BitImm = true;
    ImmArgIdx = 1;
    break;
  default:
    break;
  }

  if (Takes12BitImm) {
    // Check immediate is the correct argument...
    if (Instruction::isCommutative(Opcode) || Idx == ImmArgIdx) {
      // ... and fits into the 12-bit immediate.
      if (Imm.getSignificantBits() <= 64 &&
          getTLI()->isLegalAddImmediate(Imm.getSExtValue())) {
        return TTI::TCC_Free;
      }
    }

    // Otherwise, use the full materialisation cost.
    return getIntImmCost(Imm, Ty, CostKind);
  }

  // By default, prevent hoisting.
  return TTI::TCC_Free;
}

InstructionCost
RISCVTTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
                                  const APInt &Imm, Type *Ty,
                                  TTI::TargetCostKind CostKind) const {
  // Prevent hoisting in unknown cases.
  return TTI::TCC_Free;
}

bool RISCVTTIImpl::hasActiveVectorLength() const {
  return ST->hasVInstructions();
}

TargetTransformInfo::PopcntSupportKind
RISCVTTIImpl::getPopcntSupport(unsigned TyWidth) const {
  assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
  return ST->hasCPOPLike() ? TTI::PSK_FastHardware : TTI::PSK_Software;
}

InstructionCost RISCVTTIImpl::getPartialReductionCost(
    unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
    ElementCount VF, TTI::PartialReductionExtendKind OpAExtend,
    TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
    TTI::TargetCostKind CostKind, std::optional<FastMathFlags> FMF) const {
  if (Opcode == Instruction::FAdd)
    return InstructionCost::getInvalid();

  // zve32x is broken for partial_reduce_umla, but let's make sure we
  // don't generate them.
  if (!ST->hasStdExtZvdot4a8i() || ST->getELen() < 64 ||
      Opcode != Instruction::Add || !BinOp || *BinOp != Instruction::Mul ||
      InputTypeA != InputTypeB || !InputTypeA->isIntegerTy(8) ||
      !AccumType->isIntegerTy(32) || !VF.isKnownMultipleOf(4))
    return InstructionCost::getInvalid();

  Type *Tp = VectorType::get(AccumType, VF.divideCoefficientBy(4));
  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Tp);
  // Note: Asuming all vdota4* variants are equal cost
  return LT.first *
         getRISCVInstructionCost(RISCV::VDOTA4_VV, LT.second, CostKind);
}

bool RISCVTTIImpl::shouldExpandReduction(const IntrinsicInst *II) const {
  // Currently, the ExpandReductions pass can't expand scalable-vector
  // reductions, but we still request expansion as RVV doesn't support certain
  // reductions and the SelectionDAG can't legalize them either.
  switch (II->getIntrinsicID()) {
  default:
    return false;
  // These reductions have no equivalent in RVV
  case Intrinsic::vector_reduce_mul:
  case Intrinsic::vector_reduce_fmul:
    return true;
  }
}

std::optional<unsigned> RISCVTTIImpl::getMaxVScale() const {
  if (ST->hasVInstructions())
    return ST->getRealMaxVLen() / RISCV::RVVBitsPerBlock;
  return BaseT::getMaxVScale();
}

std::optional<unsigned> RISCVTTIImpl::getVScaleForTuning() const {
  if (ST->hasVInstructions())
    if (unsigned MinVLen = ST->getRealMinVLen();
        MinVLen >= RISCV::RVVBitsPerBlock)
      return MinVLen / RISCV::RVVBitsPerBlock;
  return BaseT::getVScaleForTuning();
}

TypeSize
RISCVTTIImpl::getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const {
  unsigned LMUL =
      llvm::bit_floor(std::clamp<unsigned>(RVVRegisterWidthLMUL, 1, 8));
  switch (K) {
  case TargetTransformInfo::RGK_Scalar:
    return TypeSize::getFixed(ST->getXLen());
  case TargetTransformInfo::RGK_FixedWidthVector:
    return TypeSize::getFixed(
        ST->useRVVForFixedLengthVectors() ? LMUL * ST->getRealMinVLen() : 0);
  case TargetTransformInfo::RGK_ScalableVector:
    return TypeSize::getScalable(
        (ST->hasVInstructions() &&
         ST->getRealMinVLen() >= RISCV::RVVBitsPerBlock)
            ? LMUL * RISCV::RVVBitsPerBlock
            : 0);
  }

  llvm_unreachable("Unsupported register kind");
}

InstructionCost RISCVTTIImpl::getStaticDataAddrGenerationCost(
    const TTI::TargetCostKind CostKind) const {
  switch (CostKind) {
  case TTI::TCK_CodeSize:
  case TTI::TCK_SizeAndLatency:
    // Always 2 instructions
    return 2;
  case TTI::TCK_Latency:
  case TTI::TCK_RecipThroughput:
    // Depending on the memory model the address generation will
    // require AUIPC + ADDI (medany) or LUI + ADDI (medlow). Don't
    // have a way of getting this information here, so conservatively
    // require both.
    // In practice, these are generally implemented together.
    return (ST->hasAUIPCADDIFusion() && ST->hasLUIADDIFusion()) ? 1 : 2;
  }
  llvm_unreachable("Unsupported cost kind");
}

InstructionCost
RISCVTTIImpl::getConstantPoolLoadCost(Type *Ty,
                                      TTI::TargetCostKind CostKind) const {
  // Add a cost of address generation + the cost of the load. The address
  // is expected to be a PC relative offset to a constant pool entry
  // using auipc/addi.
  return getStaticDataAddrGenerationCost(CostKind) +
         getMemoryOpCost(Instruction::Load, Ty, DL.getABITypeAlign(Ty),
                         /*AddressSpace=*/0, CostKind);
}

static bool isRepeatedConcatMask(ArrayRef<int> Mask, int &SubVectorSize) {
  unsigned Size = Mask.size();
  if (!isPowerOf2_32(Size))
    return false;
  for (unsigned I = 0; I != Size; ++I) {
    if (static_cast<unsigned>(Mask[I]) == I)
      continue;
    if (Mask[I] != 0)
      return false;
    if (Size % I != 0)
      return false;
    for (unsigned J = I + 1; J != Size; ++J)
      // Check the pattern is repeated.
      if (static_cast<unsigned>(Mask[J]) != J % I)
        return false;
    SubVectorSize = I;
    return true;
  }
  // That means Mask is <0, 1, 2, 3>. This is not a concatenation.
  return false;
}

static VectorType *getVRGatherIndexType(MVT DataVT, const RISCVSubtarget &ST,
                                        LLVMContext &C) {
  assert((DataVT.getScalarSizeInBits() != 8 ||
          DataVT.getVectorNumElements() <= 256) && "unhandled case in lowering");
  MVT IndexVT = DataVT.changeTypeToInteger();
  if (IndexVT.getScalarType().bitsGT(ST.getXLenVT()))
    IndexVT = IndexVT.changeVectorElementType(MVT::i16);
  return cast<VectorType>(EVT(IndexVT).getTypeForEVT(C));
}

/// Attempt to approximate the cost of a shuffle which will require splitting
/// during legalization.  Note that processShuffleMasks is not an exact proxy
/// for the algorithm used in LegalizeVectorTypes, but hopefully it's a
/// reasonably close upperbound.
static InstructionCost costShuffleViaSplitting(const RISCVTTIImpl &TTI,
                                               MVT LegalVT, VectorType *Tp,
                                               ArrayRef<int> Mask,
                                               TTI::TargetCostKind CostKind) {
  assert(LegalVT.isFixedLengthVector() && !Mask.empty() &&
         "Expected fixed vector type and non-empty mask");
  unsigned LegalNumElts = LegalVT.getVectorNumElements();
  // Number of destination vectors after legalization:
  unsigned NumOfDests = divideCeil(Mask.size(), LegalNumElts);
  // We are going to permute multiple sources and the result will be in
  // multiple destinations. Providing an accurate cost only for splits where
  // the element type remains the same.
  if (NumOfDests <= 1 ||
      LegalVT.getVectorElementType().getSizeInBits() !=
          Tp->getElementType()->getPrimitiveSizeInBits() ||
      LegalNumElts >= Tp->getElementCount().getFixedValue())
    return InstructionCost::getInvalid();

  unsigned VecTySize = TTI.getDataLayout().getTypeStoreSize(Tp);
  unsigned LegalVTSize = LegalVT.getStoreSize();
  // Number of source vectors after legalization:
  unsigned NumOfSrcs = divideCeil(VecTySize, LegalVTSize);

  auto *SingleOpTy = FixedVectorType::get(Tp->getElementType(), LegalNumElts);

  unsigned NormalizedVF = LegalNumElts * std::max(NumOfSrcs, NumOfDests);
  unsigned NumOfSrcRegs = NormalizedVF / LegalNumElts;
  unsigned NumOfDestRegs = NormalizedVF / LegalNumElts;
  SmallVector<int> NormalizedMask(NormalizedVF, PoisonMaskElem);
  assert(NormalizedVF >= Mask.size() &&
         "Normalized mask expected to be not shorter than original mask.");
  copy(Mask, NormalizedMask.begin());
  InstructionCost Cost = 0;
  SmallDenseSet<std::pair<ArrayRef<int>, unsigned>> ReusedSingleSrcShuffles;
  processShuffleMasks(
      NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
      [&](ArrayRef<int> RegMask, unsigned SrcReg, unsigned DestReg) {
        if (ShuffleVectorInst::isIdentityMask(RegMask, RegMask.size()))
          return;
        if (!ReusedSingleSrcShuffles.insert(std::make_pair(RegMask, SrcReg))
                 .second)
          return;
        Cost += TTI.getShuffleCost(
            TTI::SK_PermuteSingleSrc,
            FixedVectorType::get(SingleOpTy->getElementType(), RegMask.size()),
            SingleOpTy, RegMask, CostKind, 0, nullptr);
      },
      [&](ArrayRef<int> RegMask, unsigned Idx1, unsigned Idx2, bool NewReg) {
        Cost += TTI.getShuffleCost(
            TTI::SK_PermuteTwoSrc,
            FixedVectorType::get(SingleOpTy->getElementType(), RegMask.size()),
            SingleOpTy, RegMask, CostKind, 0, nullptr);
      });
  return Cost;
}

/// Try to perform better estimation of the permutation.
/// 1. Split the source/destination vectors into real registers.
/// 2. Do the mask analysis to identify which real registers are
/// permuted. If more than 1 source registers are used for the
/// destination register building, the cost for this destination register
/// is (Number_of_source_register - 1) * Cost_PermuteTwoSrc. If only one
/// source register is used, build mask and calculate the cost as a cost
/// of PermuteSingleSrc.
/// Also, for the single register permute we try to identify if the
/// destination register is just a copy of the source register or the
/// copy of the previous destination register (the cost is
/// TTI::TCC_Basic). If the source register is just reused, the cost for
/// this operation is 0.
static InstructionCost
costShuffleViaVRegSplitting(const RISCVTTIImpl &TTI, MVT LegalVT,
                            std::optional<unsigned> VLen, VectorType *Tp,
                            ArrayRef<int> Mask, TTI::TargetCostKind CostKind) {
  assert(LegalVT.isFixedLengthVector());
  if (!VLen || Mask.empty())
    return InstructionCost::getInvalid();
  MVT ElemVT = LegalVT.getVectorElementType();
  unsigned ElemsPerVReg = *VLen / ElemVT.getFixedSizeInBits();
  LegalVT = TTI.getTypeLegalizationCost(
                   FixedVectorType::get(Tp->getElementType(), ElemsPerVReg))
                .second;
  // Number of destination vectors after legalization:
  InstructionCost NumOfDests =
      divideCeil(Mask.size(), LegalVT.getVectorNumElements());
  if (NumOfDests <= 1 ||
      LegalVT.getVectorElementType().getSizeInBits() !=
          Tp->getElementType()->getPrimitiveSizeInBits() ||
      LegalVT.getVectorNumElements() >= Tp->getElementCount().getFixedValue())
    return InstructionCost::getInvalid();

  unsigned VecTySize = TTI.getDataLayout().getTypeStoreSize(Tp);
  unsigned LegalVTSize = LegalVT.getStoreSize();
  // Number of source vectors after legalization:
  unsigned NumOfSrcs = divideCeil(VecTySize, LegalVTSize);

  auto *SingleOpTy = FixedVectorType::get(Tp->getElementType(),
                                          LegalVT.getVectorNumElements());

  unsigned E = NumOfDests.getValue();
  unsigned NormalizedVF =
      LegalVT.getVectorNumElements() * std::max(NumOfSrcs, E);
  unsigned NumOfSrcRegs = NormalizedVF / LegalVT.getVectorNumElements();
  unsigned NumOfDestRegs = NormalizedVF / LegalVT.getVectorNumElements();
  SmallVector<int> NormalizedMask(NormalizedVF, PoisonMaskElem);
  assert(NormalizedVF >= Mask.size() &&
         "Normalized mask expected to be not shorter than original mask.");
  copy(Mask, NormalizedMask.begin());
  InstructionCost Cost = 0;
  int NumShuffles = 0;
  SmallDenseSet<std::pair<ArrayRef<int>, unsigned>> ReusedSingleSrcShuffles;
  processShuffleMasks(
      NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
      [&](ArrayRef<int> RegMask, unsigned SrcReg, unsigned DestReg) {
        if (ShuffleVectorInst::isIdentityMask(RegMask, RegMask.size()))
          return;
        if (!ReusedSingleSrcShuffles.insert(std::make_pair(RegMask, SrcReg))
                 .second)
          return;
        ++NumShuffles;
        Cost += TTI.getShuffleCost(TTI::SK_PermuteSingleSrc, SingleOpTy,
                                   SingleOpTy, RegMask, CostKind, 0, nullptr);
      },
      [&](ArrayRef<int> RegMask, unsigned Idx1, unsigned Idx2, bool NewReg) {
        Cost += TTI.getShuffleCost(TTI::SK_PermuteTwoSrc, SingleOpTy,
                                   SingleOpTy, RegMask, CostKind, 0, nullptr);
        NumShuffles += 2;
      });
  // Note: check that we do not emit too many shuffles here to prevent code
  // size explosion.
  // TODO: investigate, if it can be improved by extra analysis of the masks
  // to check if the code is more profitable.
  if ((NumOfDestRegs > 2 && NumShuffles <= static_cast<int>(NumOfDestRegs)) ||
      (NumOfDestRegs <= 2 && NumShuffles < 4))
    return Cost;
  return InstructionCost::getInvalid();
}

InstructionCost RISCVTTIImpl::getSlideCost(FixedVectorType *Tp,
                                           ArrayRef<int> Mask,
                                           TTI::TargetCostKind CostKind) const {
  // Avoid missing masks and length changing shuffles
  if (Mask.size() <= 2 || Mask.size() != Tp->getNumElements())
    return InstructionCost::getInvalid();

  int NumElts = Tp->getNumElements();
  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Tp);
  // Avoid scalarization cases
  if (!LT.second.isFixedLengthVector())
    return InstructionCost::getInvalid();

  // Requires moving elements between parts, which requires additional
  // unmodeled instructions.
  if (LT.first != 1)
    return InstructionCost::getInvalid();

  auto GetSlideOpcode = [&](int SlideAmt) {
    assert(SlideAmt != 0);
    bool IsVI = isUInt<5>(std::abs(SlideAmt));
    if (SlideAmt < 0)
      return IsVI ? RISCV::VSLIDEDOWN_VI : RISCV::VSLIDEDOWN_VX;
    return IsVI ? RISCV::VSLIDEUP_VI : RISCV::VSLIDEUP_VX;
  };

  std::array<std::pair<int, int>, 2> SrcInfo;
  if (!isMaskedSlidePair(Mask, NumElts, SrcInfo))
    return InstructionCost::getInvalid();

  if (SrcInfo[1].second == 0)
    std::swap(SrcInfo[0], SrcInfo[1]);

  InstructionCost FirstSlideCost = 0;
  if (SrcInfo[0].second != 0) {
    unsigned Opcode = GetSlideOpcode(SrcInfo[0].second);
    FirstSlideCost = getRISCVInstructionCost(Opcode, LT.second, CostKind);
  }

  if (SrcInfo[1].first == -1)
    return FirstSlideCost;

  InstructionCost SecondSlideCost = 0;
  if (SrcInfo[1].second != 0) {
    unsigned Opcode = GetSlideOpcode(SrcInfo[1].second);
    SecondSlideCost = getRISCVInstructionCost(Opcode, LT.second, CostKind);
  } else {
    SecondSlideCost =
        getRISCVInstructionCost(RISCV::VMERGE_VVM, LT.second, CostKind);
  }

  auto EC = Tp->getElementCount();
  VectorType *MaskTy =
      VectorType::get(IntegerType::getInt1Ty(Tp->getContext()), EC);
  InstructionCost MaskCost = getConstantPoolLoadCost(MaskTy, CostKind);
  return FirstSlideCost + SecondSlideCost + MaskCost;
}

InstructionCost
RISCVTTIImpl::getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy,
                             VectorType *SrcTy, ArrayRef<int> Mask,
                             TTI::TargetCostKind CostKind, int Index,
                             VectorType *SubTp, ArrayRef<const Value *> Args,
                             const Instruction *CxtI) const {
  assert((Mask.empty() || DstTy->isScalableTy() ||
          Mask.size() == DstTy->getElementCount().getKnownMinValue()) &&
         "Expected the Mask to match the return size if given");
  assert(SrcTy->getScalarType() == DstTy->getScalarType() &&
         "Expected the same scalar types");

  Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);

  // TODO: Add proper cost model for P extension fixed vectors (e.g., v4i16)
  // For now, skip all fixed vector cost analysis when P extension is available
  // to avoid crashes in getMinRVVVectorSizeInBits()
  if (ST->hasStdExtP() && isa<FixedVectorType>(SrcTy))
    return 1;

  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcTy);

  // First, handle cases where having a fixed length vector enables us to
  // give a more accurate cost than falling back to generic scalable codegen.
  // TODO: Each of these cases hints at a modeling gap around scalable vectors.
  if (auto *FVTp = dyn_cast<FixedVectorType>(SrcTy);
      FVTp && ST->hasVInstructions() && LT.second.isFixedLengthVector()) {
    InstructionCost VRegSplittingCost = costShuffleViaVRegSplitting(
        *this, LT.second, ST->getRealVLen(),
        Kind == TTI::SK_InsertSubvector ? DstTy : SrcTy, Mask, CostKind);
    if (VRegSplittingCost.isValid())
      return VRegSplittingCost;
    switch (Kind) {
    default:
      break;
    case TTI::SK_PermuteSingleSrc: {
      if (Mask.size() >= 2) {
        MVT EltTp = LT.second.getVectorElementType();
        // If the size of the element is < ELEN then shuffles of interleaves and
        // deinterleaves of 2 vectors can be lowered into the following
        // sequences
        if (EltTp.getScalarSizeInBits() < ST->getELen()) {
          // Example sequence:
          //   vsetivli     zero, 4, e8, mf4, ta, ma (ignored)
          //   vwaddu.vv    v10, v8, v9
          //   li       a0, -1                   (ignored)
          //   vwmaccu.vx   v10, a0, v9
          if (ShuffleVectorInst::isInterleaveMask(Mask, 2, Mask.size()))
            return 2 * LT.first * TLI->getLMULCost(LT.second);

          if (Mask[0] == 0 || Mask[0] == 1) {
            auto DeinterleaveMask = createStrideMask(Mask[0], 2, Mask.size());
            // Example sequence:
            //   vnsrl.wi   v10, v8, 0
            if (equal(DeinterleaveMask, Mask))
              return LT.first * getRISCVInstructionCost(RISCV::VNSRL_WI,
                                                        LT.second, CostKind);
          }
        }
        int SubVectorSize;
        if (LT.second.getScalarSizeInBits() != 1 &&
            isRepeatedConcatMask(Mask, SubVectorSize)) {
          InstructionCost Cost = 0;
          unsigned NumSlides = Log2_32(Mask.size() / SubVectorSize);
          // The cost of extraction from a subvector is 0 if the index is 0.
          for (unsigned I = 0; I != NumSlides; ++I) {
            unsigned InsertIndex = SubVectorSize * (1 << I);
            FixedVectorType *SubTp =
                FixedVectorType::get(SrcTy->getElementType(), InsertIndex);
            FixedVectorType *DestTp =
                FixedVectorType::getDoubleElementsVectorType(SubTp);
            std::pair<InstructionCost, MVT> DestLT =
                getTypeLegalizationCost(DestTp);
            // Add the cost of whole vector register move because the
            // destination vector register group for vslideup cannot overlap the
            // source.
            Cost += DestLT.first * TLI->getLMULCost(DestLT.second);
            Cost += getShuffleCost(TTI::SK_InsertSubvector, DestTp, DestTp, {},
                                   CostKind, InsertIndex, SubTp);
          }
          return Cost;
        }
      }

      if (InstructionCost SlideCost = getSlideCost(FVTp, Mask, CostKind);
          SlideCost.isValid())
        return SlideCost;

      // vrgather + cost of generating the mask constant.
      // We model this for an unknown mask with a single vrgather.
      if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
                            LT.second.getVectorNumElements() <= 256)) {
        VectorType *IdxTy =
            getVRGatherIndexType(LT.second, *ST, SrcTy->getContext());
        InstructionCost IndexCost = getConstantPoolLoadCost(IdxTy, CostKind);
        return IndexCost +
               getRISCVInstructionCost(RISCV::VRGATHER_VV, LT.second, CostKind);
      }
      break;
    }
    case TTI::SK_Transpose:
    case TTI::SK_PermuteTwoSrc: {

      if (InstructionCost SlideCost = getSlideCost(FVTp, Mask, CostKind);
          SlideCost.isValid())
        return SlideCost;

      // 2 x (vrgather + cost of generating the mask constant) + cost of mask
      // register for the second vrgather. We model this for an unknown
      // (shuffle) mask.
      if (LT.first == 1 && (LT.second.getScalarSizeInBits() != 8 ||
                            LT.second.getVectorNumElements() <= 256)) {
        auto &C = SrcTy->getContext();
        auto EC = SrcTy->getElementCount();
        VectorType *IdxTy = getVRGatherIndexType(LT.second, *ST, C);
        VectorType *MaskTy = VectorType::get(IntegerType::getInt1Ty(C), EC);
        InstructionCost IndexCost = getConstantPoolLoadCost(IdxTy, CostKind);
        InstructionCost MaskCost = getConstantPoolLoadCost(MaskTy, CostKind);
        return 2 * IndexCost +
               getRISCVInstructionCost({RISCV::VRGATHER_VV, RISCV::VRGATHER_VV},
                                       LT.second, CostKind) +
               MaskCost;
      }
      break;
    }
    }

    auto shouldSplit = [](TTI::ShuffleKind Kind) {
      switch (Kind) {
      default:
        return false;
      case TTI::SK_PermuteSingleSrc:
      case TTI::SK_Transpose:
      case TTI::SK_PermuteTwoSrc:
        return true;
      }
    };

    if (!Mask.empty() && LT.first.isValid() && LT.first != 1 &&
        shouldSplit(Kind)) {
      InstructionCost SplitCost =
          costShuffleViaSplitting(*this, LT.second, FVTp, Mask, CostKind);
      if (SplitCost.isValid())
        return SplitCost;
    }
  }

  // Handle scalable vectors (and fixed vectors legalized to scalable vectors).
  switch (Kind) {
  default:
    // Fallthrough to generic handling.
    // TODO: Most of these cases will return getInvalid in generic code, and
    // must be implemented here.
    break;
  case TTI::SK_ExtractSubvector:
    // Extract at zero is always a subregister extract
    if (Index == 0)
      return TTI::TCC_Free;

    // If we're extracting a subvector of at most m1 size at a sub-register
    // boundary - which unfortunately we need exact vlen to identify - this is
    // a subregister extract at worst and thus won't require a vslidedown.
    // TODO: Extend for aligned m2, m4 subvector extracts
    // TODO: Extend for misalgined (but contained) extracts
    // TODO: Extend for scalable subvector types
    if (std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
        SubLT.second.isValid() && SubLT.second.isFixedLengthVector()) {
      if (std::optional<unsigned> VLen = ST->getRealVLen();
          VLen && SubLT.second.getScalarSizeInBits() * Index % *VLen == 0 &&
          SubLT.second.getSizeInBits() <= *VLen)
        return TTI::TCC_Free;
    }

    // Example sequence:
    // vsetivli     zero, 4, e8, mf2, tu, ma (ignored)
    // vslidedown.vi  v8, v9, 2
    return LT.first *
           getRISCVInstructionCost(RISCV::VSLIDEDOWN_VI, LT.second, CostKind);
  case TTI::SK_InsertSubvector:
    // Example sequence:
    // vsetivli     zero, 4, e8, mf2, tu, ma (ignored)
    // vslideup.vi  v8, v9, 2
    LT = getTypeLegalizationCost(DstTy);
    return LT.first *
           getRISCVInstructionCost(RISCV::VSLIDEUP_VI, LT.second, CostKind);
  case TTI::SK_Select: {
    // Example sequence:
    // li           a0, 90
    // vsetivli     zero, 8, e8, mf2, ta, ma (ignored)
    // vmv.s.x      v0, a0
    // vmerge.vvm   v8, v9, v8, v0
    // We use 2 for the cost of the mask materialization as this is the true
    // cost for small masks and most shuffles are small.  At worst, this cost
    // should be a very small constant for the constant pool load.  As such,
    // we may bias towards large selects slightly more than truly warranted.
    return LT.first *
           (1 + getRISCVInstructionCost({RISCV::VMV_S_X, RISCV::VMERGE_VVM},
                                        LT.second, CostKind));
  }
  case TTI::SK_Broadcast: {
    bool HasScalar = (Args.size() > 0) && (Operator::getOpcode(Args[0]) ==
                                           Instruction::InsertElement);
    if (LT.second.getScalarSizeInBits() == 1) {
      if (HasScalar) {
        // Example sequence:
        //   andi a0, a0, 1
        //   vsetivli zero, 2, e8, mf8, ta, ma (ignored)
        //   vmv.v.x v8, a0
        //   vmsne.vi v0, v8, 0
        return LT.first *
               (1 + getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
                                            LT.second, CostKind));
      }
      // Example sequence:
      //   vsetivli  zero, 2, e8, mf8, ta, mu (ignored)
      //   vmv.v.i v8, 0
      //   vmerge.vim      v8, v8, 1, v0
      //   vmv.x.s a0, v8
      //   andi    a0, a0, 1
      //   vmv.v.x v8, a0
      //   vmsne.vi  v0, v8, 0

      return LT.first *
             (1 + getRISCVInstructionCost({RISCV::VMV_V_I, RISCV::VMERGE_VIM,
                                           RISCV::VMV_X_S, RISCV::VMV_V_X,
                                           RISCV::VMSNE_VI},
                                          LT.second, CostKind));
    }

    if (HasScalar) {
      // Example sequence:
      //   vmv.v.x v8, a0
      return LT.first *
             getRISCVInstructionCost(RISCV::VMV_V_X, LT.second, CostKind);
    }

    // Example sequence:
    //   vrgather.vi     v9, v8, 0
    return LT.first *
           getRISCVInstructionCost(RISCV::VRGATHER_VI, LT.second, CostKind);
  }
  case TTI::SK_Splice: {
    // vslidedown+vslideup.
    // TODO: Multiplying by LT.first implies this legalizes into multiple copies
    // of similar code, but I think we expand through memory.
    unsigned Opcodes[2] = {RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX};
    if (Index >= 0 && Index < 32)
      Opcodes[0] = RISCV::VSLIDEDOWN_VI;
    else if (Index < 0 && Index > -32)
      Opcodes[1] = RISCV::VSLIDEUP_VI;
    return LT.first * getRISCVInstructionCost(Opcodes, LT.second, CostKind);
  }
  case TTI::SK_Reverse: {

    if (!LT.second.isVector())
      return InstructionCost::getInvalid();

    // TODO: Cases to improve here:
    // * Illegal vector types
    // * i64 on RV32
    if (SrcTy->getElementType()->isIntegerTy(1)) {
      VectorType *WideTy =
          VectorType::get(IntegerType::get(SrcTy->getContext(), 8),
                          cast<VectorType>(SrcTy)->getElementCount());
      return getCastInstrCost(Instruction::ZExt, WideTy, SrcTy,
                              TTI::CastContextHint::None, CostKind) +
             getShuffleCost(TTI::SK_Reverse, WideTy, WideTy, {}, CostKind, 0,
                            nullptr) +
             getCastInstrCost(Instruction::Trunc, SrcTy, WideTy,
                              TTI::CastContextHint::None, CostKind);
    }

    MVT ContainerVT = LT.second;
    if (LT.second.isFixedLengthVector())
      ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
    MVT M1VT = RISCVTargetLowering::getM1VT(ContainerVT);
    if (ContainerVT.bitsLE(M1VT)) {
      // Example sequence:
      //   csrr a0, vlenb
      //   srli a0, a0, 3
      //   addi a0, a0, -1
      //   vsetvli a1, zero, e8, mf8, ta, mu (ignored)
      //   vid.v v9
      //   vrsub.vx v10, v9, a0
      //   vrgather.vv v9, v8, v10
      InstructionCost LenCost = 3;
      if (LT.second.isFixedLengthVector())
        // vrsub.vi has a 5 bit immediate field, otherwise an li suffices
        LenCost = isInt<5>(LT.second.getVectorNumElements() - 1) ? 0 : 1;
      unsigned Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX, RISCV::VRGATHER_VV};
      if (LT.second.isFixedLengthVector() &&
          isInt<5>(LT.second.getVectorNumElements() - 1))
        Opcodes[1] = RISCV::VRSUB_VI;
      InstructionCost GatherCost =
          getRISCVInstructionCost(Opcodes, LT.second, CostKind);
      return LT.first * (LenCost + GatherCost);
    }

    // At high LMUL, we split into a series of M1 reverses (see
    // lowerVECTOR_REVERSE) and then do a single slide at the end to eliminate
    // the resulting gap at the bottom (for fixed vectors only).  The important
    // bit is that the cost scales linearly, not quadratically with LMUL.
    unsigned M1Opcodes[] = {RISCV::VID_V, RISCV::VRSUB_VX};
    InstructionCost FixedCost =
        getRISCVInstructionCost(M1Opcodes, M1VT, CostKind) + 3;
    unsigned Ratio =
        ContainerVT.getVectorMinNumElements() / M1VT.getVectorMinNumElements();
    InstructionCost GatherCost =
        getRISCVInstructionCost({RISCV::VRGATHER_VV}, M1VT, CostKind) * Ratio;
    InstructionCost SlideCost = !LT.second.isFixedLengthVector() ? 0 :
      getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX}, LT.second, CostKind);
    return FixedCost + LT.first * (GatherCost + SlideCost);
  }
  }
  return BaseT::getShuffleCost(Kind, DstTy, SrcTy, Mask, CostKind, Index,
                               SubTp);
}

static unsigned isM1OrSmaller(MVT VT) {
  RISCVVType::VLMUL LMUL = RISCVTargetLowering::getLMUL(VT);
  return (LMUL == RISCVVType::VLMUL::LMUL_F8 ||
          LMUL == RISCVVType::VLMUL::LMUL_F4 ||
          LMUL == RISCVVType::VLMUL::LMUL_F2 ||
          LMUL == RISCVVType::VLMUL::LMUL_1);
}

InstructionCost RISCVTTIImpl::getScalarizationOverhead(
    VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
    TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef<Value *> VL,
    TTI::VectorInstrContext VIC) const {
  if (isa<ScalableVectorType>(Ty))
    return InstructionCost::getInvalid();

  // TODO: Add proper cost model for P extension fixed vectors (e.g., v4i16)
  // For now, skip all fixed vector cost analysis when P extension is available
  // to avoid crashes in getMinRVVVectorSizeInBits()
  if (ST->hasStdExtP() && isa<FixedVectorType>(Ty)) {
    return 1; // Treat as single instruction cost for now
  }

  // A build_vector (which is m1 sized or smaller) can be done in no
  // worse than one vslide1down.vx per element in the type.  We could
  // in theory do an explode_vector in the inverse manner, but our
  // lowering today does not have a first class node for this pattern.
  InstructionCost Cost = BaseT::getScalarizationOverhead(
      Ty, DemandedElts, Insert, Extract, CostKind);
  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
  if (Insert && !Extract && LT.first.isValid() && LT.second.isVector()) {
    if (Ty->getScalarSizeInBits() == 1) {
      auto *WideVecTy = cast<VectorType>(Ty->getWithNewBitWidth(8));
      // Note: Implicit scalar anyextend is assumed to be free since the i1
      // must be stored in a GPR.
      return getScalarizationOverhead(WideVecTy, DemandedElts, Insert, Extract,
                                      CostKind) +
             getCastInstrCost(Instruction::Trunc, Ty, WideVecTy,
                              TTI::CastContextHint::None, CostKind, nullptr);
    }

    assert(LT.second.isFixedLengthVector());
    MVT ContainerVT = TLI->getContainerForFixedLengthVector(LT.second);
    if (isM1OrSmaller(ContainerVT)) {
      InstructionCost BV =
          cast<FixedVectorType>(Ty)->getNumElements() *
          getRISCVInstructionCost(RISCV::VSLIDE1DOWN_VX, LT.second, CostKind);
      if (BV < Cost)
        Cost = BV;
    }
  }
  return Cost;
}

InstructionCost
RISCVTTIImpl::getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA,
                                       TTI::TargetCostKind CostKind) const {
  Type *DataTy = MICA.getDataType();
  Align Alignment = MICA.getAlignment();
  switch (MICA.getID()) {
  case Intrinsic::vp_load_ff: {
    EVT DataTypeVT = TLI->getValueType(DL, DataTy);
    if (!TLI->isLegalFirstFaultLoad(DataTypeVT, Alignment))
      return BaseT::getMemIntrinsicInstrCost(MICA, CostKind);

    unsigned AS = MICA.getAddressSpace();
    return getMemoryOpCost(Instruction::Load, DataTy, Alignment, AS, CostKind,
                           {TTI::OK_AnyValue, TTI::OP_None}, nullptr);
  }
  case Intrinsic::experimental_vp_strided_load:
  case Intrinsic::experimental_vp_strided_store:
    return getStridedMemoryOpCost(MICA, CostKind);
  case Intrinsic::masked_compressstore:
  case Intrinsic::masked_expandload:
    return getExpandCompressMemoryOpCost(MICA, CostKind);
  case Intrinsic::vp_scatter:
  case Intrinsic::vp_gather:
  case Intrinsic::masked_scatter:
  case Intrinsic::masked_gather:
    return getGatherScatterOpCost(MICA, CostKind);
  case Intrinsic::vp_load:
  case Intrinsic::vp_store:
  case Intrinsic::masked_load:
  case Intrinsic::masked_store:
    return getMaskedMemoryOpCost(MICA, CostKind);
  }
  return BaseT::getMemIntrinsicInstrCost(MICA, CostKind);
}

InstructionCost
RISCVTTIImpl::getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
                                    TTI::TargetCostKind CostKind) const {
  unsigned Opcode = MICA.getID() == Intrinsic::masked_load ? Instruction::Load
                                                           : Instruction::Store;
  Type *Src = MICA.getDataType();
  Align Alignment = MICA.getAlignment();
  unsigned AddressSpace = MICA.getAddressSpace();

  if (!isLegalMaskedLoadStore(Src, Alignment) ||
      CostKind != TTI::TCK_RecipThroughput)
    return BaseT::getMemIntrinsicInstrCost(MICA, CostKind);

  return getMemoryOpCost(Opcode, Src, Alignment, AddressSpace, CostKind);
}

InstructionCost RISCVTTIImpl::getInterleavedMemoryOpCost(
    unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
    Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
    bool UseMaskForCond, bool UseMaskForGaps) const {

  // The interleaved memory access pass will lower (de)interleave ops combined
  // with an adjacent appropriate memory to vlseg/vsseg intrinsics. vlseg/vsseg
  // only support masking per-iteration (i.e. condition), not per-segment (i.e.
  // gap).
  if (!UseMaskForGaps && Factor <= TLI->getMaxSupportedInterleaveFactor()) {
    auto *VTy = cast<VectorType>(VecTy);
    std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(VTy);
    // Need to make sure type has't been scalarized
    if (LT.second.isVector()) {
      auto *SubVecTy =
          VectorType::get(VTy->getElementType(),
                          VTy->getElementCount().divideCoefficientBy(Factor));
      if (VTy->getElementCount().isKnownMultipleOf(Factor) &&
          TLI->isLegalInterleavedAccessType(SubVecTy, Factor, Alignment,
                                            AddressSpace, DL)) {

        // Some processors optimize segment loads/stores as one wide memory op +
        // Factor * LMUL shuffle ops.
        if (ST->hasOptimizedSegmentLoadStore(Factor)) {
          InstructionCost Cost =
              getMemoryOpCost(Opcode, VTy, Alignment, AddressSpace, CostKind);
          MVT SubVecVT = getTLI()->getValueType(DL, SubVecTy).getSimpleVT();
          Cost += Factor * TLI->getLMULCost(SubVecVT);
          return LT.first * Cost;
        }

        // Otherwise, the cost is proportional to the number of elements (VL *
        // Factor ops).
        InstructionCost MemOpCost =
            getMemoryOpCost(Opcode, VTy->getElementType(), Alignment, 0,
                            CostKind, {TTI::OK_AnyValue, TTI::OP_None});
        unsigned NumLoads = getEstimatedVLFor(VTy);
        return NumLoads * MemOpCost;
      }
    }
  }

  // TODO: Return the cost of interleaved accesses for scalable vector when
  // unable to convert to segment accesses instructions.
  if (isa<ScalableVectorType>(VecTy))
    return InstructionCost::getInvalid();

  auto *FVTy = cast<FixedVectorType>(VecTy);
  InstructionCost MemCost =
      getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace, CostKind);
  unsigned VF = FVTy->getNumElements() / Factor;

  // An interleaved load will look like this for Factor=3:
  // %wide.vec = load <12 x i32>, ptr %3, align 4
  // %strided.vec = shufflevector %wide.vec, poison, <4 x i32> <stride mask>
  // %strided.vec1 = shufflevector %wide.vec, poison, <4 x i32> <stride mask>
  // %strided.vec2 = shufflevector %wide.vec, poison, <4 x i32> <stride mask>
  if (Opcode == Instruction::Load) {
    InstructionCost Cost = MemCost;
    for (unsigned Index : Indices) {
      FixedVectorType *VecTy =
          FixedVectorType::get(FVTy->getElementType(), VF * Factor);
      auto Mask = createStrideMask(Index, Factor, VF);
      Mask.resize(VF * Factor, -1);
      InstructionCost ShuffleCost =
          getShuffleCost(TTI::ShuffleKind::SK_PermuteSingleSrc, VecTy, VecTy,
                         Mask, CostKind, 0, nullptr, {});
      Cost += ShuffleCost;
    }
    return Cost;
  }

  // TODO: Model for NF > 2
  // We'll need to enhance getShuffleCost to model shuffles that are just
  // inserts and extracts into subvectors, since they won't have the full cost
  // of a vrgather.
  // An interleaved store for 3 vectors of 4 lanes will look like
  // %11 = shufflevector <4 x i32> %4, <4 x i32> %6, <8 x i32> <0...7>
  // %12 = shufflevector <4 x i32> %9, <4 x i32> poison, <8 x i32> <0...3>
  // %13 = shufflevector <8 x i32> %11, <8 x i32> %12, <12 x i32> <0...11>
  // %interleaved.vec = shufflevector %13, poison, <12 x i32> <interleave mask>
  // store <12 x i32> %interleaved.vec, ptr %10, align 4
  if (Factor != 2)
    return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
                                             Alignment, AddressSpace, CostKind,
                                             UseMaskForCond, UseMaskForGaps);

  assert(Opcode == Instruction::Store && "Opcode must be a store");
  // For an interleaving store of 2 vectors, we perform one large interleaving
  // shuffle that goes into the wide store
  auto Mask = createInterleaveMask(VF, Factor);
  InstructionCost ShuffleCost =
      getShuffleCost(TTI::ShuffleKind::SK_PermuteSingleSrc, FVTy, FVTy, Mask,
                     CostKind, 0, nullptr, {});
  return MemCost + ShuffleCost;
}

InstructionCost
RISCVTTIImpl::getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA,
                                     TTI::TargetCostKind CostKind) const {

  bool IsLoad = MICA.getID() == Intrinsic::masked_gather ||
                MICA.getID() == Intrinsic::vp_gather;
  unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
  Type *DataTy = MICA.getDataType();
  Align Alignment = MICA.getAlignment();
  if (CostKind != TTI::TCK_RecipThroughput)
    return BaseT::getMemIntrinsicInstrCost(MICA, CostKind);

  if ((Opcode == Instruction::Load &&
       !isLegalMaskedGather(DataTy, Align(Alignment))) ||
      (Opcode == Instruction::Store &&
       !isLegalMaskedScatter(DataTy, Align(Alignment))))
    return BaseT::getMemIntrinsicInstrCost(MICA, CostKind);

  // Cost is proportional to the number of memory operations implied.  For
  // scalable vectors, we use an estimate on that number since we don't
  // know exactly what VL will be.
  auto &VTy = *cast<VectorType>(DataTy);
  unsigned NumLoads = getEstimatedVLFor(&VTy);
  return NumLoads * TTI::TCC_Basic;
}

InstructionCost RISCVTTIImpl::getExpandCompressMemoryOpCost(
    const MemIntrinsicCostAttributes &MICA,
    TTI::TargetCostKind CostKind) const {
  unsigned Opcode = MICA.getID() == Intrinsic::masked_expandload
                        ? Instruction::Load
                        : Instruction::Store;
  Type *DataTy = MICA.getDataType();
  bool VariableMask = MICA.getVariableMask();
  Align Alignment = MICA.getAlignment();
  bool IsLegal = (Opcode == Instruction::Store &&
                  isLegalMaskedCompressStore(DataTy, Alignment)) ||
                 (Opcode == Instruction::Load &&
                  isLegalMaskedExpandLoad(DataTy, Alignment));
  if (!IsLegal || CostKind != TTI::TCK_RecipThroughput)
    return BaseT::getMemIntrinsicInstrCost(MICA, CostKind);
  // Example compressstore sequence:
  // vsetivli        zero, 8, e32, m2, ta, ma (ignored)
  // vcompress.vm    v10, v8, v0
  // vcpop.m a1, v0
  // vsetvli zero, a1, e32, m2, ta, ma
  // vse32.v v10, (a0)
  // Example expandload sequence:
  // vsetivli        zero, 8, e8, mf2, ta, ma (ignored)
  // vcpop.m a1, v0
  // vsetvli zero, a1, e32, m2, ta, ma
  // vle32.v v10, (a0)
  // vsetivli        zero, 8, e32, m2, ta, ma
  // viota.m v12, v0
  // vrgather.vv     v8, v10, v12, v0.t
  auto MemOpCost =
      getMemoryOpCost(Opcode, DataTy, Alignment, /*AddressSpace*/ 0, CostKind);
  auto LT = getTypeLegalizationCost(DataTy);
  SmallVector<unsigned, 4> Opcodes{RISCV::VSETVLI};
  if (VariableMask)
    Opcodes.push_back(RISCV::VCPOP_M);
  if (Opcode == Instruction::Store)
    Opcodes.append({RISCV::VCOMPRESS_VM});
  else
    Opcodes.append({RISCV::VSETIVLI, RISCV::VIOTA_M, RISCV::VRGATHER_VV});
  return MemOpCost +
         LT.first * getRISCVInstructionCost(Opcodes, LT.second, CostKind);
}

InstructionCost
RISCVTTIImpl::getStridedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
                                     TTI::TargetCostKind CostKind) const {

  unsigned Opcode = MICA.getID() == Intrinsic::experimental_vp_strided_load
                        ? Instruction::Load
                        : Instruction::Store;

  Type *DataTy = MICA.getDataType();
  Align Alignment = MICA.getAlignment();
  const Instruction *I = MICA.getInst();

  if (!isLegalStridedLoadStore(DataTy, Alignment))
    return BaseT::getMemIntrinsicInstrCost(MICA, CostKind);

  if (CostKind == TTI::TCK_CodeSize)
    return TTI::TCC_Basic;

  // Cost is proportional to the number of memory operations implied.  For
  // scalable vectors, we use an estimate on that number since we don't
  // know exactly what VL will be.
  // FIXME: This will overcost for i64 on rv32 with +zve64x.
  auto &VTy = *cast<VectorType>(DataTy);
  InstructionCost MemOpCost =
      getMemoryOpCost(Opcode, VTy.getElementType(), Alignment, 0, CostKind,
                      {TTI::OK_AnyValue, TTI::OP_None}, I);
  unsigned NumLoads = getEstimatedVLFor(&VTy);
  return NumLoads * MemOpCost;
}

InstructionCost
RISCVTTIImpl::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
  // FIXME: This is a property of the default vector convention, not
  // all possible calling conventions.  Fixing that will require
  // some TTI API and SLP rework.
  InstructionCost Cost = 0;
  TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
  for (auto *Ty : Tys) {
    if (!Ty->isVectorTy())
      continue;
    Align A = DL.getPrefTypeAlign(Ty);
    Cost += getMemoryOpCost(Instruction::Store, Ty, A, 0, CostKind) +
            getMemoryOpCost(Instruction::Load, Ty, A, 0, CostKind);
  }
  return Cost;
}

// Currently, these represent both throughput and codesize costs
// for the respective intrinsics.  The costs in this table are simply
// instruction counts with the following adjustments made:
// * One vsetvli is considered free.
static const CostTblEntry VectorIntrinsicCostTable[]{
    {Intrinsic::floor, MVT::f32, 9},
    {Intrinsic::floor, MVT::f64, 9},
    {Intrinsic::ceil, MVT::f32, 9},
    {Intrinsic::ceil, MVT::f64, 9},
    {Intrinsic::trunc, MVT::f32, 7},
    {Intrinsic::trunc, MVT::f64, 7},
    {Intrinsic::round, MVT::f32, 9},
    {Intrinsic::round, MVT::f64, 9},
    {Intrinsic::roundeven, MVT::f32, 9},
    {Intrinsic::roundeven, MVT::f64, 9},
    {Intrinsic::rint, MVT::f32, 7},
    {Intrinsic::rint, MVT::f64, 7},
    {Intrinsic::nearbyint, MVT::f32, 9},
    {Intrinsic::nearbyint, MVT::f64, 9},
    {Intrinsic::bswap, MVT::i16, 3},
    {Intrinsic::bswap, MVT::i32, 12},
    {Intrinsic::bswap, MVT::i64, 31},
    {Intrinsic::vp_bswap, MVT::i16, 3},
    {Intrinsic::vp_bswap, MVT::i32, 12},
    {Intrinsic::vp_bswap, MVT::i64, 31},
    {Intrinsic::vp_fshl, MVT::i8, 7},
    {Intrinsic::vp_fshl, MVT::i16, 7},
    {Intrinsic::vp_fshl, MVT::i32, 7},
    {Intrinsic::vp_fshl, MVT::i64, 7},
    {Intrinsic::vp_fshr, MVT::i8, 7},
    {Intrinsic::vp_fshr, MVT::i16, 7},
    {Intrinsic::vp_fshr, MVT::i32, 7},
    {Intrinsic::vp_fshr, MVT::i64, 7},
    {Intrinsic::bitreverse, MVT::i8, 17},
    {Intrinsic::bitreverse, MVT::i16, 24},
    {Intrinsic::bitreverse, MVT::i32, 33},
    {Intrinsic::bitreverse, MVT::i64, 52},
    {Intrinsic::vp_bitreverse, MVT::i8, 17},
    {Intrinsic::vp_bitreverse, MVT::i16, 24},
    {Intrinsic::vp_bitreverse, MVT::i32, 33},
    {Intrinsic::vp_bitreverse, MVT::i64, 52},
    {Intrinsic::ctpop, MVT::i8, 12},
    {Intrinsic::ctpop, MVT::i16, 19},
    {Intrinsic::ctpop, MVT::i32, 20},
    {Intrinsic::ctpop, MVT::i64, 21},
    {Intrinsic::ctlz, MVT::i8, 19},
    {Intrinsic::ctlz, MVT::i16, 28},
    {Intrinsic::ctlz, MVT::i32, 31},
    {Intrinsic::ctlz, MVT::i64, 35},
    {Intrinsic::cttz, MVT::i8, 16},
    {Intrinsic::cttz, MVT::i16, 23},
    {Intrinsic::cttz, MVT::i32, 24},
    {Intrinsic::cttz, MVT::i64, 25},
    {Intrinsic::vp_ctpop, MVT::i8, 12},
    {Intrinsic::vp_ctpop, MVT::i16, 19},
    {Intrinsic::vp_ctpop, MVT::i32, 20},
    {Intrinsic::vp_ctpop, MVT::i64, 21},
    {Intrinsic::vp_ctlz, MVT::i8, 19},
    {Intrinsic::vp_ctlz, MVT::i16, 28},
    {Intrinsic::vp_ctlz, MVT::i32, 31},
    {Intrinsic::vp_ctlz, MVT::i64, 35},
    {Intrinsic::vp_cttz, MVT::i8, 16},
    {Intrinsic::vp_cttz, MVT::i16, 23},
    {Intrinsic::vp_cttz, MVT::i32, 24},
    {Intrinsic::vp_cttz, MVT::i64, 25},
};

InstructionCost
RISCVTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
                                    TTI::TargetCostKind CostKind) const {
  auto *RetTy = ICA.getReturnType();
  switch (ICA.getID()) {
  case Intrinsic::lrint:
  case Intrinsic::llrint:
  case Intrinsic::lround:
  case Intrinsic::llround: {
    auto LT = getTypeLegalizationCost(RetTy);
    Type *SrcTy = ICA.getArgTypes().front();
    auto SrcLT = getTypeLegalizationCost(SrcTy);
    if (ST->hasVInstructions() && LT.second.isVector()) {
      SmallVector<unsigned, 2> Ops;
      unsigned SrcEltSz = DL.getTypeSizeInBits(SrcTy->getScalarType());
      unsigned DstEltSz = DL.getTypeSizeInBits(RetTy->getScalarType());
      if (LT.second.getVectorElementType() == MVT::bf16) {
        if (!ST->hasVInstructionsBF16Minimal())
          return InstructionCost::getInvalid();
        if (DstEltSz == 32)
          Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFCVT_X_F_V};
        else
          Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVT_X_F_V};
      } else if (LT.second.getVectorElementType() == MVT::f16 &&
                 !ST->hasVInstructionsF16()) {
        if (!ST->hasVInstructionsF16Minimal())
          return InstructionCost::getInvalid();
        if (DstEltSz == 32)
          Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFCVT_X_F_V};
        else
          Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_X_F_V};

      } else if (SrcEltSz > DstEltSz) {
        Ops = {RISCV::VFNCVT_X_F_W};
      } else if (SrcEltSz < DstEltSz) {
        Ops = {RISCV::VFWCVT_X_F_V};
      } else {
        Ops = {RISCV::VFCVT_X_F_V};
      }

      // We need to use the source LMUL in the case of a narrowing op, and the
      // destination LMUL otherwise.
      if (SrcEltSz > DstEltSz)
        return SrcLT.first *
               getRISCVInstructionCost(Ops, SrcLT.second, CostKind);
      return LT.first * getRISCVInstructionCost(Ops, LT.second, CostKind);
    }
    break;
  }
  case Intrinsic::ceil:
  case Intrinsic::floor:
  case Intrinsic::trunc:
  case Intrinsic::rint:
  case Intrinsic::round:
  case Intrinsic::roundeven: {
    // These all use the same code.
    auto LT = getTypeLegalizationCost(RetTy);
    if (!LT.second.isVector() && TLI->isOperationCustom(ISD::FCEIL, LT.second))
      return LT.first * 8;
    break;
  }
  case Intrinsic::umin:
  case Intrinsic::umax:
  case Intrinsic::smin:
  case Intrinsic::smax: {
    auto LT = getTypeLegalizationCost(RetTy);
    if (LT.second.isScalarInteger() && ST->hasStdExtZbb())
      return LT.first;

    if (ST->hasVInstructions() && LT.second.isVector()) {
      unsigned Op;
      switch (ICA.getID()) {
      case Intrinsic::umin:
        Op = RISCV::VMINU_VV;
        break;
      case Intrinsic::umax:
        Op = RISCV::VMAXU_VV;
        break;
      case Intrinsic::smin:
        Op = RISCV::VMIN_VV;
        break;
      case Intrinsic::smax:
        Op = RISCV::VMAX_VV;
        break;
      }
      return LT.first * getRISCVInstructionCost(Op, LT.second, CostKind);
    }
    break;
  }
  case Intrinsic::sadd_sat:
  case Intrinsic::ssub_sat:
  case Intrinsic::uadd_sat:
  case Intrinsic::usub_sat: {
    auto LT = getTypeLegalizationCost(RetTy);
    if (ST->hasVInstructions() && LT.second.isVector()) {
      unsigned Op;
      switch (ICA.getID()) {
      case Intrinsic::sadd_sat:
        Op = RISCV::VSADD_VV;
        break;
      case Intrinsic::ssub_sat:
        Op = RISCV::VSSUB_VV;
        break;
      case Intrinsic::uadd_sat:
        Op = RISCV::VSADDU_VV;
        break;
      case Intrinsic::usub_sat:
        Op = RISCV::VSSUBU_VV;
        break;
      }
      return LT.first * getRISCVInstructionCost(Op, LT.second, CostKind);
    }
    break;
  }
  case Intrinsic::fma:
  case Intrinsic::fmuladd: {
    // TODO: handle promotion with f16/bf16 with zvfhmin/zvfbfmin
    auto LT = getTypeLegalizationCost(RetTy);
    if (ST->hasVInstructions() && LT.second.isVector())
      return LT.first *
             getRISCVInstructionCost(RISCV::VFMADD_VV, LT.second, CostKind);
    break;
  }
  case Intrinsic::fabs: {
    auto LT = getTypeLegalizationCost(RetTy);
    if (ST->hasVInstructions() && LT.second.isVector()) {
      // lui a0, 8
      // addi a0, a0, -1
      // vsetvli a1, zero, e16, m1, ta, ma
      // vand.vx v8, v8, a0
      // f16 with zvfhmin and bf16 with zvfhbmin
      if (LT.second.getVectorElementType() == MVT::bf16 ||
          (LT.second.getVectorElementType() == MVT::f16 &&
           !ST->hasVInstructionsF16()))
        return LT.first * getRISCVInstructionCost(RISCV::VAND_VX, LT.second,
                                                  CostKind) +
               2;
      else
        return LT.first *
               getRISCVInstructionCost(RISCV::VFSGNJX_VV, LT.second, CostKind);
    }
    break;
  }
  case Intrinsic::sqrt: {
    auto LT = getTypeLegalizationCost(RetTy);
    if (ST->hasVInstructions() && LT.second.isVector()) {
      SmallVector<unsigned, 4> ConvOp;
      SmallVector<unsigned, 2> FsqrtOp;
      MVT ConvType = LT.second;
      MVT FsqrtType = LT.second;
      // f16 with zvfhmin and bf16 with zvfbfmin and the type of nxv32[b]f16
      // will be spilt.
      if (LT.second.getVectorElementType() == MVT::bf16) {
        if (LT.second == MVT::nxv32bf16) {
          ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVTBF16_F_F_V,
                    RISCV::VFNCVTBF16_F_F_W, RISCV::VFNCVTBF16_F_F_W};
          FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
          ConvType = MVT::nxv16f16;
          FsqrtType = MVT::nxv16f32;
        } else {
          ConvOp = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFNCVTBF16_F_F_W};
          FsqrtOp = {RISCV::VFSQRT_V};
          FsqrtType = TLI->getTypeToPromoteTo(ISD::FSQRT, FsqrtType);
        }
      } else if (LT.second.getVectorElementType() == MVT::f16 &&
                 !ST->hasVInstructionsF16()) {
        if (LT.second == MVT::nxv32f16) {
          ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_F_F_V,
                    RISCV::VFNCVT_F_F_W, RISCV::VFNCVT_F_F_W};
          FsqrtOp = {RISCV::VFSQRT_V, RISCV::VFSQRT_V};
          ConvType = MVT::nxv16f16;
          FsqrtType = MVT::nxv16f32;
        } else {
          ConvOp = {RISCV::VFWCVT_F_F_V, RISCV::VFNCVT_F_F_W};
          FsqrtOp = {RISCV::VFSQRT_V};
          FsqrtType = TLI->getTypeToPromoteTo(ISD::FSQRT, FsqrtType);
        }
      } else {
        FsqrtOp = {RISCV::VFSQRT_V};
      }

      return LT.first * (getRISCVInstructionCost(FsqrtOp, FsqrtType, CostKind) +
                         getRISCVInstructionCost(ConvOp, ConvType, CostKind));
    }
    break;
  }
  case Intrinsic::cttz:
  case Intrinsic::ctlz:
  case Intrinsic::ctpop: {
    auto LT = getTypeLegalizationCost(RetTy);
    if (ST->hasStdExtZvbb() && LT.second.isVector()) {
      unsigned Op;
      switch (ICA.getID()) {
      case Intrinsic::cttz:
        Op = RISCV::VCTZ_V;
        break;
      case Intrinsic::ctlz:
        Op = RISCV::VCLZ_V;
        break;
      case Intrinsic::ctpop:
        Op = RISCV::VCPOP_V;
        break;
      }
      return LT.first * getRISCVInstructionCost(Op, LT.second, CostKind);
    }
    break;
  }
  case Intrinsic::abs: {
    auto LT = getTypeLegalizationCost(RetTy);
    if (ST->hasVInstructions() && LT.second.isVector()) {
      // vabs.v v10, v8
      if (ST->hasStdExtZvabd())
        return LT.first *
               getRISCVInstructionCost({RISCV::VABS_V}, LT.second, CostKind);

      // vrsub.vi v10, v8, 0
      // vmax.vv v8, v8, v10
      return LT.first *
             getRISCVInstructionCost({RISCV::VRSUB_VI, RISCV::VMAX_VV},
                                     LT.second, CostKind);
    }
    break;
  }
  case Intrinsic::fshl:
  case Intrinsic::fshr: {
    if (ICA.getArgs().empty())
      break;

    // Funnel-shifts are ROTL/ROTR when the first and second operand are equal.
    // When Zbb/Zbkb is enabled we can use a single ROL(W)/ROR(I)(W)
    // instruction.
    if ((ST->hasStdExtZbb() || ST->hasStdExtZbkb()) && RetTy->isIntegerTy() &&
        ICA.getArgs()[0] == ICA.getArgs()[1] &&
        (RetTy->getIntegerBitWidth() == 32 ||
         RetTy->getIntegerBitWidth() == 64) &&
        RetTy->getIntegerBitWidth() <= ST->getXLen()) {
      return 1;
    }
    break;
  }
  case Intrinsic::masked_udiv:
    return getArithmeticInstrCost(Instruction::UDiv, ICA.getReturnType(),
                                  CostKind);
  case Intrinsic::masked_sdiv:
    return getArithmeticInstrCost(Instruction::SDiv, ICA.getReturnType(),
                                  CostKind);
  case Intrinsic::masked_urem:
    return getArithmeticInstrCost(Instruction::URem, ICA.getReturnType(),
                                  CostKind);
  case Intrinsic::masked_srem:
    return getArithmeticInstrCost(Instruction::SRem, ICA.getReturnType(),
                                  CostKind);
  case Intrinsic::get_active_lane_mask: {
    if (ST->hasVInstructions()) {
      Type *ExpRetTy = VectorType::get(
          ICA.getArgTypes()[0], cast<VectorType>(RetTy)->getElementCount());
      auto LT = getTypeLegalizationCost(ExpRetTy);

      // vid.v   v8  // considered hoisted
      // vsaddu.vx   v8, v8, a0
      // vmsltu.vx   v0, v8, a1
      return LT.first *
             getRISCVInstructionCost({RISCV::VSADDU_VX, RISCV::VMSLTU_VX},
                                     LT.second, CostKind);
    }
    break;
  }
  // TODO: add more intrinsic
  case Intrinsic::stepvector: {
    auto LT = getTypeLegalizationCost(RetTy);
    // Legalisation of illegal types involves an `index' instruction plus
    // (LT.first - 1) vector adds.
    if (ST->hasVInstructions())
      return getRISCVInstructionCost(RISCV::VID_V, LT.second, CostKind) +
             (LT.first - 1) *
                 getRISCVInstructionCost(RISCV::VADD_VX, LT.second, CostKind);
    return 1 + (LT.first - 1);
  }
  case Intrinsic::vector_splice_left:
  case Intrinsic::vector_splice_right: {
    auto LT = getTypeLegalizationCost(RetTy);
    // Constant offsets fall through to getShuffleCost.
    if (!ICA.isTypeBasedOnly() && isa<ConstantInt>(ICA.getArgs()[2]))
      break;
    if (ST->hasVInstructions() && LT.second.isVector()) {
      return LT.first *
             getRISCVInstructionCost({RISCV::VSLIDEDOWN_VX, RISCV::VSLIDEUP_VX},
                                     LT.second, CostKind);
    }
    break;
  }
  case Intrinsic::experimental_cttz_elts: {
    Type *ArgTy = ICA.getArgTypes()[0];
    EVT ArgType = TLI->getValueType(DL, ArgTy, true);
    if (getTLI()->shouldExpandCttzElements(ArgType))
      break;
    InstructionCost Cost = getRISCVInstructionCost(
        RISCV::VFIRST_M, getTypeLegalizationCost(ArgTy).second, CostKind);

    // If zero_is_poison is false, then we will generate additional
    // cmp + select instructions to convert -1 to EVL.
    Type *BoolTy = Type::getInt1Ty(RetTy->getContext());
    if (ICA.getArgs().size() > 1 &&
        cast<ConstantInt>(ICA.getArgs()[1])->isZero())
      Cost += getCmpSelInstrCost(Instruction::ICmp, BoolTy, RetTy,
                                 CmpInst::ICMP_SLT, CostKind) +
              getCmpSelInstrCost(Instruction::Select, RetTy, BoolTy,
                                 CmpInst::BAD_ICMP_PREDICATE, CostKind);

    return Cost;
  }
  case Intrinsic::experimental_vp_splice: {
    // To support type-based query from vectorizer, set the index to 0.
    // Note that index only change the cost from vslide.vx to vslide.vi and in
    // current implementations they have same costs.
    return getShuffleCost(TTI::SK_Splice, cast<VectorType>(ICA.getReturnType()),
                          cast<VectorType>(ICA.getArgTypes()[0]), {}, CostKind,
                          0, cast<VectorType>(ICA.getReturnType()));
  }
  case Intrinsic::fptoui_sat:
  case Intrinsic::fptosi_sat: {
    InstructionCost Cost = 0;
    bool IsSigned = ICA.getID() == Intrinsic::fptosi_sat;
    Type *SrcTy = ICA.getArgTypes()[0];

    auto SrcLT = getTypeLegalizationCost(SrcTy);
    auto DstLT = getTypeLegalizationCost(RetTy);
    if (!SrcTy->isVectorTy())
      break;

    if (!SrcLT.first.isValid() || !DstLT.first.isValid())
      return InstructionCost::getInvalid();

    Cost +=
        getCastInstrCost(IsSigned ? Instruction::FPToSI : Instruction::FPToUI,
                         RetTy, SrcTy, TTI::CastContextHint::None, CostKind);

    // Handle NaN.
    // vmfne v0, v8, v8         # If v8[i] is NaN set v0[i] to 1.
    // vmerge.vim v8, v8, 0, v0 # Convert NaN to 0.
    Type *CondTy = RetTy->getWithNewBitWidth(1);
    Cost += getCmpSelInstrCost(BinaryOperator::FCmp, SrcTy, CondTy,
                               CmpInst::FCMP_UNO, CostKind);
    Cost += getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
                               CmpInst::FCMP_UNO, CostKind);
    return Cost;
  }
  case Intrinsic::experimental_vector_extract_last_active: {
    auto *ValTy = cast<VectorType>(ICA.getArgTypes()[0]);
    auto *MaskTy = cast<VectorType>(ICA.getArgTypes()[1]);

    auto ValLT = getTypeLegalizationCost(ValTy);
    auto MaskLT = getTypeLegalizationCost(MaskTy);

    // TODO: Return cheaper cost when the entire lane is inactive.
    // The expected asm sequence is:
    // vcpop.m a0, v0
    // beqz a0, exit # Return passthru when the entire lane is inactive.
    // vid v10, v0.t
    // vredmaxu.vs v10, v10, v10
    // vmv.x.s a0, v10
    // zext.b a0, a0
    // vslidedown.vx v8, v8, a0
    // vmv.x.s a0, v8
    // exit:
    //   ...

    // Find a suitable type for a stepvector.
    ConstantRange VScaleRange(APInt(64, 1), APInt::getZero(64));
    unsigned EltWidth = getTLI()->getBitWidthForCttzElements(
        TLI->getVectorIdxTy(getDataLayout()), MaskTy->getElementCount(),
        /*ZeroIsPoison=*/true, &VScaleRange);
    EltWidth = std::max(EltWidth, MaskTy->getScalarSizeInBits());
    Type *StepTy = Type::getIntNTy(MaskTy->getContext(), EltWidth);
    auto *StepVecTy = VectorType::get(StepTy, ValTy->getElementCount());
    auto StepLT = getTypeLegalizationCost(StepVecTy);

    // Currently expandVectorFindLastActive cannot handle step vector split.
    // So return invalid when the type needs split.
    // FIXME: Remove this if expandVectorFindLastActive supports split vector.
    if (StepLT.first > 1)
      return InstructionCost::getInvalid();

    InstructionCost Cost = 0;
    unsigned Opcodes[] = {RISCV::VID_V, RISCV::VREDMAXU_VS, RISCV::VMV_X_S};

    Cost += MaskLT.first *
            getRISCVInstructionCost(RISCV::VCPOP_M, MaskLT.second, CostKind);
    Cost += getCFInstrCost(Instruction::CondBr, CostKind, nullptr);
    Cost += StepLT.first *
            getRISCVInstructionCost(Opcodes, StepLT.second, CostKind);
    Cost += getCastInstrCost(Instruction::ZExt,
                             Type::getInt64Ty(ValTy->getContext()), StepTy,
                             TTI::CastContextHint::None, CostKind, nullptr);
    Cost += ValLT.first *
            getRISCVInstructionCost({RISCV::VSLIDEDOWN_VI, RISCV::VMV_X_S},
                                    ValLT.second, CostKind);
    return Cost;
  }
  }

  if (ST->hasVInstructions() && RetTy->isVectorTy()) {
    if (auto LT = getTypeLegalizationCost(RetTy);
        LT.second.isVector()) {
      MVT EltTy = LT.second.getVectorElementType();
      if (const auto *Entry = CostTableLookup(VectorIntrinsicCostTable,
                                              ICA.getID(), EltTy))
        return LT.first * Entry->Cost;
    }
  }

  return BaseT::getIntrinsicInstrCost(ICA, CostKind);
}

InstructionCost
RISCVTTIImpl::getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE,
                                        const SCEV *Ptr,
                                        TTI::TargetCostKind CostKind) const {
  // Address computations for vector indexed load/store likely require an offset
  // and/or scaling.
  if (ST->hasVInstructions() && PtrTy->isVectorTy())
    return getArithmeticInstrCost(Instruction::Add, PtrTy, CostKind);

  return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
}

InstructionCost RISCVTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst,
                                               Type *Src,
                                               TTI::CastContextHint CCH,
                                               TTI::TargetCostKind CostKind,
                                               const Instruction *I) const {
  bool IsVectorType = isa<VectorType>(Dst) && isa<VectorType>(Src);
  if (!IsVectorType)
    return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);

  // TODO: Add proper cost model for P extension fixed vectors (e.g., v4i16)
  // For now, skip all fixed vector cost analysis when P extension is available
  // to avoid crashes in getMinRVVVectorSizeInBits()
  if (ST->hasStdExtP() &&
      (isa<FixedVectorType>(Dst) || isa<FixedVectorType>(Src))) {
    return 1; // Treat as single instruction cost for now
  }

  // FIXME: Need to compute legalizing cost for illegal types.  The current
  // code handles only legal types and those which can be trivially
  // promoted to legal.
  if (!ST->hasVInstructions() || Src->getScalarSizeInBits() > ST->getELen() ||
      Dst->getScalarSizeInBits() > ST->getELen())
    return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);

  int ISD = TLI->InstructionOpcodeToISD(Opcode);
  assert(ISD && "Invalid opcode");
  std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(Src);
  std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(Dst);

  // Handle i1 source and dest cases *before* calling logic in BasicTTI.
  // The shared implementation doesn't model vector widening during legalization
  // and instead assumes scalarization.  In order to scalarize an <N x i1>
  // vector, we need to extend/trunc to/from i8.  If we don't special case
  // this, we can get an infinite recursion cycle.
  switch (ISD) {
  default:
    break;
  case ISD::SIGN_EXTEND:
  case ISD::ZERO_EXTEND:
    if (Src->getScalarSizeInBits() == 1) {
      // We do not use vsext/vzext to extend from mask vector.
      // Instead we use the following instructions to extend from mask vector:
      // vmv.v.i v8, 0
      // vmerge.vim v8, v8, -1, v0 (repeated per split)
      return getRISCVInstructionCost(RISCV::VMV_V_I, DstLT.second, CostKind) +
             DstLT.first * getRISCVInstructionCost(RISCV::VMERGE_VIM,
                                                   DstLT.second, CostKind) +
             DstLT.first - 1;
    }
    break;
  case ISD::TRUNCATE:
    if (Dst->getScalarSizeInBits() == 1) {
      // We do not use several vncvt to truncate to mask vector. So we could
      // not use PowDiff to calculate it.
      // Instead we use the following instructions to truncate to mask vector:
      // vand.vi v8, v8, 1
      // vmsne.vi v0, v8, 0
      return SrcLT.first *
                 getRISCVInstructionCost({RISCV::VAND_VI, RISCV::VMSNE_VI},
                                         SrcLT.second, CostKind) +
             SrcLT.first - 1;
    }
    break;
  };

  // Our actual lowering for the case where a wider legal type is available
  // uses promotion to the wider type.  This is reflected in the result of
  // getTypeLegalizationCost, but BasicTTI assumes the widened cases are
  // scalarized if the legalized Src and Dst are not equal sized.
  const DataLayout &DL = this->getDataLayout();
  if (!SrcLT.second.isVector() || !DstLT.second.isVector() ||
      !SrcLT.first.isValid() || !DstLT.first.isValid() ||
      !TypeSize::isKnownLE(DL.getTypeSizeInBits(Src),
                           SrcLT.second.getSizeInBits()) ||
      !TypeSize::isKnownLE(DL.getTypeSizeInBits(Dst),
                           DstLT.second.getSizeInBits()) ||
      SrcLT.first > 1 || DstLT.first > 1)
    return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);

  // The split cost is handled by the base getCastInstrCost
  assert((SrcLT.first == 1) && (DstLT.first == 1) && "Illegal type");

  int PowDiff = (int)Log2_32(DstLT.second.getScalarSizeInBits()) -
                (int)Log2_32(SrcLT.second.getScalarSizeInBits());
  switch (ISD) {
  case ISD::SIGN_EXTEND:
  case ISD::ZERO_EXTEND: {
    if ((PowDiff < 1) || (PowDiff > 3))
      return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
    unsigned SExtOp[] = {RISCV::VSEXT_VF2, RISCV::VSEXT_VF4, RISCV::VSEXT_VF8};
    unsigned ZExtOp[] = {RISCV::VZEXT_VF2, RISCV::VZEXT_VF4, RISCV::VZEXT_VF8};
    unsigned Op =
        (ISD == ISD::SIGN_EXTEND) ? SExtOp[PowDiff - 1] : ZExtOp[PowDiff - 1];
    return getRISCVInstructionCost(Op, DstLT.second, CostKind);
  }
  case ISD::TRUNCATE:
  case ISD::FP_EXTEND:
  case ISD::FP_ROUND: {
    // Counts of narrow/widen instructions.
    unsigned SrcEltSize = SrcLT.second.getScalarSizeInBits();
    unsigned DstEltSize = DstLT.second.getScalarSizeInBits();

    unsigned Op = (ISD == ISD::TRUNCATE)    ? RISCV::VNSRL_WI
                  : (ISD == ISD::FP_EXTEND) ? RISCV::VFWCVT_F_F_V
                                            : RISCV::VFNCVT_F_F_W;
    InstructionCost Cost = 0;
    for (; SrcEltSize != DstEltSize;) {
      MVT ElementMVT = (ISD == ISD::TRUNCATE)
                           ? MVT::getIntegerVT(DstEltSize)
                           : MVT::getFloatingPointVT(DstEltSize);
      MVT DstMVT = DstLT.second.changeVectorElementType(ElementMVT);
      DstEltSize =
          (DstEltSize > SrcEltSize) ? DstEltSize >> 1 : DstEltSize << 1;
      Cost += getRISCVInstructionCost(Op, DstMVT, CostKind);
    }
    return Cost;
  }
  case ISD::FP_TO_SINT:
  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 zvfhmin 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);
      }
    }
    return Cost;
  }
  case ISD::SINT_TO_FP:
  case ISD::UINT_TO_FP: {
    unsigned IsSigned = ISD == ISD::SINT_TO_FP;
    unsigned FCVT = IsSigned ? RISCV::VFCVT_F_X_V : RISCV::VFCVT_F_XU_V;
    unsigned FWCVT = IsSigned ? RISCV::VFWCVT_F_X_V : RISCV::VFWCVT_F_XU_V;
    unsigned FNCVT = IsSigned ? RISCV::VFNCVT_F_X_W : RISCV::VFNCVT_F_XU_W;
    unsigned SrcEltSize = Src->getScalarSizeInBits();
    unsigned DstEltSize = Dst->getScalarSizeInBits();

    InstructionCost Cost = 0;
    if ((DstEltSize == 16) &&
        (!ST->hasVInstructionsF16() || ((SrcEltSize / 2) > DstEltSize))) {
      // If the target only supports zvfhmin or it is i64-to-fp16 conversion
      // it is converted to f32 and then converted to f16
      VectorType *VecF32Ty =
          VectorType::get(Type::getFloatTy(Dst->getContext()),
                          cast<VectorType>(Dst)->getElementCount());
      std::pair<InstructionCost, MVT> VecF32LT =
          getTypeLegalizationCost(VecF32Ty);
      Cost += getCastInstrCost(Opcode, VecF32Ty, Src, CCH, CostKind, I);
      Cost += VecF32LT.first * getRISCVInstructionCost(RISCV::VFNCVT_F_F_W,
                                                       DstLT.second, CostKind);
      return Cost;
    }

    if (DstEltSize == SrcEltSize)
      Cost += getRISCVInstructionCost(FCVT, DstLT.second, CostKind);
    else if (DstEltSize > SrcEltSize) {
      if ((DstEltSize / 2) > SrcEltSize) {
        VectorType *VecTy =
            VectorType::get(IntegerType::get(Dst->getContext(), DstEltSize / 2),
                            cast<VectorType>(Dst)->getElementCount());
        unsigned Op = IsSigned ? Instruction::SExt : Instruction::ZExt;
        Cost += getCastInstrCost(Op, VecTy, Src, CCH, CostKind, I);
      }
      Cost += getRISCVInstructionCost(FWCVT, DstLT.second, CostKind);
    } else
      Cost += getRISCVInstructionCost(FNCVT, DstLT.second, CostKind);
    return Cost;
  }
  }
  return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
}

unsigned RISCVTTIImpl::getEstimatedVLFor(VectorType *Ty) const {
  if (isa<ScalableVectorType>(Ty)) {
    const unsigned EltSize = DL.getTypeSizeInBits(Ty->getElementType());
    const unsigned MinSize = DL.getTypeSizeInBits(Ty).getKnownMinValue();
    const unsigned VectorBits = *getVScaleForTuning() * RISCV::RVVBitsPerBlock;
    return RISCVTargetLowering::computeVLMAX(VectorBits, EltSize, MinSize);
  }
  return cast<FixedVectorType>(Ty)->getNumElements();
}

InstructionCost
RISCVTTIImpl::getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty,
                                     FastMathFlags FMF,
                                     TTI::TargetCostKind CostKind) const {
  if (isa<FixedVectorType>(Ty) && !ST->useRVVForFixedLengthVectors())
    return BaseT::getMinMaxReductionCost(IID, Ty, FMF, CostKind);

  // Skip if scalar size of Ty is bigger than ELEN.
  if (Ty->getScalarSizeInBits() > ST->getELen())
    return BaseT::getMinMaxReductionCost(IID, Ty, FMF, CostKind);

  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
  if (Ty->getElementType()->isIntegerTy(1)) {
    // SelectionDAGBuilder does following transforms:
    //   vector_reduce_{smin,umax}(<n x i1>) --> vector_reduce_or(<n x i1>)
    //   vector_reduce_{smax,umin}(<n x i1>) --> vector_reduce_and(<n x i1>)
    if (IID == Intrinsic::umax || IID == Intrinsic::smin)
      return getArithmeticReductionCost(Instruction::Or, Ty, FMF, CostKind);
    else
      return getArithmeticReductionCost(Instruction::And, Ty, FMF, CostKind);
  }

  if (IID == Intrinsic::maximum || IID == Intrinsic::minimum) {
    SmallVector<unsigned, 3> Opcodes;
    InstructionCost ExtraCost = 0;
    switch (IID) {
    case Intrinsic::maximum:
      if (FMF.noNaNs()) {
        Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
      } else {
        Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMAX_VS,
                   RISCV::VFMV_F_S};
        // Cost of Canonical Nan + branch
        // lui a0, 523264
        // fmv.w.x fa0, a0
        Type *DstTy = Ty->getScalarType();
        const unsigned EltTyBits = DstTy->getScalarSizeInBits();
        Type *SrcTy = IntegerType::getIntNTy(DstTy->getContext(), EltTyBits);
        ExtraCost = 1 +
                    getCastInstrCost(Instruction::UIToFP, DstTy, SrcTy,
                                     TTI::CastContextHint::None, CostKind) +
                    getCFInstrCost(Instruction::CondBr, CostKind);
      }
      break;

    case Intrinsic::minimum:
      if (FMF.noNaNs()) {
        Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
      } else {
        Opcodes = {RISCV::VMFNE_VV, RISCV::VCPOP_M, RISCV::VFREDMIN_VS,
                   RISCV::VFMV_F_S};
        // Cost of Canonical Nan + branch
        // lui a0, 523264
        // fmv.w.x fa0, a0
        Type *DstTy = Ty->getScalarType();
        const unsigned EltTyBits = DL.getTypeSizeInBits(DstTy);
        Type *SrcTy = IntegerType::getIntNTy(DstTy->getContext(), EltTyBits);
        ExtraCost = 1 +
                    getCastInstrCost(Instruction::UIToFP, DstTy, SrcTy,
                                     TTI::CastContextHint::None, CostKind) +
                    getCFInstrCost(Instruction::CondBr, CostKind);
      }
      break;
    }
    return ExtraCost + getRISCVInstructionCost(Opcodes, LT.second, CostKind);
  }

  // IR Reduction is composed by one rvv reduction instruction and vmv
  unsigned SplitOp;
  SmallVector<unsigned, 3> Opcodes;
  switch (IID) {
  default:
    llvm_unreachable("Unsupported intrinsic");
  case Intrinsic::smax:
    SplitOp = RISCV::VMAX_VV;
    Opcodes = {RISCV::VREDMAX_VS, RISCV::VMV_X_S};
    break;
  case Intrinsic::smin:
    SplitOp = RISCV::VMIN_VV;
    Opcodes = {RISCV::VREDMIN_VS, RISCV::VMV_X_S};
    break;
  case Intrinsic::umax:
    SplitOp = RISCV::VMAXU_VV;
    Opcodes = {RISCV::VREDMAXU_VS, RISCV::VMV_X_S};
    break;
  case Intrinsic::umin:
    SplitOp = RISCV::VMINU_VV;
    Opcodes = {RISCV::VREDMINU_VS, RISCV::VMV_X_S};
    break;
  case Intrinsic::maxnum:
    SplitOp = RISCV::VFMAX_VV;
    Opcodes = {RISCV::VFREDMAX_VS, RISCV::VFMV_F_S};
    break;
  case Intrinsic::minnum:
    SplitOp = RISCV::VFMIN_VV;
    Opcodes = {RISCV::VFREDMIN_VS, RISCV::VFMV_F_S};
    break;
  }
  // Add a cost for data larger than LMUL8
  InstructionCost SplitCost =
      (LT.first > 1) ? (LT.first - 1) *
                           getRISCVInstructionCost(SplitOp, LT.second, CostKind)
                     : 0;
  return SplitCost + getRISCVInstructionCost(Opcodes, LT.second, CostKind);
}

InstructionCost
RISCVTTIImpl::getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
                                         std::optional<FastMathFlags> FMF,
                                         TTI::TargetCostKind CostKind) const {
  if (isa<FixedVectorType>(Ty) && !ST->useRVVForFixedLengthVectors())
    return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);

  // Skip if scalar size of Ty is bigger than ELEN.
  if (Ty->getScalarSizeInBits() > ST->getELen())
    return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);

  int ISD = TLI->InstructionOpcodeToISD(Opcode);
  assert(ISD && "Invalid opcode");

  if (ISD != ISD::ADD && ISD != ISD::OR && ISD != ISD::XOR && ISD != ISD::AND &&
      ISD != ISD::FADD)
    return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);

  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
  Type *ElementTy = Ty->getElementType();
  if (ElementTy->isIntegerTy(1)) {
    // Example sequences:
    //   vfirst.m a0, v0
    //   seqz a0, a0
    if (LT.second == MVT::v1i1)
      return getRISCVInstructionCost(RISCV::VFIRST_M, LT.second, CostKind) +
             getCmpSelInstrCost(Instruction::ICmp, ElementTy, ElementTy,
                                CmpInst::ICMP_EQ, CostKind);

    if (ISD == ISD::AND) {
      // Example sequences:
      //   vmand.mm v8, v9, v8 ; needed every time type is split
      //   vmnot.m v8, v0      ; alias for vmnand
      //   vcpop.m a0, v8
      //   seqz a0, a0

      // See the discussion: https://github.com/llvm/llvm-project/pull/119160
      // For LMUL <= 8, there is no splitting,
      //   the sequences are vmnot, vcpop and seqz.
      // When LMUL > 8 and split = 1,
      //   the sequences are vmnand, vcpop and seqz.
      // When LMUL > 8 and split > 1,
      //   the sequences are (LT.first-2) * vmand, vmnand, vcpop and seqz.
      return ((LT.first > 2) ? (LT.first - 2) : 0) *
                 getRISCVInstructionCost(RISCV::VMAND_MM, LT.second, CostKind) +
             getRISCVInstructionCost(RISCV::VMNAND_MM, LT.second, CostKind) +
             getRISCVInstructionCost(RISCV::VCPOP_M, LT.second, CostKind) +
             getCmpSelInstrCost(Instruction::ICmp, ElementTy, ElementTy,
                                CmpInst::ICMP_EQ, CostKind);
    } else if (ISD == ISD::XOR || ISD == ISD::ADD) {
      // Example sequences:
      //   vsetvli a0, zero, e8, mf8, ta, ma
      //   vmxor.mm v8, v0, v8 ; needed every time type is split
      //   vcpop.m a0, v8
      //   andi a0, a0, 1
      return (LT.first - 1) *
                 getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second, CostKind) +
             getRISCVInstructionCost(RISCV::VCPOP_M, LT.second, CostKind) + 1;
    } else {
      assert(ISD == ISD::OR);
      // Example sequences:
      //   vsetvli a0, zero, e8, mf8, ta, ma
      //   vmor.mm v8, v9, v8 ; needed every time type is split
      //   vcpop.m a0, v0
      //   snez a0, a0
      return (LT.first - 1) *
                 getRISCVInstructionCost(RISCV::VMOR_MM, LT.second, CostKind) +
             getRISCVInstructionCost(RISCV::VCPOP_M, LT.second, CostKind) +
             getCmpSelInstrCost(Instruction::ICmp, ElementTy, ElementTy,
                                CmpInst::ICMP_NE, CostKind);
    }
  }

  // IR Reduction of or/and is composed by one vmv and one rvv reduction
  // instruction, and others is composed by two vmv and one rvv reduction
  // instruction
  unsigned SplitOp;
  SmallVector<unsigned, 3> Opcodes;
  switch (ISD) {
  case ISD::ADD:
    SplitOp = RISCV::VADD_VV;
    Opcodes = {RISCV::VMV_S_X, RISCV::VREDSUM_VS, RISCV::VMV_X_S};
    break;
  case ISD::OR:
    SplitOp = RISCV::VOR_VV;
    Opcodes = {RISCV::VREDOR_VS, RISCV::VMV_X_S};
    break;
  case ISD::XOR:
    SplitOp = RISCV::VXOR_VV;
    Opcodes = {RISCV::VMV_S_X, RISCV::VREDXOR_VS, RISCV::VMV_X_S};
    break;
  case ISD::AND:
    SplitOp = RISCV::VAND_VV;
    Opcodes = {RISCV::VREDAND_VS, RISCV::VMV_X_S};
    break;
  case ISD::FADD:
    // We can't promote f16/bf16 fadd reductions.
    if ((LT.second.getScalarType() == MVT::f16 && !ST->hasVInstructionsF16()) ||
        LT.second.getScalarType() == MVT::bf16)
      return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
    if (TTI::requiresOrderedReduction(FMF)) {
      Opcodes.push_back(RISCV::VFMV_S_F);
      for (unsigned i = 0; i < LT.first.getValue(); i++)
        Opcodes.push_back(RISCV::VFREDOSUM_VS);
      Opcodes.push_back(RISCV::VFMV_F_S);
      return getRISCVInstructionCost(Opcodes, LT.second, CostKind);
    }
    SplitOp = RISCV::VFADD_VV;
    Opcodes = {RISCV::VFMV_S_F, RISCV::VFREDUSUM_VS, RISCV::VFMV_F_S};
    break;
  }
  // Add a cost for data larger than LMUL8
  InstructionCost SplitCost =
      (LT.first > 1) ? (LT.first - 1) *
                           getRISCVInstructionCost(SplitOp, LT.second, CostKind)
                     : 0;
  return SplitCost + getRISCVInstructionCost(Opcodes, LT.second, CostKind);
}

InstructionCost RISCVTTIImpl::getExtendedReductionCost(
    unsigned Opcode, bool IsUnsigned, Type *ResTy, VectorType *ValTy,
    std::optional<FastMathFlags> FMF, TTI::TargetCostKind CostKind) const {
  if (isa<FixedVectorType>(ValTy) && !ST->useRVVForFixedLengthVectors())
    return BaseT::getExtendedReductionCost(Opcode, IsUnsigned, ResTy, ValTy,
                                           FMF, CostKind);

  // Skip if scalar size of ResTy is bigger than ELEN.
  if (ResTy->getScalarSizeInBits() > ST->getELen())
    return BaseT::getExtendedReductionCost(Opcode, IsUnsigned, ResTy, ValTy,
                                           FMF, CostKind);

  if (Opcode != Instruction::Add && Opcode != Instruction::FAdd)
    return BaseT::getExtendedReductionCost(Opcode, IsUnsigned, ResTy, ValTy,
                                           FMF, CostKind);

  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);

  if (IsUnsigned && Opcode == Instruction::Add &&
      LT.second.isFixedLengthVector() && LT.second.getScalarType() == MVT::i1) {
    // Represent vector_reduce_add(ZExt(<n x i1>)) as
    // ZExtOrTrunc(ctpop(bitcast <n x i1> to in)).
    return LT.first *
           getRISCVInstructionCost(RISCV::VCPOP_M, LT.second, CostKind);
  }

  if (ResTy->getScalarSizeInBits() != 2 * LT.second.getScalarSizeInBits())
    return BaseT::getExtendedReductionCost(Opcode, IsUnsigned, ResTy, ValTy,
                                           FMF, CostKind);

  return (LT.first - 1) +
         getArithmeticReductionCost(Opcode, ValTy, FMF, CostKind);
}

InstructionCost
RISCVTTIImpl::getStoreImmCost(Type *Ty, TTI::OperandValueInfo OpInfo,
                              TTI::TargetCostKind CostKind) const {
  assert(OpInfo.isConstant() && "non constant operand?");
  if (!isa<VectorType>(Ty))
    // FIXME: We need to account for immediate materialization here, but doing
    // a decent job requires more knowledge about the immediate than we
    // currently have here.
    return 0;

  if (OpInfo.isUniform())
    // vmv.v.i, vmv.v.x, or vfmv.v.f
    // We ignore the cost of the scalar constant materialization to be consistent
    // with how we treat scalar constants themselves just above.
    return 1;

  return getConstantPoolLoadCost(Ty, CostKind);
}

InstructionCost RISCVTTIImpl::getMemoryOpCost(unsigned Opcode, Type *Src,
                                              Align Alignment,
                                              unsigned AddressSpace,
                                              TTI::TargetCostKind CostKind,
                                              TTI::OperandValueInfo OpInfo,
                                              const Instruction *I) const {
  EVT VT = TLI->getValueType(DL, Src, true);
  // Type legalization can't handle structs
  if (VT == MVT::Other)
    return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
                                  CostKind, OpInfo, I);

  InstructionCost Cost = 0;
  if (Opcode == Instruction::Store && OpInfo.isConstant())
    Cost += getStoreImmCost(Src, OpInfo, CostKind);

  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);

  InstructionCost BaseCost = [&]() {
    InstructionCost Cost = LT.first;
    if (CostKind != TTI::TCK_RecipThroughput)
      return Cost;

    // Our actual lowering for the case where a wider legal type is available
    // uses the a VL predicated load on the wider type.  This is reflected in
    // the result of getTypeLegalizationCost, but BasicTTI assumes the
    // widened cases are scalarized.
    const DataLayout &DL = this->getDataLayout();
    if (Src->isVectorTy() && LT.second.isVector() &&
        TypeSize::isKnownLT(DL.getTypeStoreSizeInBits(Src),
                            LT.second.getSizeInBits()))
        return Cost;

    return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
                                  CostKind, OpInfo, I);
  }();

  // Assume memory ops cost scale with the number of vector registers
  // possible accessed by the instruction.  Note that BasicTTI already
  // handles the LT.first term for us.
  if (ST->hasVInstructions() && LT.second.isVector() &&
      CostKind != TTI::TCK_CodeSize)
    BaseCost *= TLI->getLMULCost(LT.second);
  return Cost + BaseCost;
}

InstructionCost RISCVTTIImpl::getCmpSelInstrCost(
    unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
    TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info,
    TTI::OperandValueInfo Op2Info, const Instruction *I) const {
  if (CostKind != TTI::TCK_RecipThroughput)
    return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
                                     Op1Info, Op2Info, I);

  if (isa<FixedVectorType>(ValTy) && !ST->useRVVForFixedLengthVectors())
    return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
                                     Op1Info, Op2Info, I);

  // Skip if scalar size of ValTy is bigger than ELEN.
  if (ValTy->isVectorTy() && ValTy->getScalarSizeInBits() > ST->getELen())
    return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
                                     Op1Info, Op2Info, I);

  auto GetConstantMatCost =
      [&](TTI::OperandValueInfo OpInfo) -> InstructionCost {
    if (OpInfo.isUniform())
      // We return 0 we currently ignore the cost of materializing scalar
      // constants in GPRs.
      return 0;

    return getConstantPoolLoadCost(ValTy, CostKind);
  };

  InstructionCost ConstantMatCost;
  if (Op1Info.isConstant())
    ConstantMatCost += GetConstantMatCost(Op1Info);
  if (Op2Info.isConstant())
    ConstantMatCost += GetConstantMatCost(Op2Info);

  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
  if (Opcode == Instruction::Select && ValTy->isVectorTy()) {
    if (CondTy->isVectorTy()) {
      if (ValTy->getScalarSizeInBits() == 1) {
        // vmandn.mm v8, v8, v9
        // vmand.mm v9, v0, v9
        // vmor.mm v0, v9, v8
        return ConstantMatCost +
               LT.first *
                   getRISCVInstructionCost(
                       {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
                       LT.second, CostKind);
      }
      // vselect and max/min are supported natively.
      return ConstantMatCost +
             LT.first * getRISCVInstructionCost(RISCV::VMERGE_VVM, LT.second,
                                                CostKind);
    }

    if (ValTy->getScalarSizeInBits() == 1) {
      //  vmv.v.x v9, a0
      //  vmsne.vi v9, v9, 0
      //  vmandn.mm v8, v8, v9
      //  vmand.mm v9, v0, v9
      //  vmor.mm v0, v9, v8
      MVT InterimVT = LT.second.changeVectorElementType(MVT::i8);
      return ConstantMatCost +
             LT.first *
                 getRISCVInstructionCost({RISCV::VMV_V_X, RISCV::VMSNE_VI},
                                         InterimVT, CostKind) +
             LT.first * getRISCVInstructionCost(
                            {RISCV::VMANDN_MM, RISCV::VMAND_MM, RISCV::VMOR_MM},
                            LT.second, CostKind);
    }

    // vmv.v.x v10, a0
    // vmsne.vi v0, v10, 0
    // vmerge.vvm v8, v9, v8, v0
    return ConstantMatCost +
           LT.first * getRISCVInstructionCost(
                          {RISCV::VMV_V_X, RISCV::VMSNE_VI, RISCV::VMERGE_VVM},
                          LT.second, CostKind);
  }

  if ((Opcode == Instruction::ICmp) && ValTy->isVectorTy() &&
      CmpInst::isIntPredicate(VecPred)) {
    // Use VMSLT_VV to represent VMSEQ, VMSNE, VMSLTU, VMSLEU, VMSLT, VMSLE
    // provided they incur the same cost across all implementations
    return ConstantMatCost + LT.first * getRISCVInstructionCost(RISCV::VMSLT_VV,
                                                                LT.second,
                                                                CostKind);
  }

  if ((Opcode == Instruction::FCmp) && ValTy->isVectorTy() &&
      CmpInst::isFPPredicate(VecPred)) {

    // Use VMXOR_MM and VMXNOR_MM to generate all true/false mask
    if ((VecPred == CmpInst::FCMP_FALSE) || (VecPred == CmpInst::FCMP_TRUE))
      return ConstantMatCost +
             getRISCVInstructionCost(RISCV::VMXOR_MM, LT.second, CostKind);

    // If we do not support the input floating point vector type, use the base
    // one which will calculate as:
    // ScalarizeCost + Num * Cost for fixed vector,
    // InvalidCost for scalable vector.
    if ((ValTy->getScalarSizeInBits() == 16 && !ST->hasVInstructionsF16()) ||
        (ValTy->getScalarSizeInBits() == 32 && !ST->hasVInstructionsF32()) ||
        (ValTy->getScalarSizeInBits() == 64 && !ST->hasVInstructionsF64()))
      return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
                                       Op1Info, Op2Info, I);

    // Assuming vector fp compare and mask instructions are all the same cost
    // until a need arises to differentiate them.
    switch (VecPred) {
    case CmpInst::FCMP_ONE: // vmflt.vv + vmflt.vv + vmor.mm
    case CmpInst::FCMP_ORD: // vmfeq.vv + vmfeq.vv + vmand.mm
    case CmpInst::FCMP_UNO: // vmfne.vv + vmfne.vv + vmor.mm
    case CmpInst::FCMP_UEQ: // vmflt.vv + vmflt.vv + vmnor.mm
      return ConstantMatCost +
             LT.first * getRISCVInstructionCost(
                            {RISCV::VMFLT_VV, RISCV::VMFLT_VV, RISCV::VMOR_MM},
                            LT.second, CostKind);

    case CmpInst::FCMP_UGT: // vmfle.vv + vmnot.m
    case CmpInst::FCMP_UGE: // vmflt.vv + vmnot.m
    case CmpInst::FCMP_ULT: // vmfle.vv + vmnot.m
    case CmpInst::FCMP_ULE: // vmflt.vv + vmnot.m
      return ConstantMatCost +
             LT.first *
                 getRISCVInstructionCost({RISCV::VMFLT_VV, RISCV::VMNAND_MM},
                                         LT.second, CostKind);

    case CmpInst::FCMP_OEQ: // vmfeq.vv
    case CmpInst::FCMP_OGT: // vmflt.vv
    case CmpInst::FCMP_OGE: // vmfle.vv
    case CmpInst::FCMP_OLT: // vmflt.vv
    case CmpInst::FCMP_OLE: // vmfle.vv
    case CmpInst::FCMP_UNE: // vmfne.vv
      return ConstantMatCost +
             LT.first *
                 getRISCVInstructionCost(RISCV::VMFLT_VV, LT.second, CostKind);
    default:
      break;
    }
  }

  // With ShortForwardBranchOpt or ConditionalMoveFusion, scalar icmp + select
  // instructions will lower to SELECT_CC and lower to PseudoCCMOVGPR which will
  // generate a conditional branch + mv. The cost of scalar (icmp + select) will
  // be (0 + select instr cost).
  if (ST->hasConditionalMoveFusion() && I && isa<ICmpInst>(I) &&
      ValTy->isIntegerTy() && !I->user_empty()) {
    if (all_of(I->users(), [&](const User *U) {
          return match(U, m_Select(m_Specific(I), m_Value(), m_Value())) &&
                 U->getType()->isIntegerTy() &&
                 !isa<ConstantData>(U->getOperand(1)) &&
                 !isa<ConstantData>(U->getOperand(2));
        }))
      return 0;
  }

  // TODO: Add cost for scalar type.

  return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
                                   Op1Info, Op2Info, I);
}

InstructionCost RISCVTTIImpl::getCFInstrCost(unsigned Opcode,
                                             TTI::TargetCostKind CostKind,
                                             const Instruction *I) const {
  if (CostKind != TTI::TCK_RecipThroughput)
    return Opcode == Instruction::PHI ? 0 : 1;
  // Branches are assumed to be predicted.
  return 0;
}

InstructionCost RISCVTTIImpl::getVectorInstrCost(
    unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
    const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
  assert(Val->isVectorTy() && "This must be a vector type");

  // TODO: Add proper cost model for P extension fixed vectors (e.g., v4i16)
  // For now, skip all fixed vector cost analysis when P extension is available
  // to avoid crashes in getMinRVVVectorSizeInBits()
  if (ST->hasStdExtP() && isa<FixedVectorType>(Val)) {
    return 1; // Treat as single instruction cost for now
  }

  if (Opcode != Instruction::ExtractElement &&
      Opcode != Instruction::InsertElement)
    return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1,
                                     VIC);

  // Legalize the type.
  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Val);

  // This type is legalized to a scalar type.
  if (!LT.second.isVector()) {
    auto *FixedVecTy = cast<FixedVectorType>(Val);
    // If Index is a known constant, cost is zero.
    if (Index != -1U)
      return 0;
    // Extract/InsertElement with non-constant index is very costly when
    // scalarized; estimate cost of loads/stores sequence via the stack:
    // ExtractElement cost: store vector to stack, load scalar;
    // InsertElement cost: store vector to stack, store scalar, load vector.
    Type *ElemTy = FixedVecTy->getElementType();
    auto NumElems = FixedVecTy->getNumElements();
    auto Align = DL.getPrefTypeAlign(ElemTy);
    InstructionCost LoadCost =
        getMemoryOpCost(Instruction::Load, ElemTy, Align, 0, CostKind);
    InstructionCost StoreCost =
        getMemoryOpCost(Instruction::Store, ElemTy, Align, 0, CostKind);
    return Opcode == Instruction::ExtractElement
               ? StoreCost * NumElems + LoadCost
               : (StoreCost + LoadCost) * NumElems + StoreCost;
  }

  // For unsupported scalable vector.
  if (LT.second.isScalableVector() && !LT.first.isValid())
    return LT.first;

  // Mask vector extract/insert is expanded via e8.
  if (Val->getScalarSizeInBits() == 1) {
    VectorType *WideTy =
      VectorType::get(IntegerType::get(Val->getContext(), 8),
                      cast<VectorType>(Val)->getElementCount());
    if (Opcode == Instruction::ExtractElement) {
      InstructionCost ExtendCost
        = getCastInstrCost(Instruction::ZExt, WideTy, Val,
                           TTI::CastContextHint::None, CostKind);
      InstructionCost ExtractCost
        = getVectorInstrCost(Opcode, WideTy, CostKind, Index, nullptr, nullptr);
      return ExtendCost + ExtractCost;
    }
    InstructionCost ExtendCost
      = getCastInstrCost(Instruction::ZExt, WideTy, Val,
                         TTI::CastContextHint::None, CostKind);
    InstructionCost InsertCost
      = getVectorInstrCost(Opcode, WideTy, CostKind, Index, nullptr, nullptr);
    InstructionCost TruncCost
      = getCastInstrCost(Instruction::Trunc, Val, WideTy,
                         TTI::CastContextHint::None, CostKind);
    return ExtendCost + InsertCost + TruncCost;
  }


  // In RVV, we could use vslidedown + vmv.x.s to extract element from vector
  // and vslideup + vmv.s.x to insert element to vector.
  unsigned BaseCost = 1;
  // When insertelement we should add the index with 1 as the input of vslideup.
  unsigned SlideCost = Opcode == Instruction::InsertElement ? 2 : 1;

  if (Index != -1U) {
    // The type may be split. For fixed-width vectors we can normalize the
    // index to the new type.
    if (LT.second.isFixedLengthVector()) {
      unsigned Width = LT.second.getVectorNumElements();
      Index = Index % Width;
    }

    // If exact VLEN is known, we will insert/extract into the appropriate
    // subvector with no additional subvector insert/extract cost.
    if (auto VLEN = ST->getRealVLen()) {
      unsigned EltSize = LT.second.getScalarSizeInBits();
      unsigned M1Max = *VLEN / EltSize;
      Index = Index % M1Max;
    }

    if (Index == 0)
      // We can extract/insert the first element without vslidedown/vslideup.
      SlideCost = 0;
    else if (Opcode == Instruction::InsertElement)
      SlideCost = 1; // With a constant index, we do not need to use addi.
  }

  // When the vector needs to split into multiple register groups and the index
  // exceeds single vector register group, we need to insert/extract the element
  // via stack.
  if (LT.first > 1 &&
      ((Index == -1U) || (Index >= LT.second.getVectorMinNumElements() &&
                          LT.second.isScalableVector()))) {
    Type *ScalarType = Val->getScalarType();
    Align VecAlign = DL.getPrefTypeAlign(Val);
    Align SclAlign = DL.getPrefTypeAlign(ScalarType);
    // Extra addi for unknown index.
    InstructionCost IdxCost = Index == -1U ? 1 : 0;

    // Store all split vectors into stack and load the target element.
    if (Opcode == Instruction::ExtractElement)
      return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
             getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
                             CostKind) +
             IdxCost;

    // Store all split vectors into stack and store the target element and load
    // vectors back.
    return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
           getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind) +
           getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
                           CostKind) +
           IdxCost;
  }

  // Extract i64 in the target that has XLEN=32 need more instruction.
  if (Val->getScalarType()->isIntegerTy() &&
      ST->getXLen() < Val->getScalarSizeInBits()) {
    // For extractelement, we need the following instructions:
    // vsetivli zero, 1, e64, m1, ta, mu (not count)
    // vslidedown.vx v8, v8, a0
    // vmv.x.s a0, v8
    // li a1, 32
    // vsrl.vx v8, v8, a1
    // vmv.x.s a1, v8

    // For insertelement, we need the following instructions:
    // vsetivli zero, 2, e32, m4, ta, mu (not count)
    // vmv.v.i v12, 0
    // vslide1up.vx v16, v12, a1
    // vslide1up.vx v12, v16, a0
    // addi a0, a2, 1
    // vsetvli zero, a0, e64, m4, tu, mu (not count)
    // vslideup.vx v8, v12, a2

    // TODO: should we count these special vsetvlis?
    BaseCost = Opcode == Instruction::InsertElement ? 3 : 4;
  }
  return BaseCost + SlideCost;
}

InstructionCost
RISCVTTIImpl::getIndexedVectorInstrCostFromEnd(unsigned Opcode, Type *Val,
                                               TTI::TargetCostKind CostKind,
                                               unsigned Index) const {
  if (isa<FixedVectorType>(Val))
    return BaseT::getIndexedVectorInstrCostFromEnd(Opcode, Val, CostKind,
                                                   Index);

  // TODO: This code replicates what LoopVectorize.cpp used to do when asking
  // for the cost of extracting the last lane of a scalable vector. It probably
  // needs a more accurate cost.
  ElementCount EC = cast<VectorType>(Val)->getElementCount();
  assert(Index < EC.getKnownMinValue() && "Unexpected reverse index");
  return getVectorInstrCost(Opcode, Val, CostKind,
                            EC.getKnownMinValue() - 1 - Index, nullptr,
                            nullptr);
}

/// Check to see if this instruction is expected to be combined to a simpler
/// operation during/before lowering. If so return the cost of the combined
/// operation rather than provided one. For instance, `udiv i16 %X, 2` is likely
/// to be combined to `lshr i16 %X, 1`, so return the cost of a `lshr` rather
/// than the cost of a `udiv`
std::optional<InstructionCost>
RISCVTTIImpl::getCombinedArithmeticInstructionCost(
    unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
    TTI::OperandValueInfo Opd1Info, TTI::OperandValueInfo Opd2Info,
    ArrayRef<const Value *> Args, const Instruction *CxtI) const {
  // Vector unsigned division/remainder will be simplified to shifts/masks.
  if ((Opcode == Instruction::UDiv || Opcode == Instruction::URem) &&
      Opd2Info.isConstant() && Opd2Info.isPowerOf2()) {
    if (Opcode == Instruction::UDiv)
      return getArithmeticInstrCost(Instruction::LShr, Ty, CostKind, Opd1Info,
                                    Opd2Info.getNoProps());
    // UREM
    return getArithmeticInstrCost(Instruction::And, Ty, CostKind, Opd1Info,
                                  Opd2Info.getNoProps());
  }
  return std::nullopt;
}

InstructionCost RISCVTTIImpl::getArithmeticInstrCost(
    unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
    TTI::OperandValueInfo Op1Info, TTI::OperandValueInfo Op2Info,
    ArrayRef<const Value *> Args, const Instruction *CxtI) const {

  // TODO: Handle more cost kinds.
  if (CostKind != TTI::TCK_RecipThroughput)
    return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
                                         Args, CxtI);

  if (isa<FixedVectorType>(Ty) && !ST->useRVVForFixedLengthVectors())
    return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
                                         Args, CxtI);

  // Skip if scalar size of Ty is bigger than ELEN.
  if (isa<VectorType>(Ty) && Ty->getScalarSizeInBits() > ST->getELen())
    return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
                                         Args, CxtI);

  if (std::optional<InstructionCost> CombinedCost =
          getCombinedArithmeticInstructionCost(Opcode, Ty, CostKind, Op1Info,
                                               Op2Info, Args, CxtI))
    return *CombinedCost;

  // Legalize the type.
  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
  unsigned ISDOpcode = TLI->InstructionOpcodeToISD(Opcode);

  // TODO: Handle scalar type.
  if (!LT.second.isVector()) {
    static const CostTblEntry DivTbl[]{
        {ISD::UDIV, MVT::i32, TTI::TCC_Expensive},
        {ISD::UDIV, MVT::i64, TTI::TCC_Expensive},
        {ISD::SDIV, MVT::i32, TTI::TCC_Expensive},
        {ISD::SDIV, MVT::i64, TTI::TCC_Expensive},
        {ISD::UREM, MVT::i32, TTI::TCC_Expensive},
        {ISD::UREM, MVT::i64, TTI::TCC_Expensive},
        {ISD::SREM, MVT::i32, TTI::TCC_Expensive},
        {ISD::SREM, MVT::i64, TTI::TCC_Expensive}};
    if (TLI->isOperationLegalOrPromote(ISDOpcode, LT.second))
      if (const auto *Entry = CostTableLookup(DivTbl, ISDOpcode, LT.second))
        return Entry->Cost * LT.first;

    return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
                                         Args, CxtI);
  }

  // f16 with zvfhmin and bf16 will be promoted to f32.
  // FIXME: nxv32[b]f16 will be custom lowered and split.
  InstructionCost CastCost = 0;
  if ((LT.second.getVectorElementType() == MVT::f16 ||
       LT.second.getVectorElementType() == MVT::bf16) &&
      TLI->getOperationAction(ISDOpcode, LT.second) ==
          TargetLoweringBase::LegalizeAction::Promote) {
    MVT PromotedVT = TLI->getTypeToPromoteTo(ISDOpcode, LT.second);
    Type *PromotedTy = EVT(PromotedVT).getTypeForEVT(Ty->getContext());
    Type *LegalTy = EVT(LT.second).getTypeForEVT(Ty->getContext());
    // Add cost of extending arguments
    CastCost += LT.first * Args.size() *
                getCastInstrCost(Instruction::FPExt, PromotedTy, LegalTy,
                                 TTI::CastContextHint::None, CostKind);
    // Add cost of truncating result
    CastCost +=
        LT.first * getCastInstrCost(Instruction::FPTrunc, LegalTy, PromotedTy,
                                    TTI::CastContextHint::None, CostKind);
    // Compute cost of op in promoted type
    LT.second = PromotedVT;
  }

  auto getConstantMatCost =
      [&](unsigned Operand, TTI::OperandValueInfo OpInfo) -> InstructionCost {
    if (OpInfo.isUniform() && canSplatOperand(Opcode, Operand))
      // Two sub-cases:
      // * Has a 5 bit immediate operand which can be splatted.
      // * Has a larger immediate which must be materialized in scalar register
      // We return 0 for both as we currently ignore the cost of materializing
      // scalar constants in GPRs.
      return 0;

    return getConstantPoolLoadCost(Ty, CostKind);
  };

  // Add the cost of materializing any constant vectors required.
  InstructionCost ConstantMatCost = 0;
  if (Op1Info.isConstant())
    ConstantMatCost += getConstantMatCost(0, Op1Info);
  if (Op2Info.isConstant())
    ConstantMatCost += getConstantMatCost(1, Op2Info);

  unsigned Op;
  switch (ISDOpcode) {
  case ISD::ADD:
  case ISD::SUB:
    Op = RISCV::VADD_VV;
    break;
  case ISD::SHL:
  case ISD::SRL:
  case ISD::SRA:
    Op = RISCV::VSLL_VV;
    break;
  case ISD::AND:
  case ISD::OR:
  case ISD::XOR:
    Op = (Ty->getScalarSizeInBits() == 1) ? RISCV::VMAND_MM : RISCV::VAND_VV;
    break;
  case ISD::MUL:
  case ISD::MULHS:
  case ISD::MULHU:
    Op = RISCV::VMUL_VV;
    break;
  case ISD::SDIV:
  case ISD::UDIV:
    Op = RISCV::VDIV_VV;
    break;
  case ISD::SREM:
  case ISD::UREM:
    Op = RISCV::VREM_VV;
    break;
  case ISD::FADD:
  case ISD::FSUB:
    Op = RISCV::VFADD_VV;
    break;
  case ISD::FMUL:
    Op = RISCV::VFMUL_VV;
    break;
  case ISD::FDIV:
    Op = RISCV::VFDIV_VV;
    break;
  case ISD::FNEG:
    Op = RISCV::VFSGNJN_VV;
    break;
  default:
    // Assuming all other instructions have the same cost until a need arises to
    // differentiate them.
    return CastCost + ConstantMatCost +
           BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
                                         Args, CxtI);
  }

  InstructionCost InstrCost = getRISCVInstructionCost(Op, LT.second, CostKind);
  // We use BasicTTIImpl to calculate scalar costs, which assumes floating point
  // ops are twice as expensive as integer ops. Do the same for vectors so
  // scalar floating point ops aren't cheaper than their vector equivalents.
  if (Ty->isFPOrFPVectorTy())
    InstrCost *= 2;
  return CastCost + ConstantMatCost + LT.first * InstrCost;
}

// TODO: Deduplicate from TargetTransformInfoImplCRTPBase.
InstructionCost RISCVTTIImpl::getPointersChainCost(
    ArrayRef<const Value *> Ptrs, const Value *Base,
    const TTI::PointersChainInfo &Info, Type *AccessTy,
    TTI::TargetCostKind CostKind) const {
  InstructionCost Cost = TTI::TCC_Free;
  // In the basic model we take into account GEP instructions only
  // (although here can come alloca instruction, a value, constants and/or
  // constant expressions, PHIs, bitcasts ... whatever allowed to be used as a
  // pointer). Typically, if Base is a not a GEP-instruction and all the
  // pointers are relative to the same base address, all the rest are
  // either GEP instructions, PHIs, bitcasts or constants. When we have same
  // base, we just calculate cost of each non-Base GEP as an ADD operation if
  // any their index is a non-const.
  // If no known dependencies between the pointers cost is calculated as a sum
  // of costs of GEP instructions.
  for (auto [I, V] : enumerate(Ptrs)) {
    const auto *GEP = dyn_cast<GetElementPtrInst>(V);
    if (!GEP)
      continue;
    if (Info.isSameBase() && V != Base) {
      if (GEP->hasAllConstantIndices())
        continue;
      // If the chain is unit-stride and BaseReg + stride*i is a legal
      // addressing mode, then presume the base GEP is sitting around in a
      // register somewhere and check if we can fold the offset relative to
      // it.
      unsigned Stride = DL.getTypeStoreSize(AccessTy);
      if (Info.isUnitStride() &&
          isLegalAddressingMode(AccessTy,
                                /* BaseGV */ nullptr,
                                /* BaseOffset */ Stride * I,
                                /* HasBaseReg */ true,
                                /* Scale */ 0,
                                GEP->getType()->getPointerAddressSpace()))
        continue;
      Cost += getArithmeticInstrCost(Instruction::Add, GEP->getType(), CostKind,
                                     {TTI::OK_AnyValue, TTI::OP_None},
                                     {TTI::OK_AnyValue, TTI::OP_None}, {});
    } else {
      SmallVector<const Value *> Indices(GEP->indices());
      Cost += getGEPCost(GEP->getSourceElementType(), GEP->getPointerOperand(),
                         Indices, AccessTy, CostKind);
    }
  }
  return Cost;
}

void RISCVTTIImpl::getUnrollingPreferences(
    Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP,
    OptimizationRemarkEmitter *ORE) const {
  // TODO: More tuning on benchmarks and metrics with changes as needed
  //       would apply to all settings below to enable performance.


  if (ST->enableDefaultUnroll())
    return BasicTTIImplBase::getUnrollingPreferences(L, SE, UP, ORE);

  // Enable Upper bound unrolling universally, not dependent upon the conditions
  // below.
  UP.UpperBound = true;

  // Disable loop unrolling for Oz and Os.
  UP.OptSizeThreshold = 0;
  UP.PartialOptSizeThreshold = 0;
  if (L->getHeader()->getParent()->hasOptSize())
    return;

  SmallVector<BasicBlock *, 4> ExitingBlocks;
  L->getExitingBlocks(ExitingBlocks);
  LLVM_DEBUG(dbgs() << "Loop has:\n"
                    << "Blocks: " << L->getNumBlocks() << "\n"
                    << "Exit blocks: " << ExitingBlocks.size() << "\n");

  // Only allow another exit other than the latch. This acts as an early exit
  // as it mirrors the profitability calculation of the runtime unroller.
  if (ExitingBlocks.size() > 2)
    return;

  // Limit the CFG of the loop body for targets with a branch predictor.
  // Allowing 4 blocks permits if-then-else diamonds in the body.
  if (L->getNumBlocks() > 4)
    return;

  // Scan the loop: don't unroll loops with calls as this could prevent
  // inlining. Don't unroll auto-vectorized loops either, though do allow
  // unrolling of the scalar remainder.
  bool IsVectorized = getBooleanLoopAttribute(L, "llvm.loop.isvectorized");
  InstructionCost Cost = 0;
  for (auto *BB : L->getBlocks()) {
    for (auto &I : *BB) {
      // Both auto-vectorized loops and the scalar remainder have the
      // isvectorized attribute, so differentiate between them by the presence
      // of vector instructions.
      if (IsVectorized && (I.getType()->isVectorTy() ||
                           llvm::any_of(I.operand_values(), [](Value *V) {
                             return V->getType()->isVectorTy();
                           })))
        return;

      if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
        if (const Function *F = cast<CallBase>(I).getCalledFunction()) {
          if (!isLoweredToCall(F))
            continue;
        }
        return;
      }

      SmallVector<const Value *> Operands(I.operand_values());
      Cost += getInstructionCost(&I, Operands,
                                 TargetTransformInfo::TCK_SizeAndLatency);
    }
  }

  LLVM_DEBUG(dbgs() << "Cost of loop: " << Cost << "\n");

  UP.Partial = true;
  UP.Runtime = true;
  UP.UnrollRemainder = true;
  UP.UnrollAndJam = true;

  // Force unrolling small loops can be very useful because of the branch
  // taken cost of the backedge.
  if (Cost < 12)
    UP.Force = true;
}

void RISCVTTIImpl::getPeelingPreferences(Loop *L, ScalarEvolution &SE,
                                         TTI::PeelingPreferences &PP) const {
  BaseT::getPeelingPreferences(L, SE, PP);
}

bool RISCVTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
                                      MemIntrinsicInfo &Info) const {
  const DataLayout &DL = getDataLayout();
  Intrinsic::ID IID = Inst->getIntrinsicID();
  LLVMContext &C = Inst->getContext();
  bool HasMask = false;

  auto getSegNum = [](const IntrinsicInst *II, unsigned PtrOperandNo,
                      bool IsWrite) -> int64_t {
    if (auto *TarExtTy =
            dyn_cast<TargetExtType>(II->getArgOperand(0)->getType()))
      return TarExtTy->getIntParameter(0);

    return 1;
  };

  switch (IID) {
  case Intrinsic::riscv_vle_mask:
  case Intrinsic::riscv_vse_mask:
  case Intrinsic::riscv_vlseg2_mask:
  case Intrinsic::riscv_vlseg3_mask:
  case Intrinsic::riscv_vlseg4_mask:
  case Intrinsic::riscv_vlseg5_mask:
  case Intrinsic::riscv_vlseg6_mask:
  case Intrinsic::riscv_vlseg7_mask:
  case Intrinsic::riscv_vlseg8_mask:
  case Intrinsic::riscv_vsseg2_mask:
  case Intrinsic::riscv_vsseg3_mask:
  case Intrinsic::riscv_vsseg4_mask:
  case Intrinsic::riscv_vsseg5_mask:
  case Intrinsic::riscv_vsseg6_mask:
  case Intrinsic::riscv_vsseg7_mask:
  case Intrinsic::riscv_vsseg8_mask:
    HasMask = true;
    [[fallthrough]];
  case Intrinsic::riscv_vle:
  case Intrinsic::riscv_vse:
  case Intrinsic::riscv_vlseg2:
  case Intrinsic::riscv_vlseg3:
  case Intrinsic::riscv_vlseg4:
  case Intrinsic::riscv_vlseg5:
  case Intrinsic::riscv_vlseg6:
  case Intrinsic::riscv_vlseg7:
  case Intrinsic::riscv_vlseg8:
  case Intrinsic::riscv_vsseg2:
  case Intrinsic::riscv_vsseg3:
  case Intrinsic::riscv_vsseg4:
  case Intrinsic::riscv_vsseg5:
  case Intrinsic::riscv_vsseg6:
  case Intrinsic::riscv_vsseg7:
  case Intrinsic::riscv_vsseg8: {
    // Intrinsic interface:
    // riscv_vle(merge, ptr, vl)
    // riscv_vle_mask(merge, ptr, mask, vl, policy)
    // riscv_vse(val, ptr, vl)
    // riscv_vse_mask(val, ptr, mask, vl, policy)
    // riscv_vlseg#(merge, ptr, vl, sew)
    // riscv_vlseg#_mask(merge, ptr, mask, vl, policy, sew)
    // riscv_vsseg#(val, ptr, vl, sew)
    // riscv_vsseg#_mask(val, ptr, mask, vl, sew)
    bool IsWrite = Inst->getType()->isVoidTy();
    Type *Ty = IsWrite ? Inst->getArgOperand(0)->getType() : Inst->getType();
    // The results of segment loads are TargetExtType.
    if (auto *TarExtTy = dyn_cast<TargetExtType>(Ty)) {
      unsigned SEW =
          1 << cast<ConstantInt>(Inst->getArgOperand(Inst->arg_size() - 1))
                   ->getZExtValue();
      Ty = TarExtTy->getTypeParameter(0U);
      Ty = ScalableVectorType::get(
          IntegerType::get(C, SEW),
          cast<ScalableVectorType>(Ty)->getMinNumElements() * 8 / SEW);
    }
    const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
    unsigned VLIndex = RVVIInfo->VLOperand;
    unsigned PtrOperandNo = VLIndex - 1 - HasMask;
    MaybeAlign Alignment =
        Inst->getArgOperand(PtrOperandNo)->getPointerAlignment(DL);
    Type *MaskType = Ty->getWithNewType(Type::getInt1Ty(C));
    Value *Mask = ConstantInt::getTrue(MaskType);
    if (HasMask)
      Mask = Inst->getArgOperand(VLIndex - 1);
    Value *EVL = Inst->getArgOperand(VLIndex);
    unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
    // RVV uses contiguous elements as a segment.
    if (SegNum > 1) {
      unsigned ElemSize = Ty->getScalarSizeInBits();
      auto *SegTy = IntegerType::get(C, ElemSize * SegNum);
      Ty = VectorType::get(SegTy, cast<VectorType>(Ty));
    }
    Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
                                          Alignment, Mask, EVL);
    return true;
  }
  case Intrinsic::riscv_vlse_mask:
  case Intrinsic::riscv_vsse_mask:
  case Intrinsic::riscv_vlsseg2_mask:
  case Intrinsic::riscv_vlsseg3_mask:
  case Intrinsic::riscv_vlsseg4_mask:
  case Intrinsic::riscv_vlsseg5_mask:
  case Intrinsic::riscv_vlsseg6_mask:
  case Intrinsic::riscv_vlsseg7_mask:
  case Intrinsic::riscv_vlsseg8_mask:
  case Intrinsic::riscv_vssseg2_mask:
  case Intrinsic::riscv_vssseg3_mask:
  case Intrinsic::riscv_vssseg4_mask:
  case Intrinsic::riscv_vssseg5_mask:
  case Intrinsic::riscv_vssseg6_mask:
  case Intrinsic::riscv_vssseg7_mask:
  case Intrinsic::riscv_vssseg8_mask:
    HasMask = true;
    [[fallthrough]];
  case Intrinsic::riscv_vlse:
  case Intrinsic::riscv_vsse:
  case Intrinsic::riscv_vlsseg2:
  case Intrinsic::riscv_vlsseg3:
  case Intrinsic::riscv_vlsseg4:
  case Intrinsic::riscv_vlsseg5:
  case Intrinsic::riscv_vlsseg6:
  case Intrinsic::riscv_vlsseg7:
  case Intrinsic::riscv_vlsseg8:
  case Intrinsic::riscv_vssseg2:
  case Intrinsic::riscv_vssseg3:
  case Intrinsic::riscv_vssseg4:
  case Intrinsic::riscv_vssseg5:
  case Intrinsic::riscv_vssseg6:
  case Intrinsic::riscv_vssseg7:
  case Intrinsic::riscv_vssseg8: {
    // Intrinsic interface:
    // riscv_vlse(merge, ptr, stride, vl)
    // riscv_vlse_mask(merge, ptr, stride, mask, vl, policy)
    // riscv_vsse(val, ptr, stride, vl)
    // riscv_vsse_mask(val, ptr, stride, mask, vl, policy)
    // riscv_vlsseg#(merge, ptr, offset, vl, sew)
    // riscv_vlsseg#_mask(merge, ptr, offset, mask, vl, policy, sew)
    // riscv_vssseg#(val, ptr, offset, vl, sew)
    // riscv_vssseg#_mask(val, ptr, offset, mask, vl, sew)
    bool IsWrite = Inst->getType()->isVoidTy();
    Type *Ty = IsWrite ? Inst->getArgOperand(0)->getType() : Inst->getType();
    // The results of segment loads are TargetExtType.
    if (auto *TarExtTy = dyn_cast<TargetExtType>(Ty)) {
      unsigned SEW =
          1 << cast<ConstantInt>(Inst->getArgOperand(Inst->arg_size() - 1))
                   ->getZExtValue();
      Ty = TarExtTy->getTypeParameter(0U);
      Ty = ScalableVectorType::get(
          IntegerType::get(C, SEW),
          cast<ScalableVectorType>(Ty)->getMinNumElements() * 8 / SEW);
    }
    const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
    unsigned VLIndex = RVVIInfo->VLOperand;
    unsigned PtrOperandNo = VLIndex - 2 - HasMask;
    MaybeAlign Alignment =
        Inst->getArgOperand(PtrOperandNo)->getPointerAlignment(DL);

    Value *Stride = Inst->getArgOperand(PtrOperandNo + 1);
    // Use the pointer alignment as the element alignment if the stride is a
    // multiple of the pointer alignment. Otherwise, the element alignment
    // should be the greatest common divisor of pointer alignment and stride.
    // For simplicity, just consider unalignment for elements.
    unsigned PointerAlign = Alignment.valueOrOne().value();
    if (!isa<ConstantInt>(Stride) ||
        cast<ConstantInt>(Stride)->getZExtValue() % PointerAlign != 0)
      Alignment = Align(1);

    Type *MaskType = Ty->getWithNewType(Type::getInt1Ty(C));
    Value *Mask = ConstantInt::getTrue(MaskType);
    if (HasMask)
      Mask = Inst->getArgOperand(VLIndex - 1);
    Value *EVL = Inst->getArgOperand(VLIndex);
    unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
    // RVV uses contiguous elements as a segment.
    if (SegNum > 1) {
      unsigned ElemSize = Ty->getScalarSizeInBits();
      auto *SegTy = IntegerType::get(C, ElemSize * SegNum);
      Ty = VectorType::get(SegTy, cast<VectorType>(Ty));
    }
    Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
                                          Alignment, Mask, EVL, Stride);
    return true;
  }
  case Intrinsic::riscv_vloxei_mask:
  case Intrinsic::riscv_vluxei_mask:
  case Intrinsic::riscv_vsoxei_mask:
  case Intrinsic::riscv_vsuxei_mask:
  case Intrinsic::riscv_vloxseg2_mask:
  case Intrinsic::riscv_vloxseg3_mask:
  case Intrinsic::riscv_vloxseg4_mask:
  case Intrinsic::riscv_vloxseg5_mask:
  case Intrinsic::riscv_vloxseg6_mask:
  case Intrinsic::riscv_vloxseg7_mask:
  case Intrinsic::riscv_vloxseg8_mask:
  case Intrinsic::riscv_vluxseg2_mask:
  case Intrinsic::riscv_vluxseg3_mask:
  case Intrinsic::riscv_vluxseg4_mask:
  case Intrinsic::riscv_vluxseg5_mask:
  case Intrinsic::riscv_vluxseg6_mask:
  case Intrinsic::riscv_vluxseg7_mask:
  case Intrinsic::riscv_vluxseg8_mask:
  case Intrinsic::riscv_vsoxseg2_mask:
  case Intrinsic::riscv_vsoxseg3_mask:
  case Intrinsic::riscv_vsoxseg4_mask:
  case Intrinsic::riscv_vsoxseg5_mask:
  case Intrinsic::riscv_vsoxseg6_mask:
  case Intrinsic::riscv_vsoxseg7_mask:
  case Intrinsic::riscv_vsoxseg8_mask:
  case Intrinsic::riscv_vsuxseg2_mask:
  case Intrinsic::riscv_vsuxseg3_mask:
  case Intrinsic::riscv_vsuxseg4_mask:
  case Intrinsic::riscv_vsuxseg5_mask:
  case Intrinsic::riscv_vsuxseg6_mask:
  case Intrinsic::riscv_vsuxseg7_mask:
  case Intrinsic::riscv_vsuxseg8_mask:
    HasMask = true;
    [[fallthrough]];
  case Intrinsic::riscv_vloxei:
  case Intrinsic::riscv_vluxei:
  case Intrinsic::riscv_vsoxei:
  case Intrinsic::riscv_vsuxei:
  case Intrinsic::riscv_vloxseg2:
  case Intrinsic::riscv_vloxseg3:
  case Intrinsic::riscv_vloxseg4:
  case Intrinsic::riscv_vloxseg5:
  case Intrinsic::riscv_vloxseg6:
  case Intrinsic::riscv_vloxseg7:
  case Intrinsic::riscv_vloxseg8:
  case Intrinsic::riscv_vluxseg2:
  case Intrinsic::riscv_vluxseg3:
  case Intrinsic::riscv_vluxseg4:
  case Intrinsic::riscv_vluxseg5:
  case Intrinsic::riscv_vluxseg6:
  case Intrinsic::riscv_vluxseg7:
  case Intrinsic::riscv_vluxseg8:
  case Intrinsic::riscv_vsoxseg2:
  case Intrinsic::riscv_vsoxseg3:
  case Intrinsic::riscv_vsoxseg4:
  case Intrinsic::riscv_vsoxseg5:
  case Intrinsic::riscv_vsoxseg6:
  case Intrinsic::riscv_vsoxseg7:
  case Intrinsic::riscv_vsoxseg8:
  case Intrinsic::riscv_vsuxseg2:
  case Intrinsic::riscv_vsuxseg3:
  case Intrinsic::riscv_vsuxseg4:
  case Intrinsic::riscv_vsuxseg5:
  case Intrinsic::riscv_vsuxseg6:
  case Intrinsic::riscv_vsuxseg7:
  case Intrinsic::riscv_vsuxseg8: {
    // Intrinsic interface (only listed ordered version):
    // riscv_vloxei(merge, ptr, index, vl)
    // riscv_vloxei_mask(merge, ptr, index, mask, vl, policy)
    // riscv_vsoxei(val, ptr, index, vl)
    // riscv_vsoxei_mask(val, ptr, index, mask, vl, policy)
    // riscv_vloxseg#(merge, ptr, index, vl, sew)
    // riscv_vloxseg#_mask(merge, ptr, index, mask, vl, policy, sew)
    // riscv_vsoxseg#(val, ptr, index, vl, sew)
    // riscv_vsoxseg#_mask(val, ptr, index, mask, vl, sew)
    bool IsWrite = Inst->getType()->isVoidTy();
    Type *Ty = IsWrite ? Inst->getArgOperand(0)->getType() : Inst->getType();
    // The results of segment loads are TargetExtType.
    if (auto *TarExtTy = dyn_cast<TargetExtType>(Ty)) {
      unsigned SEW =
          1 << cast<ConstantInt>(Inst->getArgOperand(Inst->arg_size() - 1))
                   ->getZExtValue();
      Ty = TarExtTy->getTypeParameter(0U);
      Ty = ScalableVectorType::get(
          IntegerType::get(C, SEW),
          cast<ScalableVectorType>(Ty)->getMinNumElements() * 8 / SEW);
    }
    const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
    unsigned VLIndex = RVVIInfo->VLOperand;
    unsigned PtrOperandNo = VLIndex - 2 - HasMask;
    Value *Mask;
    if (HasMask) {
      Mask = Inst->getArgOperand(VLIndex - 1);
    } else {
      // Mask cannot be nullptr here: vector GEP produces <vscale x N x ptr>,
      // and casting that to scalar i64 triggers a vector/scalar mismatch
      // assertion in CreatePointerCast. Use an all-true mask so ASan lowers it
      // via extractelement instead.
      Type *MaskType = Ty->getWithNewType(Type::getInt1Ty(C));
      Mask = ConstantInt::getTrue(MaskType);
    }
    Value *EVL = Inst->getArgOperand(VLIndex);
    unsigned SegNum = getSegNum(Inst, PtrOperandNo, IsWrite);
    // RVV uses contiguous elements as a segment.
    if (SegNum > 1) {
      unsigned ElemSize = Ty->getScalarSizeInBits();
      auto *SegTy = IntegerType::get(C, ElemSize * SegNum);
      Ty = VectorType::get(SegTy, cast<VectorType>(Ty));
    }
    Value *OffsetOp = Inst->getArgOperand(PtrOperandNo + 1);
    Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
                                          Align(1), Mask, EVL,
                                          /* Stride */ nullptr, OffsetOp);
    return true;
  }
  }
  return false;
}

unsigned RISCVTTIImpl::getRegUsageForType(Type *Ty) const {
  if (Ty->isVectorTy()) {
    // f16 with only zvfhmin and bf16 will be promoted to f32
    Type *EltTy = cast<VectorType>(Ty)->getElementType();
    if ((EltTy->isHalfTy() && !ST->hasVInstructionsF16()) ||
        EltTy->isBFloatTy())
      Ty = VectorType::get(Type::getFloatTy(Ty->getContext()),
                           cast<VectorType>(Ty));

    TypeSize Size = DL.getTypeSizeInBits(Ty);
    if (Size.isScalable() && ST->hasVInstructions())
      return divideCeil(Size.getKnownMinValue(), RISCV::RVVBitsPerBlock);

    if (ST->useRVVForFixedLengthVectors())
      return divideCeil(Size, ST->getRealMinVLen());
  }

  return BaseT::getRegUsageForType(Ty);
}

unsigned RISCVTTIImpl::getMaximumVF(unsigned ElemWidth, unsigned Opcode) const {
  if (SLPMaxVF.getNumOccurrences())
    return SLPMaxVF;

  // Return how many elements can fit in getRegisterBitwidth.  This is the
  // same routine as used in LoopVectorizer.  We should probably be
  // accounting for whether we actually have instructions with the right
  // lane type, but we don't have enough information to do that without
  // some additional plumbing which hasn't been justified yet.
  TypeSize RegWidth =
    getRegisterBitWidth(TargetTransformInfo::RGK_FixedWidthVector);
  // If no vector registers, or absurd element widths, disable
  // vectorization by returning 1.
  return std::max<unsigned>(1U, RegWidth.getFixedValue() / ElemWidth);
}

unsigned RISCVTTIImpl::getMinTripCountTailFoldingThreshold() const {
  return RVVMinTripCount;
}

bool RISCVTTIImpl::preferAlternateOpcodeVectorization() const {
  return ST->enableUnalignedVectorMem();
}

TTI::AddressingModeKind
RISCVTTIImpl::getPreferredAddressingMode(const Loop *L,
                                         ScalarEvolution *SE) const {
  if (ST->hasVendorXCVmem() && !ST->is64Bit())
    return TTI::AMK_PostIndexed;

  return BasicTTIImplBase::getPreferredAddressingMode(L, SE);
}

bool RISCVTTIImpl::isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
                                 const TargetTransformInfo::LSRCost &C2) const {
  // RISC-V specific here are "instruction number 1st priority".
  // If we need to emit adds inside the loop to add up base registers, then
  // we need at least one extra temporary register.
  unsigned C1NumRegs = C1.NumRegs + (C1.NumBaseAdds != 0);
  unsigned C2NumRegs = C2.NumRegs + (C2.NumBaseAdds != 0);
  return std::tie(C1.Insns, C1NumRegs, C1.AddRecCost,
                  C1.NumIVMuls, C1.NumBaseAdds,
                  C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
         std::tie(C2.Insns, C2NumRegs, C2.AddRecCost,
                  C2.NumIVMuls, C2.NumBaseAdds,
                  C2.ScaleCost, C2.ImmCost, C2.SetupCost);
}

bool RISCVTTIImpl::isLegalMaskedExpandLoad(Type *DataTy,
                                           Align Alignment) const {
  auto *VTy = dyn_cast<VectorType>(DataTy);
  if (!VTy || VTy->isScalableTy())
    return false;

  if (!isLegalMaskedLoadStore(DataTy, Alignment))
    return false;

  // FIXME: If it is an i8 vector and the element count exceeds 256, we should
  // scalarize these types with LMUL >= maximum fixed-length LMUL.
  if (VTy->getElementType()->isIntegerTy(8))
    if (VTy->getElementCount().getFixedValue() > 256)
      return VTy->getPrimitiveSizeInBits() / ST->getRealMinVLen() <
             ST->getMaxLMULForFixedLengthVectors();
  return true;
}

bool RISCVTTIImpl::isLegalMaskedCompressStore(Type *DataTy,
                                              Align Alignment) const {
  auto *VTy = dyn_cast<VectorType>(DataTy);
  if (!VTy || VTy->isScalableTy())
    return false;

  if (!isLegalMaskedLoadStore(DataTy, Alignment))
    return false;
  return true;
}

/// See if \p I should be considered for address type promotion. We check if \p
/// I is a sext with right type and used in memory accesses. If it used in a
/// "complex" getelementptr, we allow it to be promoted without finding other
/// sext instructions that sign extended the same initial value. A getelementptr
/// is considered as "complex" if it has more than 2 operands.
bool RISCVTTIImpl::shouldConsiderAddressTypePromotion(
    const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const {
  bool Considerable = false;
  AllowPromotionWithoutCommonHeader = false;
  if (!isa<SExtInst>(&I))
    return false;
  Type *ConsideredSExtType =
      Type::getInt64Ty(I.getParent()->getParent()->getContext());
  if (I.getType() != ConsideredSExtType)
    return false;
  // See if the sext is the one with the right type and used in at least one
  // GetElementPtrInst.
  for (const User *U : I.users()) {
    if (const GetElementPtrInst *GEPInst = dyn_cast<GetElementPtrInst>(U)) {
      Considerable = true;
      // A getelementptr is considered as "complex" if it has more than 2
      // operands. We will promote a SExt used in such complex GEP as we
      // expect some computation to be merged if they are done on 64 bits.
      if (GEPInst->getNumOperands() > 2) {
        AllowPromotionWithoutCommonHeader = true;
        break;
      }
    }
  }
  return Considerable;
}

bool RISCVTTIImpl::canSplatOperand(unsigned Opcode, int Operand) const {
  switch (Opcode) {
  case Instruction::Add:
  case Instruction::Sub:
  case Instruction::Mul:
  case Instruction::And:
  case Instruction::Or:
  case Instruction::Xor:
  case Instruction::FAdd:
  case Instruction::FSub:
  case Instruction::FMul:
  case Instruction::FDiv:
  case Instruction::ICmp:
  case Instruction::FCmp:
    return true;
  case Instruction::Shl:
  case Instruction::LShr:
  case Instruction::AShr:
  case Instruction::UDiv:
  case Instruction::SDiv:
  case Instruction::URem:
  case Instruction::SRem:
  case Instruction::Select:
    return Operand == 1;
  default:
    return false;
  }
}

bool RISCVTTIImpl::canSplatOperand(Instruction *I, int Operand) const {
  if (!I->getType()->isVectorTy() || !ST->hasVInstructions())
    return false;

  if (canSplatOperand(I->getOpcode(), Operand))
    return true;

  auto *II = dyn_cast<IntrinsicInst>(I);
  if (!II)
    return false;

  switch (II->getIntrinsicID()) {
  case Intrinsic::fma:
  case Intrinsic::vp_fma:
  case Intrinsic::fmuladd:
  case Intrinsic::vp_fmuladd:
    return Operand == 0 || Operand == 1;
  case Intrinsic::vp_shl:
  case Intrinsic::vp_lshr:
  case Intrinsic::vp_ashr:
  case Intrinsic::vp_udiv:
  case Intrinsic::vp_sdiv:
  case Intrinsic::vp_urem:
  case Intrinsic::vp_srem:
  case Intrinsic::ssub_sat:
  case Intrinsic::vp_ssub_sat:
  case Intrinsic::usub_sat:
  case Intrinsic::vp_usub_sat:
  case Intrinsic::vp_select:
    return Operand == 1;
    // These intrinsics are commutative.
  case Intrinsic::vp_add:
  case Intrinsic::vp_mul:
  case Intrinsic::vp_and:
  case Intrinsic::vp_or:
  case Intrinsic::vp_xor:
  case Intrinsic::vp_fadd:
  case Intrinsic::vp_fmul:
  case Intrinsic::vp_icmp:
  case Intrinsic::vp_fcmp:
  case Intrinsic::smin:
  case Intrinsic::vp_smin:
  case Intrinsic::umin:
  case Intrinsic::vp_umin:
  case Intrinsic::smax:
  case Intrinsic::vp_smax:
  case Intrinsic::umax:
  case Intrinsic::vp_umax:
  case Intrinsic::sadd_sat:
  case Intrinsic::vp_sadd_sat:
  case Intrinsic::uadd_sat:
  case Intrinsic::vp_uadd_sat:
    // These intrinsics have 'vr' versions.
  case Intrinsic::vp_sub:
  case Intrinsic::vp_fsub:
  case Intrinsic::vp_fdiv:
    return Operand == 0 || Operand == 1;
  default:
    return false;
  }
}

/// Check if sinking \p I's operands to I's basic block is profitable, because
/// the operands can be folded into a target instruction, e.g.
/// splats of scalars can fold into vector instructions.
bool RISCVTTIImpl::isProfitableToSinkOperands(
    Instruction *I, SmallVectorImpl<Use *> &Ops) const {
  using namespace llvm::PatternMatch;

  if (I->isBitwiseLogicOp()) {
    if (!I->getType()->isVectorTy()) {
      if (ST->hasStdExtZbb() || ST->hasStdExtZbkb()) {
        for (auto &Op : I->operands()) {
          // (and/or/xor X, (not Y)) -> (andn/orn/xnor X, Y)
          if (match(Op.get(), m_Not(m_Value()))) {
            Ops.push_back(&Op);
            return true;
          }
        }
      }
    } else if (I->getOpcode() == Instruction::And && ST->hasStdExtZvkb()) {
      for (auto &Op : I->operands()) {
        // (and X, (not Y)) -> (vandn.vv X, Y)
        if (match(Op.get(), m_Not(m_Value()))) {
          Ops.push_back(&Op);
          return true;
        }
        // (and X, (splat (not Y))) -> (vandn.vx X, Y)
        if (match(Op.get(), m_Shuffle(m_InsertElt(m_Value(), m_Not(m_Value()),
                                                  m_ZeroInt()),
                                      m_Value(), m_ZeroMask()))) {
          Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
          Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
          Ops.push_back(&Not);
          Ops.push_back(&InsertElt);
          Ops.push_back(&Op);
          return true;
        }
      }
    }
  }

  if (!I->getType()->isVectorTy() || !ST->hasVInstructions())
    return false;

  // Don't sink splat operands if the target prefers it. Some targets requires
  // S2V transfer buffers and we can run out of them copying the same value
  // repeatedly.
  // FIXME: It could still be worth doing if it would improve vector register
  // pressure and prevent a vector spill.
  if (!ST->sinkSplatOperands())
    return false;

  for (auto OpIdx : enumerate(I->operands())) {
    if (!canSplatOperand(I, OpIdx.index()))
      continue;

    Instruction *Op = dyn_cast<Instruction>(OpIdx.value().get());
    // Make sure we are not already sinking this operand
    if (!Op || any_of(Ops, [&](Use *U) { return U->get() == Op; }))
      continue;

    // We are looking for a splat that can be sunk.
    if (!match(Op, m_Shuffle(m_InsertElt(m_Value(), m_Value(), m_ZeroInt()),
                             m_Value(), m_ZeroMask())))
      continue;

    // Don't sink i1 splats.
    if (cast<VectorType>(Op->getType())->getElementType()->isIntegerTy(1))
      continue;

    // All uses of the shuffle should be sunk to avoid duplicating it across gpr
    // and vector registers
    for (Use &U : Op->uses()) {
      Instruction *Insn = cast<Instruction>(U.getUser());
      if (!canSplatOperand(Insn, U.getOperandNo()))
        return false;
    }

    // Sink any fpexts since they might be used in a widening fp pattern.
    Use *InsertEltUse = &Op->getOperandUse(0);
    auto *InsertElt = cast<InsertElementInst>(InsertEltUse);
    if (isa<FPExtInst>(InsertElt->getOperand(1)))
      Ops.push_back(&InsertElt->getOperandUse(1));
    Ops.push_back(InsertEltUse);
    Ops.push_back(&OpIdx.value());
  }
  return true;
}

RISCVTTIImpl::TTI::MemCmpExpansionOptions
RISCVTTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
  TTI::MemCmpExpansionOptions Options;
  // TODO: Enable expansion when unaligned access is not supported after we fix
  // issues in ExpandMemcmp.
  if (!ST->enableUnalignedScalarMem())
    return Options;

  if (!ST->hasStdExtZbb() && !ST->hasStdExtZbkb() && !IsZeroCmp)
    return Options;

  Options.AllowOverlappingLoads = true;
  Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
  Options.NumLoadsPerBlock = Options.MaxNumLoads;
  if (ST->is64Bit()) {
    Options.LoadSizes = {8, 4, 2, 1};
    Options.AllowedTailExpansions = {3, 5, 6};
  } else {
    Options.LoadSizes = {4, 2, 1};
    Options.AllowedTailExpansions = {3};
  }

  if (IsZeroCmp && ST->hasVInstructions()) {
    unsigned VLenB = ST->getRealMinVLen() / 8;
    // The minimum size should be `XLen / 8 + 1`, and the maxinum size should be
    // `VLenB * MaxLMUL` so that it fits in a single register group.
    unsigned MinSize = ST->getXLen() / 8 + 1;
    unsigned MaxSize = VLenB * ST->getMaxLMULForFixedLengthVectors();
    for (unsigned Size = MinSize; Size <= MaxSize; Size++)
      Options.LoadSizes.insert(Options.LoadSizes.begin(), Size);
  }
  return Options;
}

bool RISCVTTIImpl::shouldTreatInstructionLikeSelect(
    const Instruction *I) const {
  if (EnableOrLikeSelectOpt) {
    // For the binary operators (e.g. or) we need to be more careful than
    // selects, here we only transform them if they are already at a natural
    // break point in the code - the end of a block with an unconditional
    // terminator.
    if (I->getOpcode() == Instruction::Or &&
        isa<UncondBrInst>(I->getNextNode()))
      return true;

    if (I->getOpcode() == Instruction::Add ||
        I->getOpcode() == Instruction::Sub)
      return true;
  }
  return BaseT::shouldTreatInstructionLikeSelect(I);
}

bool RISCVTTIImpl::shouldCopyAttributeWhenOutliningFrom(
    const Function *Caller, const Attribute &Attr) const {
  // "interrupt" controls the prolog/epilog of interrupt handlers (and includes
  // restrictions on their signatures). We can outline from the bodies of these
  // handlers, but when we do we need to make sure we don't mark the outlined
  // function as an interrupt handler too.
  if (Attr.isStringAttribute() && Attr.getKindAsString() == "interrupt")
    return false;

  return BaseT::shouldCopyAttributeWhenOutliningFrom(Caller, Attr);
}

std::optional<Instruction *>
RISCVTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
  // If all operands of a vmv.v.x are constant, fold a bitcast(vmv.v.x) to scale
  // the vmv.v.x, enabling removal of the bitcast. The transform helps avoid
  // creating redundant masks.
  const DataLayout &DL = IC.getDataLayout();
  if (II.user_empty())
    return {};
  auto *TargetVecTy = dyn_cast<ScalableVectorType>(II.user_back()->getType());
  if (!TargetVecTy)
    return {};
  const APInt *Scalar;
  uint64_t VL;
  if (!match(&II, m_Intrinsic<Intrinsic::riscv_vmv_v_x>(
                      m_Poison(), m_APInt(Scalar), m_ConstantInt(VL))) ||
      !all_of(II.users(), [TargetVecTy](User *U) {
        return U->getType() == TargetVecTy && match(U, m_BitCast(m_Value()));
      }))
    return {};
  auto *SourceVecTy = cast<ScalableVectorType>(II.getType());
  unsigned TargetEltBW = DL.getTypeSizeInBits(TargetVecTy->getElementType());
  unsigned SourceEltBW = DL.getTypeSizeInBits(SourceVecTy->getElementType());
  if (TargetEltBW % SourceEltBW)
    return {};
  unsigned TargetScale = TargetEltBW / SourceEltBW;
  if (VL % TargetScale)
    return {};
  Type *VLTy = II.getOperand(2)->getType();
  ElementCount SourceEC = SourceVecTy->getElementCount();
  unsigned NewEltBW = SourceEltBW * TargetScale;
  if (!SourceEC.isKnownMultipleOf(TargetScale) ||
      !DL.fitsInLegalInteger(NewEltBW))
    return {};
  auto *NewEltTy = IntegerType::get(II.getContext(), NewEltBW);
  if (!TLI->isLegalElementTypeForRVV(TLI->getValueType(DL, NewEltTy)))
    return {};
  ElementCount NewEC = SourceEC.divideCoefficientBy(TargetScale);
  Type *RetTy = VectorType::get(NewEltTy, NewEC);
  assert(SourceVecTy->canLosslesslyBitCastTo(RetTy) &&
         "Lossless bitcast between types expected");
  APInt NewScalar = APInt::getSplat(NewEltBW, *Scalar);
  return IC.replaceInstUsesWith(
      II,
      IC.Builder.CreateBitCast(
          IC.Builder.CreateIntrinsic(
              RetTy, Intrinsic::riscv_vmv_v_x,
              {PoisonValue::get(RetTy), ConstantInt::get(NewEltTy, NewScalar),
               ConstantInt::get(VLTy, VL / TargetScale)}),
          SourceVecTy));
}
