35#include "llvm/IR/IntrinsicsARM.h"
47#define DEBUG_TYPE "arm-mve-gather-scatter-lowering"
51 cl::desc(
"Enable the generation of masked gathers and scatters"));
65 StringRef getPassName()
const override {
66 return "MVE gather/scatter lowering";
69 void getAnalysisUsage(AnalysisUsage &AU)
const override {
73 FunctionPass::getAnalysisUsage(AU);
77 LoopInfo *LI =
nullptr;
81 bool isLegalTypeAndAlignment(
unsigned NumElements,
unsigned ElemSize,
84 void lookThroughBitcast(
Value *&Ptr);
89 FixedVectorType *Ty,
Type *MemoryTy,
97 int computeScale(
unsigned GEPElemSize,
unsigned MemoryElemSize);
100 std::optional<int64_t> getIfConst(
const Value *V);
104 std::pair<Value *, int64_t> getVarAndConst(
Value *Inst,
int TypeScale);
141 Value *Ptr,
unsigned TypeScale,
145 bool optimiseAddress(
Value *
Address, BasicBlock *BB, LoopInfo *LI);
147 Value *foldGEP(GetElementPtrInst *
GEP,
Value *&Offsets,
unsigned &Scale,
150 bool optimiseOffsets(
Value *Offsets, BasicBlock *BB, LoopInfo *LI);
152 void pushOutAdd(PHINode *&Phi,
Value *OffsSecondOperand,
unsigned StartIndex);
154 void pushOutMulShl(
unsigned Opc, PHINode *&Phi,
Value *IncrementPerRound,
155 Value *OffsSecondOperand,
unsigned LoopIncrement,
161char MVEGatherScatterLowering::ID = 0;
164 "MVE gather/scattering lowering pass",
false,
false)
167 return new MVEGatherScatterLowering();
170bool MVEGatherScatterLowering::isLegalTypeAndAlignment(
unsigned NumElements,
173 if (((NumElements == 4 &&
174 (ElemSize == 32 || ElemSize == 16 || ElemSize == 8)) ||
175 (NumElements == 8 && (ElemSize == 16 || ElemSize == 8)) ||
176 (NumElements == 16 && ElemSize == 8)) &&
177 Alignment >= ElemSize / 8)
179 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: instruction does not have "
180 <<
"valid alignment or vector type \n");
195 unsigned TargetElemSize = 128 / TargetElemCount;
198 ->getScalarSizeInBits();
199 if (OffsetElemSize != TargetElemSize || OffsetElemSize != 32) {
203 int64_t TargetElemMaxSize = (1ULL << TargetElemSize);
204 auto CheckValueSize = [TargetElemMaxSize](
Value *OffsetElem) {
209 if (SExtValue >= TargetElemMaxSize || SExtValue < 0)
214 for (
unsigned i = 0; i < TargetElemCount; i++) {
219 if (!CheckValueSize(ConstOff))
226Value *MVEGatherScatterLowering::decomposePtr(
Value *Ptr,
Value *&Offsets,
227 int &Scale, FixedVectorType *Ty,
233 computeScale(
DL->getTypeAllocSizeInBits(
GEP->getSourceElementType()),
235 return Scale == -1 ? nullptr :
V;
253Value *MVEGatherScatterLowering::decomposeGEP(
Value *&Offsets,
255 GetElementPtrInst *
GEP,
258 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: no getelementpointer "
262 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: getelementpointer found."
263 <<
" Looking at intrinsic for base + vector of offsets\n");
264 Value *GEPPtr =
GEP->getPointerOperand();
270 if (
GEP->getNumOperands() != 2) {
271 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: getelementptr with too many"
272 <<
" operands. Expanding.\n");
276 unsigned OffsetsElemCount =
290 ->getScalarSizeInBits() != 32)
296 if (Ty !=
Offsets->getType()) {
305 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: found correct offsets\n");
309void MVEGatherScatterLowering::lookThroughBitcast(
Value *&Ptr) {
314 if (BCTy->getNumElements() == BCSrcTy->getNumElements()) {
317 Ptr = BitCast->getOperand(0);
322int MVEGatherScatterLowering::computeScale(
unsigned GEPElemSize,
323 unsigned MemoryElemSize) {
326 if (GEPElemSize == 32 && MemoryElemSize == 32)
328 else if (GEPElemSize == 16 && MemoryElemSize == 16)
330 else if (GEPElemSize == 8)
332 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: incorrect scale. Can't "
333 <<
"create intrinsic\n");
337std::optional<int64_t> MVEGatherScatterLowering::getIfConst(
const Value *V) {
339 if (
C &&
C->getSplatValue())
340 return std::optional<int64_t>{
C->getUniqueInteger().getSExtValue()};
342 return std::optional<int64_t>{};
345 if (
I->getOpcode() == Instruction::Add ||
I->getOpcode() == Instruction::Or ||
346 I->getOpcode() == Instruction::Mul ||
347 I->getOpcode() == Instruction::Shl) {
348 std::optional<int64_t> Op0 = getIfConst(
I->getOperand(0));
349 std::optional<int64_t> Op1 = getIfConst(
I->getOperand(1));
351 return std::optional<int64_t>{};
352 if (
I->getOpcode() == Instruction::Add)
353 return std::optional<int64_t>{*Op0 + *Op1};
354 if (
I->getOpcode() == Instruction::Mul)
355 return std::optional<int64_t>{*Op0 * *Op1};
356 if (
I->getOpcode() == Instruction::Shl)
357 return std::optional<int64_t>{*Op0 << *Op1};
358 if (
I->getOpcode() == Instruction::Or)
359 return std::optional<int64_t>{*Op0 | *Op1};
361 return std::optional<int64_t>{};
367 return I->getOpcode() == Instruction::Or &&
371std::pair<Value *, int64_t>
372MVEGatherScatterLowering::getVarAndConst(
Value *Inst,
int TypeScale) {
373 std::pair<Value *, int64_t> ReturnFalse =
374 std::pair<Value *, int64_t>(
nullptr, 0);
378 if (
Add ==
nullptr ||
383 std::optional<int64_t>
Const;
385 if ((Const = getIfConst(
Add->getOperand(0))))
386 Summand =
Add->getOperand(1);
387 else if ((Const = getIfConst(
Add->getOperand(1))))
388 Summand =
Add->getOperand(0);
393 int64_t Immediate = *
Const << TypeScale;
394 if (Immediate > 512 || Immediate < -512 || Immediate % 4 != 0)
397 return std::pair<Value *, int64_t>(Summand, Immediate);
400Instruction *MVEGatherScatterLowering::lowerGather(IntrinsicInst *
I) {
401 using namespace PatternMatch;
402 LLVM_DEBUG(
dbgs() <<
"masked gathers: checking transform preconditions\n"
409 Value *Ptr =
I->getArgOperand(0);
410 Align Alignment =
I->getParamAlign(0).valueOrOne();
412 Value *PassThru =
I->getArgOperand(2);
417 lookThroughBitcast(Ptr);
428 Load = tryCreateMaskedGatherOffset(
I, Ptr, Root, Builder);
430 Load = tryCreateMaskedGatherBase(
I, Ptr, Builder);
435 LLVM_DEBUG(
dbgs() <<
"masked gathers: found non-trivial passthru - "
436 <<
"creating select\n");
446 I->eraseFromParent();
448 LLVM_DEBUG(
dbgs() <<
"masked gathers: successfully built masked gather\n"
453Instruction *MVEGatherScatterLowering::tryCreateMaskedGatherBase(
455 using namespace PatternMatch;
457 LLVM_DEBUG(
dbgs() <<
"masked gathers: loading from vector of pointers\n");
464 Intrinsic::arm_mve_vldr_gather_base, {Ty, Ptr->
getType()},
467 Intrinsic::arm_mve_vldr_gather_base_predicated,
472Instruction *MVEGatherScatterLowering::tryCreateMaskedGatherBaseWB(
474 using namespace PatternMatch;
476 LLVM_DEBUG(
dbgs() <<
"masked gathers: loading from vector of pointers with "
484 Intrinsic::arm_mve_vldr_gather_base_wb, {Ty, Ptr->
getType()},
487 Intrinsic::arm_mve_vldr_gather_base_wb_predicated,
492Instruction *MVEGatherScatterLowering::tryCreateMaskedGatherOffset(
494 using namespace PatternMatch;
496 Type *MemoryTy =
I->getType();
497 Type *ResultTy = MemoryTy;
503 bool TruncResult =
false;
505 if (
I->hasOneUse()) {
511 User->getType()->getPrimitiveSizeInBits() == 128) {
515 ResultTy =
User->getType();
518 User->getType()->getPrimitiveSizeInBits() == 128) {
520 << *ResultTy <<
"\n");
522 ResultTy =
User->getType();
533 LLVM_DEBUG(
dbgs() <<
"masked gathers: Small input type, truncing to: "
534 << *ResultTy <<
"\n");
539 LLVM_DEBUG(
dbgs() <<
"masked gathers: Extend needed but not provided "
540 "from the correct type. Expanding\n");
557 Intrinsic::arm_mve_vldr_gather_offset_predicated,
563 Intrinsic::arm_mve_vldr_gather_offset,
569 Load = TruncInst::Create(Instruction::Trunc, Load, MemoryTy);
575Instruction *MVEGatherScatterLowering::lowerScatter(IntrinsicInst *
I) {
576 using namespace PatternMatch;
577 LLVM_DEBUG(
dbgs() <<
"masked scatters: checking transform preconditions\n"
583 Value *Input =
I->getArgOperand(0);
584 Value *Ptr =
I->getArgOperand(1);
585 Align Alignment =
I->getParamAlign(1).valueOrOne();
592 lookThroughBitcast(Ptr);
601 Store = tryCreateMaskedScatterOffset(
I, Ptr, Builder);
603 Store = tryCreateMaskedScatterBase(
I, Ptr, Builder);
607 LLVM_DEBUG(
dbgs() <<
"masked scatters: successfully built masked scatter\n"
609 I->eraseFromParent();
613Instruction *MVEGatherScatterLowering::tryCreateMaskedScatterBase(
615 using namespace PatternMatch;
616 Value *Input =
I->getArgOperand(0);
625 LLVM_DEBUG(
dbgs() <<
"masked scatters: storing to a vector of pointers\n");
628 Intrinsic::arm_mve_vstr_scatter_base,
632 Intrinsic::arm_mve_vstr_scatter_base_predicated,
637Instruction *MVEGatherScatterLowering::tryCreateMaskedScatterBaseWB(
639 using namespace PatternMatch;
640 Value *Input =
I->getArgOperand(0);
642 LLVM_DEBUG(
dbgs() <<
"masked scatters: storing to a vector of pointers "
643 <<
"with writeback\n");
650 Intrinsic::arm_mve_vstr_scatter_base_wb,
654 Intrinsic::arm_mve_vstr_scatter_base_wb_predicated,
659Instruction *MVEGatherScatterLowering::tryCreateMaskedScatterOffset(
661 using namespace PatternMatch;
662 Value *Input =
I->getArgOperand(0);
665 Type *MemoryTy = InputTy;
667 LLVM_DEBUG(
dbgs() <<
"masked scatters: getelementpointer found. Storing"
668 <<
" to base + vector of offsets\n");
672 Value *PreTrunc = Trunc->getOperand(0);
676 InputTy = PreTruncTy;
679 bool ExtendInput =
false;
689 LLVM_DEBUG(
dbgs() <<
"masked scatters: Small input type, will extend:\n"
693 LLVM_DEBUG(
dbgs() <<
"masked scatters: cannot create scatters for "
694 "non-standard input types. Expanding.\n");
709 Intrinsic::arm_mve_vstr_scatter_offset_predicated,
716 Intrinsic::arm_mve_vstr_scatter_offset,
723Instruction *MVEGatherScatterLowering::tryCreateIncrementingGatScat(
726 if (
I->getIntrinsicID() == Intrinsic::masked_gather)
746 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: trying to build incrementing "
747 "wb gather/scatter\n");
752 computeScale(
DL->getTypeAllocSizeInBits(
GEP->getSourceElementType()),
753 DL->getTypeSizeInBits(
GEP->getType()) /
758 if (
GEP->hasOneUse()) {
762 if (
auto *Load = tryCreateIncrementingWBGatScat(
I, BasePtr, Offsets,
767 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: trying to build incrementing "
768 "non-wb gather/scatter\n");
770 std::pair<Value *, int64_t>
Add = getVarAndConst(Offsets, TypeScale);
771 if (
Add.first ==
nullptr)
774 int64_t Immediate =
Add.second;
778 Instruction::Shl, OffsetsIncoming,
781 "ScaledIndex",
I->getIterator());
784 Instruction::Add, ScaledOffsets,
790 "StartIndex",
I->getIterator());
792 if (
I->getIntrinsicID() == Intrinsic::masked_gather)
793 return tryCreateMaskedGatherBase(
I, OffsetsIncoming, Builder, Immediate);
795 return tryCreateMaskedScatterBase(
I, OffsetsIncoming, Builder, Immediate);
798Instruction *MVEGatherScatterLowering::tryCreateIncrementingWBGatScat(
799 IntrinsicInst *
I,
Value *BasePtr,
Value *Offsets,
unsigned TypeScale,
807 if (Phi ==
nullptr ||
Phi->getNumIncomingValues() != 2 ||
808 Phi->getParent() !=
L->getHeader() || !
Phi->hasNUses(2))
815 unsigned IncrementIndex =
816 Phi->getIncomingBlock(0) ==
L->getLoopLatch() ? 0 : 1;
818 Offsets =
Phi->getIncomingValue(IncrementIndex);
820 std::pair<Value *, int64_t>
Add = getVarAndConst(Offsets, TypeScale);
821 if (
Add.first ==
nullptr)
824 int64_t Immediate =
Add.second;
825 if (OffsetsIncoming != Phi)
836 Instruction::Shl,
Phi->getIncomingValue(1 - IncrementIndex),
839 Phi->getIncomingBlock(1 - IncrementIndex)->back().getIterator());
842 Instruction::Add, ScaledOffsets,
849 Phi->getIncomingBlock(1 - IncrementIndex)->back().getIterator());
852 Instruction::Sub, OffsetsIncoming,
854 "PreIncrementStartIndex",
855 Phi->getIncomingBlock(1 - IncrementIndex)->back().getIterator());
856 Phi->setIncomingValue(1 - IncrementIndex, OffsetsIncoming);
862 if (
I->getIntrinsicID() == Intrinsic::masked_gather) {
864 Value *
Load = tryCreateMaskedGatherBaseWB(
I, Phi, Builder, Immediate);
869 Builder.
Insert(EndResult);
870 Builder.
Insert(NewInduction);
873 EndResult = NewInduction =
874 tryCreateMaskedScatterBaseWB(
I, Phi, Builder, Immediate);
879 Phi->setIncomingValue(IncrementIndex, NewInduction);
884void MVEGatherScatterLowering::pushOutAdd(PHINode *&Phi,
885 Value *OffsSecondOperand,
886 unsigned StartIndex) {
887 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: optimising add instruction\n");
888 assert(
Phi->getNumIncomingValues() == 2);
889 BasicBlock *NewIndexBlock =
Phi->getIncomingBlock(StartIndex);
893 Instruction::Add,
Phi->getIncomingValue(StartIndex), OffsSecondOperand,
894 "PushedOutAdd", InsertionPoint);
895 unsigned IncrementIndex = StartIndex == 0 ? 1 : 0;
898 Value *IncrementIndexValue =
Phi->getIncomingValue(IncrementIndex);
899 BasicBlock *IncrementIndexBlock =
Phi->getIncomingBlock(IncrementIndex);
900 Phi->setIncomingValue(0, NewIndex);
901 Phi->setIncomingBlock(0, NewIndexBlock);
902 Phi->setIncomingValue(1, IncrementIndexValue);
903 Phi->setIncomingBlock(1, IncrementIndexBlock);
906void MVEGatherScatterLowering::pushOutMulShl(
unsigned Opcode, PHINode *&Phi,
907 Value *IncrementPerRound,
908 Value *OffsSecondOperand,
909 unsigned LoopIncrement,
911 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: optimising mul instruction\n");
912 assert(
Phi->getNumIncomingValues() == 2);
917 Phi->getIncomingBlock(LoopIncrement == 1 ? 0 : 1);
923 Phi->getIncomingValue(LoopIncrement == 1 ? 0 : 1),
924 OffsSecondOperand,
"PushedOutMul", InsertionPoint);
928 OffsSecondOperand,
"Product", InsertionPoint);
929 BasicBlock *NewIncrementBlock =
Phi->getIncomingBlock(LoopIncrement);
932 NewIncrInsertPt = std::prev(NewIncrInsertPt);
936 Instruction::Add, Phi, Product,
"IncrementPushedOutMul", NewIncrInsertPt);
938 Phi->setIncomingValue(0, StartIndex);
939 Phi->setIncomingBlock(0, StartIndexBlock);
940 Phi->setIncomingValue(1, NewIncrement);
941 Phi->setIncomingBlock(1, NewIncrementBlock);
947 if (
I->use_empty()) {
951 for (
User *U :
I->users()) {
959 if ((OpCode == Instruction::Add || OpCode == Instruction::Mul ||
960 OpCode == Instruction::Shl ||
971bool MVEGatherScatterLowering::optimiseOffsets(
Value *Offsets, BasicBlock *BB,
973 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: trying to optimize: "
974 << *Offsets <<
"\n");
1024 if (
Phi->getParent() !=
L->getHeader())
1028 BinaryOperator *IncInstruction;
1031 IncInstruction->
getOpcode() != Instruction::Add)
1034 int IncrementingBlock =
Phi->getIncomingValue(0) == IncInstruction ? 0 : 1;
1039 if (IncrementPerRound->
getType() != OffsSecondOperand->
getType() ||
1040 !
L->isLoopInvariant(OffsSecondOperand))
1054 if (
Phi->hasNUses(2)) {
1062 IncrementPerRound,
"LoopIncrement", IncInstruction->
getIterator());
1063 Phi->setIncomingValue(IncrementingBlock, IncInstruction);
1070 NewPhi->
addIncoming(
Phi->getIncomingValue(IncrementingBlock == 1 ? 0 : 1),
1071 Phi->getIncomingBlock(IncrementingBlock == 1 ? 0 : 1));
1074 IncrementPerRound,
"LoopIncrement", IncInstruction->
getIterator());
1076 Phi->getIncomingBlock(IncrementingBlock));
1077 IncrementingBlock = 1;
1085 case Instruction::Add:
1086 case Instruction::Or:
1087 pushOutAdd(NewPhi, OffsSecondOperand, IncrementingBlock == 1 ? 0 : 1);
1089 case Instruction::Mul:
1090 case Instruction::Shl:
1091 pushOutMulShl(Offs->
getOpcode(), NewPhi, IncrementPerRound,
1092 OffsSecondOperand, IncrementingBlock, Builder);
1097 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: simplified loop variable "
1122 if (
N < (
unsigned)(1 << (TargetElemSize - 1))) {
1123 NonVectorVal = Builder.CreateVectorSplat(
1136 if (XElType && !YElType) {
1137 FixSummands(XElType,
Y);
1139 }
else if (YElType && !XElType) {
1140 FixSummands(YElType,
X);
1143 assert(XElType && YElType &&
"Unknown vector types");
1145 if (XElType != YElType) {
1146 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: incompatible gep offsets\n");
1155 if (!ConstX || !ConstY)
1163 if (!ConstXEl || !ConstYEl ||
1166 (
unsigned)(1 << (TargetElemSize - 1)))
1171 Value *XScale = Builder.CreateVectorSplat(
1174 Value *YScale = Builder.CreateVectorSplat(
1177 Value *
Add = Builder.CreateAdd(Builder.CreateMul(
X, XScale),
1178 Builder.CreateMul(
Y, YScale));
1186Value *MVEGatherScatterLowering::foldGEP(GetElementPtrInst *
GEP,
1187 Value *&Offsets,
unsigned &Scale,
1189 Value *GEPPtr =
GEP->getPointerOperand();
1191 Scale =
DL->getTypeAllocSize(
GEP->getSourceElementType());
1198 Value *BaseBasePtr = foldGEP(BaseGEP, Offsets, Scale, Builder);
1202 Offsets, Scale,
GEP->getOperand(1),
1203 DL->getTypeAllocSize(
GEP->getSourceElementType()), Builder);
1204 if (Offsets ==
nullptr)
1212bool MVEGatherScatterLowering::optimiseAddress(
Value *
Address, BasicBlock *BB,
1230 assert(Scale == 1 &&
"Expected to fold GEP to a scale of 1");
1236 "gep.merged",
GEP->getIterator());
1238 <<
"\n new : " << *NewAddress <<
"\n");
1239 GEP->replaceAllUsesWith(
1245 Changed |= optimiseOffsets(
GEP->getOperand(1),
GEP->getParent(), LI);
1249bool MVEGatherScatterLowering::runOnFunction(Function &
F) {
1252 auto &TPC = getAnalysis<TargetPassConfig>();
1253 auto &TM = TPC.getTM<TargetMachine>();
1254 auto *
ST = &TM.getSubtarget<ARMSubtarget>(
F);
1255 if (!
ST->hasMVEIntegerOps())
1257 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1258 DL = &
F.getDataLayout();
1264 for (BasicBlock &BB :
F) {
1267 for (Instruction &
I : BB) {
1269 if (
II &&
II->getIntrinsicID() == Intrinsic::masked_gather &&
1272 Changed |= optimiseAddress(
II->getArgOperand(0),
II->getParent(), LI);
1273 }
else if (
II &&
II->getIntrinsicID() == Intrinsic::masked_scatter &&
1276 Changed |= optimiseAddress(
II->getArgOperand(1),
II->getParent(), LI);
1280 for (IntrinsicInst *
I : Gathers) {
1290 for (IntrinsicInst *
I : Scatters) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static Decomposition decomposeGEP(GEPOperator &GEP, SmallVectorImpl< ConditionTy > &Preconditions, bool IsSigned, const DataLayout &DL)
static bool runOnFunction(Function &F, bool PostInlining)
static bool isAddLikeOr(Instruction *I, const DataLayout &DL)
static bool hasAllGatScatUsers(Instruction *I, const DataLayout &DL)
static bool checkOffsetSize(Value *Offsets, unsigned TargetElemCount)
static Value * CheckAndCreateOffsetAdd(Value *X, unsigned ScaleX, Value *Y, unsigned ScaleY, IRBuilder<> &Builder)
cl::opt< bool > EnableMaskedGatherScatters("enable-arm-maskedgatscat", cl::Hidden, cl::init(true), cl::desc("Enable the generation of masked gathers and scatters"))
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static unsigned getNumElements(Type *Ty)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
const Instruction & back() const
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
Type * getDestTy() const
Return the destination type, as a convenience.
This is the shared class of boolean and integer constants.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
A parsed version of the target data layout string in and methods for querying it.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
void push_back(const T &Elt)
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Type * getElementType() const
const ParentTy * getParent() const
self_iterator getIterator()
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool haveNoCommonBitsSet(const WithCache< const Value * > &LHSCache, const WithCache< const Value * > &RHSCache, const SimplifyQuery &SQ)
Return true if LHS and RHS have no common bits set.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Pass * createMVEGatherScatterLoweringPass()
LLVM_ABI bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr)
Scan the specified basic block and try to simplify any instructions in it and recursively delete dead...
LLVM_ABI bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
bool isGatherScatter(IntrinsicInst *IntInst)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void initializeMVEGatherScatterLoweringPass(PassRegistry &)
@ Increment
Incrementally increasing token ID.
This struct is a compact representation of a valid (non-zero power of two) alignment.