LLVM: lib/Transforms/Scalar/ScalarizeMaskedMemIntrin.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
38#include
39#include
40
41using namespace llvm;
42
43#define DEBUG_TYPE "scalarize-masked-mem-intrin"
44
45namespace {
46
47class ScalarizeMaskedMemIntrinLegacyPass : public FunctionPass {
48public:
49 static char ID;
50
51 explicit ScalarizeMaskedMemIntrinLegacyPass() : FunctionPass(ID) {
54 }
55
57
59 return "Scalarize Masked Memory Intrinsics";
60 }
61
65 }
66};
67
68}
69
75 const DataLayout &DL, bool HasBranchDivergence,
77
78char ScalarizeMaskedMemIntrinLegacyPass::ID = 0;
79
81 "Scalarize unsupported masked memory intrinsics", false,
82 false)
88
90 return new ScalarizeMaskedMemIntrinLegacyPass();
91}
92
94 Constant *C = dyn_cast(Mask);
95 if ()
96 return false;
97
98 unsigned NumElts = cast(Mask->getType())->getNumElements();
99 for (unsigned i = 0; i != NumElts; ++i) {
100 Constant *CElt = C->getAggregateElement(i);
101 if (!CElt || !isa(CElt))
102 return false;
103 }
104
105 return true;
106}
107
109 unsigned Idx) {
110 return DL.isBigEndian() ? VectorWidth - 1 - Idx : Idx;
111}
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
147 bool &ModifiedDT) {
152
153 const Align AlignVal = cast(Alignment)->getAlignValue();
155
156 Type *EltTy = VecType->getElementType();
157
161
164
165
166 if (isa(Mask) && cast(Mask)->isAllOnesValue()) {
172 return;
173 }
174
175
176 const Align AdjustedAlignVal =
178 unsigned VectorWidth = cast(VecType)->getNumElements();
179
180
181 Value *VResult = Src0;
182
184 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
185 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())
186 continue;
190 }
193 return;
194 }
195
196
197
198
201 Mask->getName() + ".first");
204 nullptr, DTU);
205
207 CondBlock->setName("cond.load");
210 CI->getName() + ".cond.load");
211 Load->copyMetadata(*CI);
212
215 PHINode *Phi = Builder.CreatePHI(VecType, 2);
216 Phi->addIncoming(Load, CondBlock);
217 Phi->addIncoming(Src0, IfBlock);
218 Phi->takeName(CI);
219
222 ModifiedDT = true;
223 return;
224 }
225
226
227
228 Value *SclrMask = nullptr;
229 if (VectorWidth != 1 && !HasBranchDivergence) {
230 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
231 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
232 }
233
234 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
235
236
237
238
239
240
241
242
243
244 Value *Predicate;
245 if (SclrMask != nullptr) {
249 Builder.getIntN(VectorWidth, 0));
250 } else {
252 }
253
254
255
256
257
258
259
262 nullptr, DTU);
263
265 CondBlock->setName("cond.load");
266
271
272
274 NewIfBlock->setName("else");
276 IfBlock = NewIfBlock;
277
278
280 PHINode *Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");
281 Phi->addIncoming(NewVResult, CondBlock);
282 Phi->addIncoming(VResult, PrevIfBlock);
283 VResult = Phi;
284 }
285
288
289 ModifiedDT = true;
290}
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
320 bool &ModifiedDT) {
325
326 const Align AlignVal = cast(Alignment)->getAlignValue();
327 auto *VecType = cast(Src->getType());
328
329 Type *EltTy = VecType->getElementType();
330
335
336
337 if (isa(Mask) && cast(Mask)->isAllOnesValue()) {
339 Store->takeName(CI);
340 Store->copyMetadata(*CI);
342 return;
343 }
344
345
346 const Align AdjustedAlignVal =
348 unsigned VectorWidth = cast(VecType)->getNumElements();
349
351 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
352 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())
353 continue;
357 }
359 return;
360 }
361
362
363
364
367 Mask->getName() + ".first");
370 nullptr, DTU);
372 CondBlock->setName("cond.store");
374
376 Store->takeName(CI);
377 Store->copyMetadata(*CI);
378
380 ModifiedDT = true;
381 return;
382 }
383
384
385
386
387 Value *SclrMask = nullptr;
388 if (VectorWidth != 1 && !HasBranchDivergence) {
389 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
390 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
391 }
392
393 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
394
395
396
397
398
399
400
401
402
403 Value *Predicate;
404 if (SclrMask != nullptr) {
408 Builder.getIntN(VectorWidth, 0));
409 } else {
411 }
412
413
414
415
416
417
418
421 nullptr, DTU);
422
424 CondBlock->setName("cond.store");
425
430
431
433 NewIfBlock->setName("else");
434
436 }
438
439 ModifiedDT = true;
440}
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
472 bool HasBranchDivergence, CallInst *CI,
478
479 auto *VecType = cast(CI->getType());
480 Type *EltTy = VecType->getElementType();
481
486 MaybeAlign AlignVal = cast(Alignment)->getMaybeAlignValue();
487
489
490
491 Value *VResult = Src0;
492 unsigned VectorWidth = VecType->getNumElements();
493
494
496 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
497 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())
498 continue;
502 VResult =
504 }
507 return;
508 }
509
510
511
512
513 Value *SclrMask = nullptr;
514 if (VectorWidth != 1 && !HasBranchDivergence) {
515 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
516 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
517 }
518
519 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
520
521
522
523
524
525
526
527
528
529
530 Value *Predicate;
531 if (SclrMask != nullptr) {
535 Builder.getIntN(VectorWidth, 0));
536 } else {
538 }
539
540
541
542
543
544
545
548 nullptr, DTU);
549
551 CondBlock->setName("cond.load");
552
557 Value *NewVResult =
559
560
562 NewIfBlock->setName("else");
564 IfBlock = NewIfBlock;
565
566
568 PHINode *Phi = Builder.CreatePHI(VecType, 2, "res.phi.else");
569 Phi->addIncoming(NewVResult, CondBlock);
570 Phi->addIncoming(VResult, PrevIfBlock);
571 VResult = Phi;
572 }
573
576
577 ModifiedDT = true;
578}
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
607 bool HasBranchDivergence, CallInst *CI,
613
614 auto *SrcFVTy = cast(Src->getType());
615
617 isa(Ptrs->getType()) &&
618 isa(cast(Ptrs->getType())->getElementType()) &&
619 "Vector of pointers is expected in masked scatter intrinsic");
620
625
626 MaybeAlign AlignVal = cast(Alignment)->getMaybeAlignValue();
627 unsigned VectorWidth = SrcFVTy->getNumElements();
628
629
631 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
632 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())
633 continue;
638 }
640 return;
641 }
642
643
644
645 Value *SclrMask = nullptr;
646 if (VectorWidth != 1 && !HasBranchDivergence) {
647 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
648 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
649 }
650
651 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
652
653
654
655
656
657
658
659
660
661 Value *Predicate;
662 if (SclrMask != nullptr) {
666 Builder.getIntN(VectorWidth, 0));
667 } else {
669 }
670
671
672
673
674
675
676
679 nullptr, DTU);
680
682 CondBlock->setName("cond.store");
683
688
689
691 NewIfBlock->setName("else");
692
694 }
696
697 ModifiedDT = true;
698}
699
701 bool HasBranchDivergence, CallInst *CI,
707
708 auto *VecType = cast(CI->getType());
709
710 Type *EltTy = VecType->getElementType();
711
715
718
719 unsigned VectorWidth = VecType->getNumElements();
720
721
722 Value *VResult = PassThru;
723
724
725 const Align AdjustedAlignment =
727
728
729
730
732 unsigned MemIndex = 0;
735 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
736 Value *InsertElt;
737 if (cast(Mask)->getAggregateElement(Idx)->isNullValue()) {
739 ShuffleMask[Idx] = Idx + VectorWidth;
740 } else {
743 InsertElt = Builder.CreateAlignedLoad(EltTy, NewPtr, AdjustedAlignment,
746 ++MemIndex;
747 }
750 }
754 return;
755 }
756
757
758
759
760 Value *SclrMask = nullptr;
761 if (VectorWidth != 1 && !HasBranchDivergence) {
762 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
763 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
764 }
765
766 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
767
768
769
770
771
772
773
774
775
776
777 Value *Predicate;
778 if (SclrMask != nullptr) {
782 Builder.getIntN(VectorWidth, 0));
783 } else {
785 }
786
787
788
789
790
791
792
795 nullptr, DTU);
796
798 CondBlock->setName("cond.load");
799
803
804
806 if ((Idx + 1) != VectorWidth)
808
809
811 NewIfBlock->setName("else");
813 IfBlock = NewIfBlock;
814
815
817 PHINode *ResultPhi = Builder.CreatePHI(VecType, 2, "res.phi.else");
818 ResultPhi->addIncoming(NewVResult, CondBlock);
819 ResultPhi->addIncoming(VResult, PrevIfBlock);
820 VResult = ResultPhi;
821
822
823 if ((Idx + 1) != VectorWidth) {
827 Ptr = PtrPhi;
828 }
829 }
830
833
834 ModifiedDT = true;
835}
836
838 bool HasBranchDivergence, CallInst *CI,
840 bool &ModifiedDT) {
845
846 auto *VecType = cast(Src->getType());
847
851
854
855 Type *EltTy = VecType->getElementType();
856
857
858 const Align AdjustedAlignment =
860
861 unsigned VectorWidth = VecType->getNumElements();
862
863
865 unsigned MemIndex = 0;
866 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
867 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())
868 continue;
873 ++MemIndex;
874 }
876 return;
877 }
878
879
880
881
882 Value *SclrMask = nullptr;
883 if (VectorWidth != 1 && !HasBranchDivergence) {
884 Type *SclrMaskTy = Builder.getIntNTy(VectorWidth);
885 SclrMask = Builder.CreateBitCast(Mask, SclrMaskTy, "scalar_mask");
886 }
887
888 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
889
890
891
892
893
894
895
896
897 Value *Predicate;
898 if (SclrMask != nullptr) {
902 Builder.getIntN(VectorWidth, 0));
903 } else {
905 }
906
907
908
909
910
911
912
915 nullptr, DTU);
916
918 CondBlock->setName("cond.store");
919
923
924
926 if ((Idx + 1) != VectorWidth)
928
929
931 NewIfBlock->setName("else");
933 IfBlock = NewIfBlock;
934
936
937
938 if ((Idx + 1) != VectorWidth) {
942 Ptr = PtrPhi;
943 }
944 }
946
947 ModifiedDT = true;
948}
949
952 bool &ModifiedDT) {
953
954
959
960 auto *AddrType = cast(Ptrs->getType());
962
966
968
969
970 unsigned VectorWidth = AddrType->getNumElements();
971
972
974 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
975 if (cast(Mask)->getAggregateElement(Idx)->isNullValue())
976 continue;
981 }
983 return;
984 }
985
986 for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) {
987 Value *Predicate =
989
992 nullptr, DTU);
993
995 CondBlock->setName("cond.histogram.update");
996
1002
1003
1005 NewIfBlock->setName("else");
1007 }
1008
1010 ModifiedDT = true;
1011}
1012
1015 std::optional DTU;
1016 if (DT)
1017 DTU.emplace(DT, DomTreeUpdater::UpdateStrategy::Lazy);
1018
1019 bool EverMadeChange = false;
1020 bool MadeChange = true;
1021 auto &DL = F.getDataLayout();
1023 while (MadeChange) {
1024 MadeChange = false;
1026 bool ModifiedDTOnIteration = false;
1028 HasBranchDivergence, DTU ? &*DTU : nullptr);
1029
1030
1031 if (ModifiedDTOnIteration)
1032 break;
1033 }
1034
1035 EverMadeChange |= MadeChange;
1036 }
1037 return EverMadeChange;
1038}
1039
1040bool ScalarizeMaskedMemIntrinLegacyPass::runOnFunction(Function &F) {
1041 auto &TTI = getAnalysis().getTTI(F);
1043 if (auto *DTWP = getAnalysisIfAvailable())
1044 DT = &DTWP->getDomTree();
1046}
1047
1057 return PA;
1058}
1059
1063 bool MadeChange = false;
1064
1066 while (CurInstIterator != BB.end()) {
1067 if (CallInst *CI = dyn_cast(&*CurInstIterator++))
1068 MadeChange |=
1070 if (ModifiedDT)
1071 return true;
1072 }
1073
1074 return MadeChange;
1075}
1076
1079 const DataLayout &DL, bool HasBranchDivergence,
1082 if (II) {
1083
1084 if (isa(II->getType()) ||
1086 [](Value *V) { return isa(V->getType()); }))
1087 return false;
1088 switch (II->getIntrinsicID()) {
1089 default:
1090 break;
1091 case Intrinsic::experimental_vector_histogram_add:
1094 return false;
1096 return true;
1097 case Intrinsic::masked_load:
1098
1101 cast(CI->getArgOperand(1))->getAlignValue()))
1102 return false;
1104 return true;
1105 case Intrinsic::masked_store:
1108 cast(CI->getArgOperand(2))->getAlignValue()))
1109 return false;
1111 return true;
1112 case Intrinsic::masked_gather: {
1114 cast(CI->getArgOperand(1))->getMaybeAlignValue();
1116 Align Alignment = DL.getValueOrABITypeAlignment(MA,
1120 return false;
1122 return true;
1123 }
1124 case Intrinsic::masked_scatter: {
1126 cast(CI->getArgOperand(2))->getMaybeAlignValue();
1128 Align Alignment = DL.getValueOrABITypeAlignment(MA,
1132 Alignment))
1133 return false;
1135 return true;
1136 }
1137 case Intrinsic::masked_expandload:
1141 return false;
1143 return true;
1144 case Intrinsic::masked_compressstore:
1148 return false;
1150 ModifiedDT);
1151 return true;
1152 }
1153 }
1154
1155 return false;
1156}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static Error unsupported(const char *Str, const Triple &T)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static bool runImpl(Function &F, const TargetLowering &TLI)
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void scalarizeMaskedExpandLoad(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)
static void scalarizeMaskedVectorHistogram(const DataLayout &DL, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)
static bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
static void scalarizeMaskedScatter(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)
static unsigned adjustForEndian(const DataLayout &DL, unsigned VectorWidth, unsigned Idx)
static bool optimizeCallInst(CallInst *CI, bool &ModifiedDT, const TargetTransformInfo &TTI, const DataLayout &DL, bool HasBranchDivergence, DomTreeUpdater *DTU)
static void scalarizeMaskedStore(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)
static void scalarizeMaskedCompressStore(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)
static void scalarizeMaskedGather(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)
static bool runImpl(Function &F, const TargetTransformInfo &TTI, DominatorTree *DT)
static bool isConstantIntVector(Value *Mask)
Scalarize unsupported masked memory intrinsics
static void scalarizeMaskedLoad(const DataLayout &DL, bool HasBranchDivergence, CallInst *CI, DomTreeUpdater *DTU, bool &ModifiedDT)
This pass exposes codegen information to IR-level passes.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
MaybeAlign getAlignment() const
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Value * getArgOperand(unsigned i) const
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Value * CreateConstInBoundsGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended or truncated from a 64-bit value.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
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.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserve()
Mark an analysis as preserved.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
Analysis pass providing the TargetTransformInfo.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
bool isLegalMaskedScatter(Type *DataType, Align Alignment) const
Return true if the target supports masked scatter.
bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const
Return true if the target supports masked expand load.
bool hasBranchDivergence(const Function *F=nullptr) const
Return true if branch divergence exists.
bool isLegalMaskedGather(Type *DataType, Align Alignment) const
Return true if the target supports masked gather.
bool forceScalarizeMaskedGather(VectorType *Type, Align Alignment) const
Return true if the target forces scalarizing of llvm.masked.gather intrinsics.
bool isLegalMaskedCompressStore(Type *DataType, Align Alignment) const
Return true if the target supports masked compress store.
bool isLegalMaskedStore(Type *DataType, Align Alignment) const
Return true if the target supports masked store.
bool isLegalMaskedVectorHistogram(Type *AddrType, Type *DataType) const
bool forceScalarizeMaskedScatter(VectorType *Type, Align Alignment) const
Return true if the target forces scalarizing of llvm.masked.scatter intrinsics.
bool isLegalMaskedLoad(Type *DataType, Align Alignment) const
Return true if the target supports masked load.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isVoidTy() const
Return true if this is 'void'.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void setName(const Twine &Name)
Change the name of the value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
const ParentTy * getParent() const
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionPass * createScalarizeMaskedMemIntrinLegacyPass()
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
void initializeScalarizeMaskedMemIntrinLegacyPassPass(PassRegistry &)
constexpr int PoisonMaskElem
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
This struct is a compact representation of a valid (non-zero power of two) alignment.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)