diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -327,6 +327,8 @@ void printVType(unsigned VType, raw_ostream &OS); +static constexpr unsigned RVVBitsPerBlock = 64; + } // namespace RISCVVType } // namespace llvm diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -277,6 +277,13 @@ Value *NewVal, Value *Mask, AtomicOrdering Ord) const override; + /// Returns true if the target allows unaligned memory accesses of the + /// specified type. + bool allowsMisalignedMemoryAccesses( + EVT VT, unsigned AddrSpace = 0, unsigned Align = 1, + MachineMemOperand::Flags Flags = MachineMemOperand::MONone, + bool *Fast = nullptr) const override; + private: void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo, const SmallVectorImpl &Ins, diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -4559,6 +4559,25 @@ return false; } +bool RISCVTargetLowering::allowsMisalignedMemoryAccesses( + EVT VT, unsigned AddrSpace, unsigned Align, MachineMemOperand::Flags Flags, + bool *Fast) const { + if (!VT.isScalableVector()) + return false; + + EVT ElemVT = VT.getVectorElementType(); + if ((ElemVT == MVT::i8 && Align == 1) || + (ElemVT == MVT::i16 && Align == 2) || + (ElemVT == MVT::i32 && Align == 4) || + (ElemVT == MVT::i64 && Align == 8) || + (ElemVT == MVT::f16 && Align == 2) || + (ElemVT == MVT::f32 && Align == 4) || + (ElemVT == MVT::f64 && Align == 8)) + return true; + + return false; +} + #define GET_REGISTER_MATCHER #include "RISCVGenAsmMatcher.inc" diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h --- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h +++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h @@ -47,6 +47,19 @@ Instruction *Inst = nullptr); int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind); + + bool supportsScalableVectors() const { return ST->hasStdExtV(); } + unsigned getRegisterBitWidth(bool Vector) const { + if (Vector) { + if (ST->hasStdExtV()) + return RISCVVType::RVVBitsPerBlock; + return 0; + } + if (ST->is64Bit()) + return 64; + return 32; + } + Optional getMaxVScale() const; }; } // end namespace llvm diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp @@ -15,6 +15,11 @@ #define DEBUG_TYPE "riscvtti" +static cl::opt MaxVectorLen( + "riscv-vector-bits-max", + cl::desc("The assumed maximum vector bits."), + cl::init(0), cl::Hidden); + int RISCVTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) { assert(Ty->isIntegerTy() && @@ -94,3 +99,9 @@ // Prevent hoisting in unknown cases. return TTI::TCC_Free; } + +Optional RISCVTTIImpl::getMaxVScale() const { + if (ST->hasStdExtV()) + return MaxVectorLen / RISCVVType::RVVBitsPerBlock; + return BaseT::getMaxVScale(); +} diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/scalable-vf-hint.ll b/llvm/test/Transforms/LoopVectorize/RISCV/scalable-vf-hint.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/RISCV/scalable-vf-hint.ll @@ -0,0 +1,44 @@ +; RUN: opt -mtriple=riscv64 -mattr=+m,+experimental-v -loop-vectorize \ +; RUN: -riscv-vector-bits-max=512 -S < %s 2>&1 \ +; RUN: | llc -mattr=+m,+experimental-v | FileCheck %s + +; void test(int *a, int *b, int N) { +; #pragma clang loop vectorize(enable) vectorize_width(2, scalable) +; for (int i=0; i