LLVM: lib/Analysis/LazyValueInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
43#include
44using namespace llvm;
46
47#define DEBUG_TYPE "lazy-value-info"
48
49
50
52
56 "Lazy Value Information Analysis", false, true)
60 "Lazy Value Information Analysis", false, true)
61
63 "lvi-per-pred-ranges", cl::Hidden, cl::init(false),
64 cl::desc("Enable tracking of ranges for a value in a block for"
65 "each block predecessor (default = false)"));
66
67namespace llvm {
71}
72
74
75
76
77
81
82 return true;
84
85 return true;
86 return false;
87}
88
89
90
91
92
93namespace {
94
95 class LazyValueInfoCache;
96 struct LVIValueHandle final : public CallbackVH {
97 LazyValueInfoCache *Parent;
98
99 LVIValueHandle(Value *V, LazyValueInfoCache *P = nullptr)
100 : CallbackVH(V), Parent(P) { }
101
102 void deleted() override;
103 void allUsesReplacedWith(Value *V) override {
104 deleted();
105 }
106 };
107}
108
109namespace {
111using BBLatticeElementMap =
113using PredecessorValueLatticeMap =
115
116
117
118class LazyValueInfoCache {
119
120
121
122
123 struct BlockCacheEntry {
124 SmallDenseMap<AssertingVH, ValueLatticeElement, 4> LatticeElements;
125 SmallDenseSet<AssertingVH, 4> OverDefined;
126
127
128 std::optional NonNullPointers;
129
130
131
132 std::optional PredecessorLatticeElements;
133 };
134
135
136 DenseMap<PoisoningVH, std::unique_ptr>
137 BlockCache;
138
139 DenseSet<LVIValueHandle, DenseMapInfo<Value *>> ValueHandles;
140
141 const BlockCacheEntry *getBlockEntry(BasicBlock *BB) const {
142 auto It = BlockCache.find_as(BB);
143 if (It == BlockCache.end())
144 return nullptr;
145 return It->second.get();
146 }
147
148 BlockCacheEntry *getOrCreateBlockEntry(BasicBlock *BB) {
149 auto It = BlockCache.find_as(BB);
150 if (It == BlockCache.end()) {
151 std::unique_ptr BCE =
152 std::make_unique();
154 BCE->PredecessorLatticeElements =
155 std::make_optional();
156 It = BlockCache.insert({BB, std::move(BCE)}).first;
157 }
158
159 return It->second.get();
160 }
161
162 void addValueHandle(Value *Val) {
163 auto HandleIt = ValueHandles.find_as(Val);
164 if (HandleIt == ValueHandles.end())
165 ValueHandles.insert({Val, this});
166 }
167
168public:
169 void insertResult(Value *Val, BasicBlock *BB,
170 const ValueLatticeElement &Result) {
171 BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
172
173
174
175 if (Result.isOverdefined())
176 Entry->OverDefined.insert(Val);
177 else
178 Entry->LatticeElements.insert({Val, Result});
179
180 addValueHandle(Val);
181 }
182
183 void insertPredecessorResults(Value *Val, BasicBlock *BB,
184 BBLatticeElementMap &PredLatticeElements) {
185 BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
186
187 Entry->PredecessorLatticeElements->insert({Val, PredLatticeElements});
188
189 addValueHandle(Val);
190 }
191
192 std::optional
193 getCachedPredecessorInfo(Value *V, BasicBlock *BB) const {
194 const BlockCacheEntry *Entry = getBlockEntry(BB);
195 if (!Entry)
196 return std::nullopt;
197
198 auto LatticeIt = Entry->PredecessorLatticeElements->find_as(V);
199 if (LatticeIt == Entry->PredecessorLatticeElements->end())
200 return std::nullopt;
201
202 return LatticeIt->second;
203 }
204
205 std::optional getCachedValueInfo(Value *V,
206 BasicBlock *BB) const {
207 const BlockCacheEntry *Entry = getBlockEntry(BB);
208 if (!Entry)
209 return std::nullopt;
210
211 if (Entry->OverDefined.count(V))
213
214 auto LatticeIt = Entry->LatticeElements.find_as(V);
215 if (LatticeIt == Entry->LatticeElements.end())
216 return std::nullopt;
217
218 return LatticeIt->second;
219 }
220
221 bool
222 isNonNullAtEndOfBlock(Value *V, BasicBlock *BB,
223 function_ref<NonNullPointerSet(BasicBlock *)> InitFn) {
224 BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
225 if (->NonNullPointers) {
226 Entry->NonNullPointers = InitFn(BB);
227 for (Value *V : *Entry->NonNullPointers)
228 addValueHandle(V);
229 }
230
231 return Entry->NonNullPointers->count(V);
232 }
233
234
235 void clear() {
236 BlockCache.clear();
237 ValueHandles.clear();
238 }
239
240
241 void eraseValue(Value *V);
242
243
244
245 void eraseBlock(BasicBlock *BB);
246
247
248
249
250 void threadEdgeImpl(BasicBlock *OldSucc, BasicBlock *NewSucc);
251};
252}
253
254void LazyValueInfoCache::eraseValue(Value *V) {
255 for (auto &Pair : BlockCache) {
256 Pair.second->LatticeElements.erase(V);
257 Pair.second->OverDefined.erase(V);
258 if (Pair.second->NonNullPointers)
259 Pair.second->NonNullPointers->erase(V);
261 Pair.second->PredecessorLatticeElements->erase(V);
262 }
263
264 auto HandleIt = ValueHandles.find_as(V);
265 if (HandleIt != ValueHandles.end())
266 ValueHandles.erase(HandleIt);
267}
268
269void LVIValueHandle::deleted() {
270
271
272 Parent->eraseValue(*this);
273}
274
275void LazyValueInfoCache::eraseBlock(BasicBlock *BB) {
276
278 for (auto &Pair : BlockCache)
279 Pair.second->PredecessorLatticeElements->clear();
280 BlockCache.erase(BB);
281}
282
283void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
285
286
287
288
289
290
291
292
293
294
295 std::vector<BasicBlock*> worklist;
296 worklist.push_back(OldSucc);
297
298 const BlockCacheEntry *Entry = getBlockEntry(OldSucc);
299 if (!Entry || Entry->OverDefined.empty())
300 return;
302 Entry->OverDefined.end());
303
304
305
306
307
308 while (!worklist.empty()) {
309 BasicBlock *ToUpdate = worklist.back();
310 worklist.pop_back();
311
312
313 if (ToUpdate == NewSucc) continue;
314
315
316 auto OI = BlockCache.find_as(ToUpdate);
317 if (OI == BlockCache.end() || OI->second->OverDefined.empty())
318 continue;
319 auto &ValueSet = OI->second->OverDefined;
320
321 bool changed = false;
322 for (Value *V : ValsToClear) {
323 if (!ValueSet.erase(V))
324 continue;
325
326
327
328 changed = true;
329 }
330
331 if (!changed) continue;
332
334 }
335}
336
337namespace llvm {
338namespace {
339
340
342 LazyValueInfoImpl *LVIImpl;
343
344
345 DominatorTree &DT;
346
347public:
348 LazyValueInfoAnnotatedWriter(LazyValueInfoImpl *L, DominatorTree &DTree)
349 : LVIImpl(L), DT(DTree) {}
350
351 void emitBasicBlockStartAnnot(const BasicBlock *BB,
352 formatted_raw_ostream &OS) override;
353
354 void emitInstructionAnnot(const Instruction *I,
355 formatted_raw_ostream &OS) override;
356};
357}
358
360
361
362 LazyValueInfoCache TheCache;
363
364
365
366
368
369
371
372
373
374 bool pushBlockValue(const std::pair<BasicBlock *, Value *> &BV) {
375 if (!BlockValueSet.insert(BV).second)
376 return false;
377
378 LLVM_DEBUG(dbgs() << "PUSH: " << *BV.second << " in "
379 << BV.first->getName() << "\n");
380 BlockValueStack.push_back(BV);
381 return true;
382 }
383
384 AssumptionCache *AC;
385 const DataLayout &DL;
386
387
388
390
391 std::optional getBlockValue(Value *Val, BasicBlock *BB,
393 std::optional getEdgeValue(Value *V, BasicBlock *F,
396
397
398
399
401 std::optional solveBlockValueImpl(Value *Val,
403 std::optional solveBlockValueNonLocal(Value *Val,
405 std::optional solveBlockValuePHINode(PHINode *PN,
407 std::optional solveBlockValueSelect(SelectInst *S,
409 std::optional getRangeFor(Value *V, Instruction *CxtI,
411 std::optional solveBlockValueBinaryOpImpl(
414 OpFn);
415 std::optional
417 std::optional solveBlockValueCast(CastInst *CI,
419 std::optional
421 std::optional solveBlockValueIntrinsic(IntrinsicInst *II,
423 std::optional
425 std::optional
428 void intersectAssumeOrGuardBlockValueConstantRange(Value *Val,
431
432 void solve();
433
434
435
436
437
438 std::optional
441 bool UseBlockValue);
442
443 std::optional
444 getValueFromICmpCondition(Value *Val, ICmpInst *ICI, bool isTrueDest,
445 bool UseBlockValue);
447 bool IsTrueDest);
448
449 std::optional
450 getValueFromCondition(Value *Val, Value *Cond, bool IsTrueDest,
451 bool UseBlockValue, unsigned Depth = 0);
452
453 std::optional getEdgeValueLocal(Value *Val,
456 bool UseBlockValue);
457
458public:
459
460
461
464
465
466
467
468
470
471
472
476
478
479
481 TheCache.clear();
482 }
483
484
486 LazyValueInfoAnnotatedWriter Writer(this, DTree);
487 F.print(OS, &Writer);
488 }
489
490
491
493
494
495
497 TheCache.eraseBlock(BB);
498 }
499
500
501
503
506 : AC(AC), DL(DL), GuardDecl(GuardDecl) {}
507};
508}
509
510void LazyValueInfoImpl::solve() {
512 BlockValueStack;
513
514 unsigned processedCount = 0;
515 while (!BlockValueStack.empty()) {
516 processedCount++;
517
518
519
520
521
522
523
524
527 dbgs() << "Giving up on stack because we are getting too deep\n");
528
529 while (!StartingStack.empty()) {
530 std::pair<BasicBlock *, Value *> &e = StartingStack.back();
531 TheCache.insertResult(e.second, e.first,
534 }
535 BlockValueSet.clear();
536 BlockValueStack.clear();
537 return;
538 }
539 std::pair<BasicBlock *, Value *> e = BlockValueStack.back();
540 assert(BlockValueSet.count(e) && "Stack value should be in BlockValueSet!");
541 unsigned StackSize = BlockValueStack.size();
542 (void) StackSize;
543
544 if (solveBlockValue(e.second, e.first)) {
545
546 assert(BlockValueStack.size() == StackSize &&
547 BlockValueStack.back() == e && "Nothing should have been pushed!");
548#ifndef NDEBUG
549 std::optional BBLV =
550 TheCache.getCachedValueInfo(e.second, e.first);
551 assert(BBLV && "Result should be in cache!");
553 dbgs() << "POP " << *e.second << " in " << e.first->getName() << " = "
554 << *BBLV << "\n");
555#endif
556
557 BlockValueStack.pop_back();
558 BlockValueSet.erase(e);
559 } else {
560
561 assert(BlockValueStack.size() == StackSize + 1 &&
562 "Exactly one element should have been pushed!");
563 }
564 }
565}
566
567std::optional
568LazyValueInfoImpl::getBlockValue(Value *Val, BasicBlock *BB,
570
573
574 if (std::optional OptLatticeVal =
575 TheCache.getCachedValueInfo(Val, BB)) {
576 intersectAssumeOrGuardBlockValueConstantRange(Val, *OptLatticeVal, CxtI);
577 return OptLatticeVal;
578 }
579
580
581 if (!pushBlockValue({ BB, Val }))
583
584
585 return std::nullopt;
586}
587
590 default:
591 break;
592 case Instruction::Call:
593 case Instruction::Invoke:
596 [[fallthrough]];
597 case Instruction::Load:
602 }
603 break;
604 };
605
607}
608
609bool LazyValueInfoImpl::solveBlockValue(Value *Val, BasicBlock *BB) {
611 assert(!TheCache.getCachedValueInfo(Val, BB) &&
612 "Value should not be in cache");
613
614
615
616 std::optional Res = solveBlockValueImpl(Val, BB);
617 if (!Res)
618
619 return false;
620
621 TheCache.insertResult(Val, BB, *Res);
622 return true;
623}
624
625std::optional
626LazyValueInfoImpl::solveBlockValueImpl(Value *Val, BasicBlock *BB) {
628 if (!BBI || BBI->getParent() != BB)
629 return solveBlockValueNonLocal(Val, BB);
630
632 return solveBlockValuePHINode(PN, BB);
633
635 return solveBlockValueSelect(SI, BB);
636
637
638
639
640
641
642
643
644
645
649
652 return solveBlockValueCast(CI, BB);
653
655 return solveBlockValueBinaryOp(BO, BB);
656
658 return solveBlockValueInsertElement(IEI, BB);
659
661 return solveBlockValueExtractValue(EVI, BB);
662
664 return solveBlockValueIntrinsic(II, BB);
665 }
666
668 << "' - unknown inst def found.\n");
670}
671
673 bool IsDereferenced = true) {
674
678}
679
687 if (MI->isVolatile()) return;
688
689
691 if (!Len || Len->isZero()) return;
692
697 for (auto &U : CB->args()) {
698 if (U->getType()->isPointerTy() &&
699 CB->paramHasNonNullAttr(CB->getArgOperandNo(&U),
700 false))
702 }
703 }
704}
705
706bool LazyValueInfoImpl::isNonNullAtEndOfBlock(Value *Val, BasicBlock *BB) {
709 return false;
710
712 return TheCache.isNonNullAtEndOfBlock(Val, BB, [](BasicBlock *BB) {
713 NonNullPointerSet NonNullPointers;
714 for (Instruction &I : *BB)
716 return NonNullPointers;
717 });
718}
719
720std::optional
721LazyValueInfoImpl::solveBlockValueNonLocal(Value *Val, BasicBlock *BB) {
722 ValueLatticeElement Result;
723
724
730 }
731
732
733
734
735
736
737
738
739
740
741 std::optional PredLatticeElements;
743 PredLatticeElements = std::make_optional();
745
746 if (Pred == BB)
747 continue;
748 std::optional EdgeResult = getEdgeValue(Val, Pred, BB);
749 if (!EdgeResult)
750
751 return std::nullopt;
752
753 Result.mergeIn(*EdgeResult);
754
755
756
757 if (Result.isOverdefined()) {
759 << "' - overdefined because of pred '"
760 << Pred->getName() << "' (non local).\n");
762 }
764 PredLatticeElements->insert({Pred, *EdgeResult});
765 }
766
768 TheCache.insertPredecessorResults(Val, BB, *PredLatticeElements);
769
770
773}
774
775std::optional
776LazyValueInfoImpl::solveBlockValuePHINode(PHINode *PN, BasicBlock *BB) {
777 ValueLatticeElement Result;
778
779
780
781
782 std::optional PredLatticeElements;
784 PredLatticeElements = std::make_optional();
788
789
790
791 std::optional EdgeResult =
792 getEdgeValue(PhiVal, PhiBB, BB, PN);
793 if (!EdgeResult)
794
795 return std::nullopt;
796
797 Result.mergeIn(*EdgeResult);
798
799
800
801 if (Result.isOverdefined()) {
803 << "' - overdefined because of pred (local).\n");
804
806 }
807
809 PredLatticeElements->insert({PhiBB, *EdgeResult});
810 }
811
813 TheCache.insertPredecessorResults(PN, BB, *PredLatticeElements);
814
815
816 assert(.isOverdefined() && "Possible PHI in entry block?");
818}
819
820
821
822void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
825 if (!BBI)
826 return;
827
829 for (auto &AssumeVH : AC->assumptionsFor(Val)) {
830 if (!AssumeVH)
831 continue;
832
833
834
835
838 continue;
839
840 BBLV = BBLV.intersect(*getValueFromCondition(Val, I->getArgOperand(0),
841 true,
842 false));
843 }
844
845
846 if (GuardDecl && !GuardDecl->use_empty() &&
848 for (Instruction &I :
852 BBLV = BBLV.intersect(*getValueFromCondition(Val, Cond,
853 true,
854 false));
855 }
856 }
857
859
860
863 isNonNullAtEndOfBlock(Val, BB))
865 }
866}
867
868std::optional
870
871 std::optional OptTrueVal =
872 getBlockValue(SI->getTrueValue(), BB, SI);
873 if (!OptTrueVal)
874 return std::nullopt;
875 ValueLatticeElement &TrueVal = *OptTrueVal;
876
877 std::optional OptFalseVal =
878 getBlockValue(SI->getFalseValue(), BB, SI);
879 if (!OptFalseVal)
880 return std::nullopt;
881 ValueLatticeElement &FalseVal = *OptFalseVal;
882
883 if (TrueVal.isConstantRange() || FalseVal.isConstantRange()) {
884 const ConstantRange &TrueCR = TrueVal.asConstantRange(SI->getType());
885 const ConstantRange &FalseCR = FalseVal.asConstantRange(SI->getType());
889
890
892 ((LHS == SI->getTrueValue() && RHS == SI->getFalseValue()) ||
893 (RHS == SI->getTrueValue() && LHS == SI->getFalseValue()))) {
894 ConstantRange ResultCR = [&]() {
895 switch (SPR.Flavor) {
896 default:
898 case SPF_SMIN:
899 return TrueCR.smin(FalseCR);
900 case SPF_UMIN:
901 return TrueCR.umin(FalseCR);
902 case SPF_SMAX:
903 return TrueCR.smax(FalseCR);
904 case SPF_UMAX:
905 return TrueCR.umax(FalseCR);
906 };
907 }();
909 ResultCR, TrueVal.isConstantRangeIncludingUndef() ||
910 FalseVal.isConstantRangeIncludingUndef());
911 }
912
914 if (LHS == SI->getTrueValue())
916 TrueCR.abs(), TrueVal.isConstantRangeIncludingUndef());
917 if (LHS == SI->getFalseValue())
919 FalseCR.abs(), FalseVal.isConstantRangeIncludingUndef());
920 }
921
924 if (LHS == SI->getTrueValue())
926 Zero.sub(TrueCR.abs()), FalseVal.isConstantRangeIncludingUndef());
927 if (LHS == SI->getFalseValue())
929 Zero.sub(FalseCR.abs()), FalseVal.isConstantRangeIncludingUndef());
930 }
931 }
932
933
934
935
937
938
941 TrueVal.intersect(*getValueFromCondition(SI->getTrueValue(), Cond,
942 true,
943 false));
945 FalseVal.intersect(*getValueFromCondition(SI->getFalseValue(), Cond,
946 false,
947 false));
948 }
949
950 TrueVal.mergeIn(FalseVal);
952}
953
954std::optional
956 std::optional OptVal = getBlockValue(V, BB, CxtI);
957 if (!OptVal)
958 return std::nullopt;
959 return OptVal->asConstantRange(V->getType());
960}
961
962std::optional
963LazyValueInfoImpl::solveBlockValueCast(CastInst *CI, BasicBlock *BB) {
964
965
966
968 case Instruction::Trunc:
969 case Instruction::SExt:
970 case Instruction::ZExt:
971 break;
972 default:
973
975 << "' - overdefined (unknown cast).\n");
977 }
978
979
980
981
982 std::optional LHSRes = getRangeFor(CI->getOperand(0), CI, BB);
983 if (!LHSRes)
984
985 return std::nullopt;
986 const ConstantRange &LHSRange = *LHSRes;
987
989
990
991
992
993 ConstantRange Res = ConstantRange::getEmpty(ResultBitWidth);
995 Res = LHSRange.truncate(ResultBitWidth, Trunc->getNoWrapKind());
996 else
998
1000}
1001
1002std::optional
1003LazyValueInfoImpl::solveBlockValueBinaryOpImpl(
1006 OpFn) {
1009
1010 auto ThreadBinOpOverSelect =
1011 [&](Value *X, const ConstantRange &CRX, SelectInst *Y,
1012 bool XIsLHS) -> std::optional {
1014
1016 if (!TrueC)
1017 return std::nullopt;
1019 if (!FalseC)
1020 return std::nullopt;
1022 return std::nullopt;
1023
1024 ConstantRange TrueX =
1025 CRX.intersectWith(getValueFromCondition(X, Cond, true,
1026 false)
1027 ->asConstantRange(X->getType()));
1028 ConstantRange FalseX =
1029 CRX.intersectWith(getValueFromCondition(X, Cond, false,
1030 false)
1031 ->asConstantRange(X->getType()));
1034
1035 if (XIsLHS)
1037 OpFn(TrueX, TrueY).unionWith(OpFn(FalseX, FalseY)));
1039 OpFn(TrueY, TrueX).unionWith(OpFn(FalseY, FalseX)));
1040 };
1041
1042
1043
1044
1045
1046 std::optional LHSRes = getRangeFor(LHS, I, BB);
1047 if (!LHSRes)
1048 return std::nullopt;
1049
1050
1052 if (auto Res = ThreadBinOpOverSelect(LHS, *LHSRes, SI, true))
1053 return *Res;
1054 }
1055
1056 std::optional RHSRes = getRangeFor(RHS, I, BB);
1057 if (!RHSRes)
1058 return std::nullopt;
1059
1060
1062 if (auto Res = ThreadBinOpOverSelect(RHS, *RHSRes, SI, false))
1063 return *Res;
1064 }
1065
1066 const ConstantRange &LHSRange = *LHSRes;
1067 const ConstantRange &RHSRange = *RHSRes;
1068
1069 std::optional MergedResult =
1071
1073 return MergedResult;
1074
1075 std::optional PredLHS =
1076 TheCache.getCachedPredecessorInfo(LHS, BB);
1077 if (!PredLHS)
1078 return MergedResult;
1079 std::optional PredRHS =
1080 TheCache.getCachedPredecessorInfo(RHS, BB);
1081 if (!PredRHS)
1082 return MergedResult;
1083
1084 const BBLatticeElementMap &LHSPredMap = *PredLHS;
1085 const BBLatticeElementMap &RHSPredMap = *PredRHS;
1086
1087 BBLatticeElementMap PredLatticeElements;
1088 ValueLatticeElement OverallPredResult;
1090 auto LHSIt = LHSPredMap.find_as(Pred);
1091 if (LHSIt == LHSPredMap.end())
1092 return MergedResult;
1093 const ValueLatticeElement &LHSFromPred = LHSIt->second;
1094 std::optional LHSFromPredRes =
1096 if (!LHSFromPredRes)
1097 return MergedResult;
1098
1099 auto RHSIt = RHSPredMap.find_as(Pred);
1100 if (RHSIt == RHSPredMap.end())
1101 return MergedResult;
1102 const ValueLatticeElement &RHSFromPred = RHSIt->second;
1103 std::optional RHSFromPredRes =
1105 if (!RHSFromPredRes)
1106 return MergedResult;
1107
1108 const ConstantRange &LHSFromPredRange = *LHSFromPredRes;
1109 const ConstantRange &RHSFromPredRange = *RHSFromPredRes;
1110 std::optional PredResult =
1112 if (!PredResult)
1113 return MergedResult;
1114 if (PredResult->isOverdefined()) {
1116 dbgs() << " pred BB '" << Pred->getName() << "' for BB '"
1118 << "' overdefined. Discarding all predecessor intervals.\n");
1119 return MergedResult;
1120 }
1121 PredLatticeElements.insert({Pred, *PredResult});
1122 OverallPredResult.mergeIn(*PredResult);
1123 }
1124
1125
1126
1127
1128 TheCache.insertPredecessorResults(I, BB, PredLatticeElements);
1129
1130 LLVM_DEBUG(dbgs() << " Using predecessor intervals, evaluated " << *I
1131 << " to: " << OverallPredResult << ".\n");
1132
1133 if (!MergedResult)
1134 return OverallPredResult;
1135
1136 LLVM_DEBUG(dbgs() << " Intersecting intervals for " << *I << ": "
1137 << OverallPredResult << " and " << MergedResult << ".\n");
1138 return MergedResult->intersect(OverallPredResult);
1139}
1140
1141std::optional
1144 "all operands to binary operators are sized");
1146 unsigned NoWrapKind = OBO->getNoWrapKind();
1147 return solveBlockValueBinaryOpImpl(
1148 BO, BB,
1149 [BO, NoWrapKind](const ConstantRange &CR1, const ConstantRange &CR2) {
1151 });
1152 }
1153
1154 return solveBlockValueBinaryOpImpl(
1155 BO, BB, [BO](const ConstantRange &CR1, const ConstantRange &CR2) {
1157 });
1158}
1159
1160std::optional
1161LazyValueInfoImpl::solveBlockValueOverflowIntrinsic(WithOverflowInst *WO,
1163 return solveBlockValueBinaryOpImpl(
1164 WO, BB, [WO](const ConstantRange &CR1, const ConstantRange &CR2) {
1166 });
1167}
1168
1169std::optional
1174 << "' - unknown intrinsic.\n");
1175 return MetadataVal;
1176 }
1177
1180 std::optional Range = getRangeFor(Op, II, BB);
1182 return std::nullopt;
1184 }
1185
1189}
1190
1191std::optional
1192LazyValueInfoImpl::solveBlockValueInsertElement(InsertElementInst *IEI,
1194 std::optional OptEltVal =
1195 getBlockValue(IEI->getOperand(1), BB, IEI);
1196 if (!OptEltVal)
1197 return std::nullopt;
1198 ValueLatticeElement &Res = *OptEltVal;
1199
1200 std::optional OptVecVal =
1201 getBlockValue(IEI->getOperand(0), BB, IEI);
1202 if (!OptVecVal)
1203 return std::nullopt;
1204
1205
1206
1207
1208
1209 if (OptEltVal->isConstant())
1211
1212 Res.mergeIn(*OptVecVal);
1213 return Res;
1214}
1215
1216std::optional
1217LazyValueInfoImpl::solveBlockValueExtractValue(ExtractValueInst *EVI,
1221 return solveBlockValueOverflowIntrinsic(WO, BB);
1222
1223
1224
1228 return getBlockValue(V, BB, EVI);
1229
1231 << "' - overdefined (unknown extractvalue).\n");
1233}
1234
1237 if (LHS == Val)
1238 return true;
1239
1240
1241
1245 return true;
1246 }
1247
1248
1249
1252 return true;
1253 }
1254
1255
1258 return true;
1259
1260
1263 return true;
1264
1265 return false;
1266}
1267
1268
1269std::optional
1270LazyValueInfoImpl::getValueFromSimpleICmpCondition(CmpInst::Predicate Pred,
1274 bool UseBlockValue) {
1276 true);
1278 RHSRange = ConstantRange(CI->getValue());
1279 } else if (UseBlockValue) {
1280 std::optional R =
1281 getBlockValue(RHS, CxtI->getParent(), CxtI);
1282 if (!R)
1283 return std::nullopt;
1284 RHSRange = R->asConstantRange(RHS->getType());
1285 }
1286
1287 ConstantRange TrueValues =
1290}
1291
1292static std::optional
1295 bool Invert = false;
1298 Invert = true;
1299 }
1302 if (RHS.isMaxSignedValue())
1303 return std::nullopt;
1305 }
1307 if (auto CR = Fn(RHS))
1308 return Invert ? CR->inverse() : CR;
1309 return std::nullopt;
1310}
1311
1312
1315 unsigned BitWidth = RHS->getType()->getScalarSizeInBits();
1316
1318 if (!RHSConst)
1320
1323
1326
1331}
1332
1333std::optional LazyValueInfoImpl::getValueFromICmpCondition(
1334 Value *Val, ICmpInst *ICI, bool isTrueDest, bool UseBlockValue) {
1337
1338
1341
1348 }
1349 }
1350
1354
1358 return getValueFromSimpleICmpCondition(EdgePred, RHS, Offset, ICI,
1359 UseBlockValue);
1360
1363 return getValueFromSimpleICmpCondition(SwappedPred, LHS, Offset, ICI,
1364 UseBlockValue);
1365
1368
1372
1373
1375 KnownBits Known;
1380 }
1381
1385 }
1386
1387
1388
1389
1393
1398 }
1399
1400
1401
1402
1403 const APInt *ShAmtC;
1408 EdgePred, *C, [&](const APInt &RHS) -> std::optional {
1409 APInt New = RHS << *ShAmtC;
1410 if ((New.ashr(*ShAmtC)) != RHS)
1411 return std::nullopt;
1414 });
1415 if (CR)
1417 }
1418
1419
1422
1430 }
1431 }
1432
1434}
1435
1438 bool IsTrueDest) {
1440
1443
1445
1447 if (IsTrueDest)
1450 }
1451
1452 if (IsTrueDest)
1455}
1456
1457
1458
1461
1462
1463
1467
1468
1471
1472
1473
1474 if (IsTrueDest)
1477}
1478
1479std::optional
1480LazyValueInfoImpl::getValueFromCondition(Value *Val, Value *Cond,
1481 bool IsTrueDest, bool UseBlockValue,
1482 unsigned Depth) {
1484 return getValueFromICmpCondition(Val, ICI, IsTrueDest, UseBlockValue);
1485
1487 return getValueFromTrunc(Val, Trunc, IsTrueDest);
1488
1493
1496
1499 return getValueFromCondition(Val, N, !IsTrueDest, UseBlockValue, Depth);
1500
1502 bool IsAnd;
1504 IsAnd = true;
1506 IsAnd = false;
1507 else
1509
1510 std::optional LV =
1511 getValueFromCondition(Val, L, IsTrueDest, UseBlockValue, Depth);
1512 if (!LV)
1513 return std::nullopt;
1514 std::optional RV =
1515 getValueFromCondition(Val, R, IsTrueDest, UseBlockValue, Depth);
1516 if (!RV)
1517 return std::nullopt;
1518
1519
1520
1521
1522
1523 if (IsTrueDest ^ IsAnd) {
1524 LV->mergeIn(*RV);
1525 return *LV;
1526 }
1527
1528 return LV->intersect(*RV);
1529}
1530
1531
1535
1536
1537
1538
1539
1543
1544
1545
1546
1547
1549 const APInt &OpConstVal,
1553
1560 }
1564 assert((Op0Match || Op1Match) &&
1565 "Operand 0 nor Operand 1 isn't a match");
1571 }
1575 }
1577}
1578
1579
1580std::optional
1581LazyValueInfoImpl::getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
1582 BasicBlock *BBTo, bool UseBlockValue) {
1583
1584
1586
1587
1588 if (BI->isConditional() &&
1589 BI->getSuccessor(0) != BI->getSuccessor(1)) {
1590 bool isTrueDest = BI->getSuccessor(0) == BBTo;
1591 assert(BI->getSuccessor(!isTrueDest) == BBTo &&
1592 "BBTo isn't a successor of BBFrom");
1593 Value *Condition = BI->getCondition();
1594
1595
1596
1597
1598 if (Condition == Val)
1601
1602
1603
1604 std::optional Result =
1605 getValueFromCondition(Val, Condition, isTrueDest, UseBlockValue);
1606 if (!Result)
1607 return std::nullopt;
1608
1609 if (->isOverdefined())
1611
1613 assert(Result->isOverdefined() && "Result isn't overdefined");
1614
1615
1616
1620
1621
1622
1623
1624
1625
1626
1627 APInt ConditionVal(1, isTrueDest ? 1 : 0);
1630 ValueLatticeElement OpLatticeVal =
1631 *getValueFromCondition(Usr->getOperand(0), Condition,
1632 isTrueDest, false);
1633
1635 const unsigned ResultBitWidth =
1636 Usr->getType()->getScalarSizeInBits();
1641
1645 }
1651 }
1653 } else {
1654
1655
1656
1657
1658
1659
1660
1661 for (unsigned i = 0; i < Usr->getNumOperands(); ++i) {
1662 Value *Op = Usr->getOperand(i);
1663 ValueLatticeElement OpLatticeVal = *getValueFromCondition(
1664 Op, Condition, isTrueDest, false);
1665 if (std::optional OpConst =
1668 break;
1669 }
1670 }
1671 }
1672 }
1673 }
1674 if (->isOverdefined())
1676 }
1677 }
1678
1679
1680
1682 Value *Condition = SI->getCondition();
1685 bool ValUsesConditionAndMayBeFoldable = false;
1686 if (Condition != Val) {
1687
1691 if (!ValUsesConditionAndMayBeFoldable)
1693 }
1694 assert((Condition == Val || ValUsesConditionAndMayBeFoldable) &&
1695 "Condition != Val nor Val doesn't use Condition");
1696
1697 bool DefaultCase = SI->getDefaultDest() == BBTo;
1699 ConstantRange EdgesVals(BitWidth, DefaultCase);
1700
1701 for (auto Case : SI->cases()) {
1702 APInt CaseValue = Case.getCaseValue()->getValue();
1703 ConstantRange EdgeVal(CaseValue);
1704 if (ValUsesConditionAndMayBeFoldable) {
1707 ValueLatticeElement EdgeLatticeVal =
1712 }
1713 if (DefaultCase) {
1714
1715
1716
1717
1718
1719
1720 if (Case.getCaseSuccessor() != BBTo && Condition == Val)
1721 EdgesVals = EdgesVals.difference(EdgeVal);
1722 } else if (Case.getCaseSuccessor() == BBTo)
1723 EdgesVals = EdgesVals.unionWith(EdgeVal);
1724 }
1726 }
1728}
1729
1730
1731
1732std::optional
1733LazyValueInfoImpl::getEdgeValue(Value *Val, BasicBlock *BBFrom,
1735
1738
1739 std::optional LocalResult =
1740 getEdgeValueLocal(Val, BBFrom, BBTo, true);
1741 if (!LocalResult)
1742 return std::nullopt;
1743
1745
1746 return LocalResult;
1747
1748 std::optional OptInBlock =
1749 getBlockValue(Val, BBFrom, BBFrom->getTerminator());
1750 if (!OptInBlock)
1751 return std::nullopt;
1752 ValueLatticeElement &InBlock = *OptInBlock;
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762 intersectAssumeOrGuardBlockValueConstantRange(Val, InBlock, CxtI);
1763
1764 return LocalResult->intersect(InBlock);
1765}
1766
1769 LLVM_DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '"
1770 << BB->getName() << "'\n");
1771
1772 assert(BlockValueStack.empty() && BlockValueSet.empty());
1773 std::optional OptResult = getBlockValue(V, BB, CxtI);
1774 if (!OptResult) {
1775 solve();
1776 OptResult = getBlockValue(V, BB, CxtI);
1777 assert(OptResult && "Value not available after solving");
1778 }
1779
1780 LLVM_DEBUG(dbgs() << " Result = " << *OptResult << "\n");
1781 return *OptResult;
1782}
1783
1786 << "'\n");
1787
1790
1794 intersectAssumeOrGuardBlockValueConstantRange(V, Result, CxtI);
1795
1796 LLVM_DEBUG(dbgs() << " Result = " << Result << "\n");
1797 return Result;
1798}
1799
1803 LLVM_DEBUG(dbgs() << "LVI Getting edge value " << *V << " from '"
1805 << "'\n");
1806
1807 std::optional Result =
1808 getEdgeValue(V, FromBB, ToBB, CxtI);
1809 while (!Result) {
1810
1811
1812
1813 solve();
1814 Result = getEdgeValue(V, FromBB, ToBB, CxtI);
1815 }
1816
1817 LLVM_DEBUG(dbgs() << " Result = " << *Result << "\n");
1818 return *Result;
1819}
1820
1822 Value *V = U.get();
1825
1826
1827
1828 const Use *CurrU = &U;
1829
1830 const unsigned MaxUsesToInspect = 3;
1831 for (unsigned I = 0; I < MaxUsesToInspect; ++I) {
1832 std::optional CondVal;
1835
1836
1838 break;
1839 if (CurrU->getOperandNo() == 1)
1840 CondVal =
1841 *getValueFromCondition(V, SI->getCondition(), true,
1842 false);
1843 else if (CurrU->getOperandNo() == 2)
1844 CondVal =
1845 *getValueFromCondition(V, SI->getCondition(), false,
1846 false);
1848
1849 CondVal = *getEdgeValueLocal(V, PHI->getIncomingBlock(*CurrU),
1850 PHI->getParent(), false);
1851 }
1852 if (CondVal)
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864 if (!CurrI->hasOneUse() ||
1866 CurrI, false))
1867 break;
1869 }
1870 return VL;
1871}
1872
1875 TheCache.threadEdgeImpl(OldSucc, NewSucc);
1876}
1877
1878
1879
1880
1881
1884
1885 if (auto *Impl = Info.getImpl())
1886 Impl->clear();
1887
1888
1889 return false;
1890}
1891
1897
1899
1900
1902 if (!PImpl) {
1903 assert(M && "getCache() called with a null Module");
1908 }
1909 return *PImpl;
1910}
1911
1913
1915
1917
1918 if (auto *Impl = getImpl()) {
1919 delete &*Impl;
1920 PImpl = nullptr;
1921 }
1922}
1923
1925 FunctionAnalysisManager::Invalidator &Inv) {
1926
1927
1930 return true;
1931
1932 return false;
1933}
1934
1936
1943
1944
1945
1946
1947
1948
1949
1951 V = V->stripPointerCasts();
1952
1954 return true;
1955 return false;
1956}
1957
1959
1961 return nullptr;
1962
1965 getOrCreateImpl(BB->getModule()).getValueInBlock(V, BB, CxtI);
1966
1967 if (Result.isConstant())
1968 return Result.getConstant();
1969 if (Result.isConstantRange()) {
1970 const ConstantRange &CR = Result.getConstantRange();
1972 return ConstantInt::get(V->getType(), *SingleVal);
1973 }
1974 return nullptr;
1975}
1976
1978 bool UndefAllowed) {
1981 getOrCreateImpl(BB->getModule()).getValueInBlock(V, BB, CxtI);
1982 return Result.asConstantRange(V->getType(), UndefAllowed);
1983}
1984
1986 bool UndefAllowed) {
1989 getOrCreateImpl(Inst->getModule()).getValueAtUse(U);
1990 return Result.asConstantRange(U->getType(), UndefAllowed);
1991}
1992
1993
1994
2000 getOrCreateImpl(M).getValueOnEdge(V, FromBB, ToBB, CxtI);
2001
2002 if (Result.isConstant())
2003 return Result.getConstant();
2004 if (Result.isConstantRange()) {
2005 const ConstantRange &CR = Result.getConstantRange();
2007 return ConstantInt::get(V->getType(), *SingleVal);
2008 }
2009 return nullptr;
2010}
2011
2018 getOrCreateImpl(M).getValueOnEdge(V, FromBB, ToBB, CxtI);
2019
2020 return Result.asConstantRange(V->getType(), true);
2021}
2022
2026
2029
2038 return nullptr;
2039 }
2040
2042
2043
2045
2051
2056 }
2057 return nullptr;
2058 }
2059
2060 return nullptr;
2061}
2062
2063
2064
2071 getOrCreateImpl(M).getValueOnEdge(V, FromBB, ToBB, CxtI);
2072
2074}
2075
2078 bool UseBlockValue) {
2079
2080
2081
2082
2084 const DataLayout &DL = M->getDataLayout();
2085 if (V->getType()->isPointerTy() && C->isNullValue() &&
2086 isKnownNonZero(V->stripPointerCastsSameRepresentation(), DL)) {
2092 }
2093
2094 auto &Impl = getOrCreateImpl(M);
2096 UseBlockValue ? Impl.getValueInBlock(V, CxtI->getParent(), CxtI)
2097 : Impl.getValueAt(V, CxtI);
2099 if (Ret)
2100 return Ret;
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2125
2126
2127
2129 if (PI == PE)
2130 return nullptr;
2131
2132
2133
2134
2135
2137 if (PHI->getParent() == BB) {
2138 Constant *Baseline = nullptr;
2139 for (unsigned i = 0, e = PHI->getNumIncomingValues(); i < e; i++) {
2142
2145
2146
2147
2148 Baseline = (i == 0) ? Result
2149 : (Baseline == Result ? Baseline
2150 : nullptr);
2151 if (!Baseline)
2152 break;
2153 }
2154 if (Baseline)
2155 return Baseline;
2156 }
2157
2158
2159
2160
2162
2163
2164
2166 if (Baseline) {
2167
2168 while (++PI != PE) {
2170 if (Ret != Baseline)
2171 break;
2172 }
2173
2174 if (PI == PE) {
2175 return Baseline;
2176 }
2177 }
2178 }
2179
2180 return nullptr;
2181}
2182
2185 bool UseBlockValue) {
2187 return getPredicateAt(Pred, LHS, C, CxtI, UseBlockValue);
2190 UseBlockValue);
2191
2192
2193
2194
2195 if (UseBlockValue) {
2198 getOrCreateImpl(M).getValueInBlock(LHS, CxtI->getParent(), CxtI);
2199 if (L.isOverdefined())
2200 return nullptr;
2201
2203 getOrCreateImpl(M).getValueInBlock(RHS, CxtI->getParent(), CxtI);
2205 return L.getCompare(Pred, Ty, R, M->getDataLayout());
2206 }
2207 return nullptr;
2208}
2209
2212 if (auto *Impl = getImpl())
2213 Impl->threadEdge(PredBB, OldSucc, NewSucc);
2214}
2215
2217 if (auto *Impl = getImpl())
2218 Impl->forgetValue(V);
2219}
2220
2222 if (auto *Impl = getImpl())
2223 Impl->eraseBlock(BB);
2224}
2225
2227 if (auto *Impl = getImpl())
2228 Impl->clear();
2229}
2230
2232 if (auto *Impl = getImpl())
2233 Impl->printLVI(F, DTree, OS);
2234}
2235
2236
2237void LazyValueInfoAnnotatedWriter::emitBasicBlockStartAnnot(
2239
2241 for (const auto &Arg : F->args()) {
2244 if (Result.isUnknown())
2245 continue;
2246 OS << "; LatticeVal for: '" << Arg << "' is: " << Result << "\n";
2247 }
2248}
2249
2250
2251
2252
2253
2254void LazyValueInfoAnnotatedWriter::emitInstructionAnnot(
2255 const Instruction *I, formatted_raw_ostream &OS) {
2256
2258 SmallPtrSet<const BasicBlock*, 16> BlocksContainingLVI;
2259
2260
2261
2262
2263
2264 auto printResult = [&](const BasicBlock *BB) {
2265 if (!BlocksContainingLVI.insert(BB).second)
2266 return;
2269 OS << "; LatticeVal for: '" << *I << "' in BB: '";
2271 OS << "' is: " << Result << "\n";
2272 };
2273
2274 printResult(ParentBB);
2275
2276
2277 for (const auto *BBSucc : successors(ParentBB))
2278 if (DT.dominates(ParentBB, BBSucc))
2279 printResult(BBSucc);
2280
2281
2282 for (const auto *U : I->users())
2285 printResult(UseI->getParent());
2286
2287}
2288
2291 OS << "LVI for function '" << F.getName() << "':\n";
2294 LVI.printLVI(F, DTree, OS);
2296}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseSet and SmallDenseSet classes.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
static bool isOperationFoldable(User *Usr)
Definition LazyValueInfo.cpp:1540
static void AddNonNullPointer(Value *Ptr, NonNullPointerSet &PtrSet, bool IsDereferenced=true)
Definition LazyValueInfo.cpp:672
static void AddNonNullPointersByInstruction(Instruction *I, NonNullPointerSet &PtrSet)
Definition LazyValueInfo.cpp:680
static std::optional< ConstantRange > getRangeViaSLT(CmpInst::Predicate Pred, APInt RHS, function_ref< std::optional< ConstantRange >(const APInt &)> Fn)
Definition LazyValueInfo.cpp:1293
static const unsigned MaxProcessedPerValue
Definition LazyValueInfo.cpp:51
static ValueLatticeElement getValueFromICmpCtpop(ICmpInst::Predicate Pred, Value *RHS)
Get value range for a "ctpop(Val) Pred RHS" condition.
Definition LazyValueInfo.cpp:1313
static bool usesOperand(User *Usr, Value *Op)
Definition LazyValueInfo.cpp:1532
static ValueLatticeElement constantFoldUser(User *Usr, Value *Op, const APInt &OpConstVal, const DataLayout &DL)
Definition LazyValueInfo.cpp:1548
static ValueLatticeElement getFromRangeMetadata(Instruction *BBI)
Definition LazyValueInfo.cpp:588
lazy value Lazy Value Information static true cl::opt< bool > PerPredRanges("lvi-per-pred-ranges", cl::Hidden, cl::init(false), cl::desc("Enable tracking of ranges for a value in a block for" "each block predecessor (default = false)"))
static Constant * getPredicateResult(CmpInst::Predicate Pred, Constant *C, const ValueLatticeElement &Val, const DataLayout &DL)
Definition LazyValueInfo.cpp:2023
static ValueLatticeElement getValueFromOverflowCondition(Value *Val, WithOverflowInst *WO, bool IsTrueDest)
Definition LazyValueInfo.cpp:1459
static bool isKnownNonConstant(Value *V)
Returns true if we can statically tell that this value will never be a "useful" constant.
Definition LazyValueInfo.cpp:1950
static bool matchICmpOperand(APInt &Offset, Value *LHS, Value *Val, ICmpInst::Predicate Pred)
Definition LazyValueInfo.cpp:1235
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
static bool InBlock(const Value *V, const BasicBlock *BB)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
This templated class represents "all analyses that operate over " (e....
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()
void setPreservesAll()
Set by analyses that do not transform their input at all.
This class represents an incoming formal argument to a Function.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI bool isEntryBlock() const
Return true if this is the entry block of the containing function.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
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...
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
LLVM_ABI unsigned getNoWrapKind() const
Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
LLVM_ABI Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
BinaryOps getOpcode() const
Value handle with callbacks on RAUW and destruction.
This is the base class for all instructions that perform data casts.
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Type * getDestTy() const
Return the destination type, as a convenience.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
This class represents a range of values.
LLVM_ABI ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
static LLVM_ABI ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned)
Initialize a range based on a known bits constraint.
LLVM_ABI ConstantRange castOp(Instruction::CastOps CastOp, uint32_t BitWidth) const
Return a new range representing the possible values resulting from an application of the specified ca...
LLVM_ABI ConstantRange umin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned minimum of a value in ...
LLVM_ABI APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
LLVM_ABI bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other?
static LLVM_ABI ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
LLVM_ABI ConstantRange abs(bool IntMinIsPoison=false) const
Calculate absolute value range.
static LLVM_ABI bool isIntrinsicSupported(Intrinsic::ID IntrinsicID)
Returns true if ConstantRange calculations are supported for intrinsic with IntrinsicID.
LLVM_ABI ConstantRange overflowingBinaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind) const
Return a new range representing the possible values resulting from an application of the specified ov...
bool isSingleElement() const
Return true if this set contains exactly one member.
LLVM_ABI ConstantRange truncate(uint32_t BitWidth, unsigned NoWrapKind=0) const
Return a new range in the specified integer type, which must be strictly smaller than the current typ...
LLVM_ABI ConstantRange umax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned maximum of a value in ...
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
static LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
LLVM_ABI ConstantRange inverse() const
Return a new range that is the logical not of the current set.
LLVM_ABI APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
static LLVM_ABI ConstantRange makeMaskNotEqualRange(const APInt &Mask, const APInt &C)
Initialize a range containing all values X that satisfy (X & Mask) / != C.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
LLVM_ABI ConstantRange smin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed minimum of a value in thi...
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
LLVM_ABI ConstantRange smax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed maximum of a value in thi...
LLVM_ABI ConstantRange binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const
Return a new range representing the possible values resulting from an application of the specified bi...
static LLVM_ABI ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, const APInt &Other, unsigned NoWrapKind)
Produce the range that contains X if and only if "X BinOp Other" does not wrap.
This is an important base class in LLVM.
static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
LLVM_ABI ConstantRange toConstantRange() const
Convert constant to an approximate constant range.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
A parsed version of the target data layout string in and methods for querying it.
iterator find_as(const LookupKeyT &Val)
Alternate version of find() which allows a different, and possibly less expensive,...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FunctionPass class - This class is used to implement most global optimizations.
Module * getParent()
Get the module that this global value is contained inside of...
This instruction compares its operands according to the predicate given to the constructor.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
This instruction inserts a single (scalar) element into a VectorType value.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
Analysis to compute lazy value information.
Result run(Function &F, FunctionAnalysisManager &FAM)
Definition LazyValueInfo.cpp:1937
Definition LazyValueInfo.cpp:359
ValueLatticeElement getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI=nullptr)
This is the query interface to determine the lattice value for the specified Value* that is true on t...
Definition LazyValueInfo.cpp:1801
ValueLatticeElement getValueAt(Value *V, Instruction *CxtI)
This is the query interface to determine the lattice value for the specified Value* at the specified ...
Definition LazyValueInfo.cpp:1784
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc)
This is the update interface to inform the cache that an edge from PredBB to OldSucc has been threade...
Definition LazyValueInfo.cpp:1873
void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS)
Printing the LazyValueInfo Analysis.
Definition LazyValueInfo.cpp:485
void forgetValue(Value *V)
This is part of the update interface to remove information related to this value from the cache.
Definition LazyValueInfo.cpp:492
void eraseBlock(BasicBlock *BB)
This is part of the update interface to inform the cache that a block has been deleted.
Definition LazyValueInfo.cpp:496
void clear()
Complete flush all previously computed values.
Definition LazyValueInfo.cpp:480
LazyValueInfoImpl(AssumptionCache *AC, const DataLayout &DL, Function *GuardDecl)
Definition LazyValueInfo.cpp:504
ValueLatticeElement getValueInBlock(Value *V, BasicBlock *BB, Instruction *CxtI=nullptr)
This is the query interface to determine the lattice value for the specified Value* at the context in...
Definition LazyValueInfo.cpp:1767
ValueLatticeElement getValueAtUse(const Use &U)
Definition LazyValueInfo.cpp:1821
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition LazyValueInfo.cpp:2289
Wrapper around LazyValueInfo.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Definition LazyValueInfo.cpp:1882
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
Definition LazyValueInfo.cpp:1935
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition LazyValueInfo.cpp:1892
LazyValueInfo & getLVI()
Definition LazyValueInfo.cpp:1898
LazyValueInfoWrapperPass()
Definition LazyValueInfo.cpp:54
This pass computes, caches, and vends lazy value constraint information.
void eraseBlock(BasicBlock *BB)
Inform the analysis cache that we have erased a block.
Definition LazyValueInfo.cpp:2221
ConstantRange getConstantRangeAtUse(const Use &U, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the value at a specific use-site.
Definition LazyValueInfo.cpp:1985
ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
Definition LazyValueInfo.cpp:1977
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc)
Inform the analysis cache that we have threaded an edge from PredBB to OldSucc to be from PredBB to N...
Definition LazyValueInfo.cpp:2210
Constant * getPredicateOnEdge(CmpInst::Predicate Pred, Value *V, Constant *C, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI=nullptr)
Determine whether the specified value comparison with a constant is known to be true or false on the ...
Definition LazyValueInfo.cpp:2065
void releaseMemory()
Definition LazyValueInfo.cpp:1916
Constant * getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI=nullptr)
Determine whether the specified value is known to be a constant on the specified edge.
Definition LazyValueInfo.cpp:1995
ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI=nullptr)
Return the ConstantRage constraint that is known to hold for the specified value on the specified edg...
Definition LazyValueInfo.cpp:2012
Constant * getConstant(Value *V, Instruction *CxtI)
Determine whether the specified value is known to be a constant at the specified instruction.
Definition LazyValueInfo.cpp:1958
void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS)
Print the \LazyValueInfo Analysis.
Definition LazyValueInfo.cpp:2231
void forgetValue(Value *V)
Remove information related to this value from the cache.
Definition LazyValueInfo.cpp:2216
void clear()
Complete flush all previously computed values.
Definition LazyValueInfo.cpp:2226
Constant * getPredicateAt(CmpInst::Predicate Pred, Value *V, Constant *C, Instruction *CxtI, bool UseBlockValue)
Determine whether the specified value comparison with a constant is known to be true or false at the ...
Definition LazyValueInfo.cpp:2076
~LazyValueInfo()
Definition LazyValueInfo.cpp:1914
bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle invalidation events in the new pass manager.
Definition LazyValueInfo.cpp:1924
An instruction for reading from memory.
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memcpy/memmove intrinsics.
A Module instance is used to store all the information related to an LLVM module.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AnalysisType & getAnalysis() const
getAnalysis() - This function is used by subclasses to get to the analysis information ...
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.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
This class represents the LLVM 'select' instruction.
Implements a dense probed hash-table based set with some number of buckets stored inline.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class represents a truncation of integer types.
unsigned getNoWrapKind() const
Returns the no-wrap kind of the operation.
bool hasNoUnsignedWrap() const
Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
This class represents lattice values for constants.
static ValueLatticeElement getRange(ConstantRange CR, bool MayIncludeUndef=false)
bool isOverdefined() const
static ValueLatticeElement getNot(Constant *C)
ConstantRange asConstantRange(unsigned BW, bool UndefAllowed=false) const
bool isNotConstant() const
std::optional< APInt > asConstantInteger() const
const ConstantRange & getConstantRange(bool UndefAllowed=true) const
Returns the constant range for this value.
bool isConstantRange(bool UndefAllowed=true) const
Returns true if this value is a constant range.
static ValueLatticeElement get(Constant *C)
Constant * getNotConstant() const
LLVM_ABI ValueLatticeElement intersect(const ValueLatticeElement &Other) const
Combine two sets of facts about the same value into a single set of facts.
Constant * getConstant() const
bool mergeIn(const ValueLatticeElement &RHS, MergeOptions Opts=MergeOptions())
Updates this object to approximate both this object and RHS.
static ValueLatticeElement getOverdefined()
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI const Value * stripInBoundsOffsets(function_ref< void(const Value *)> Func=[](const Value *) {}) const
Strip off pointer casts and inbounds GEPs.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Represents an op.with.overflow intrinsic.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find_as(const LookupKeyT &Val)
Alternative version of find() which allows a different, and possibly less expensive,...
bool erase(const ValueT &V)
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
PtrToIntSameSize_match< OpTy > m_PtrToIntSameSize(const DataLayout &DL, const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_IntrinsicIntrinsic::fabs(m_Value(X))
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
This namespace contains all of the command line option processing machinery.
@ User
could "use" a pointer
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr, bool AllowEphemerals=false)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
auto pred_end(const MachineBasicBlock *BB)
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
static ConstantRange getRange(Value *Op, SCCPSolver &Solver, const SmallPtrSetImpl< Value * > &InsertedValues)
Helper for getting ranges from Solver.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
LLVM_ABI bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
LLVM_ABI FunctionPass * createLazyValueInfoPass()
createLazyValueInfoPass - This creates an instance of the LazyValueInfo pass.
Definition LazyValueInfo.cpp:68
auto dyn_cast_or_null(const Y &Val)
constexpr unsigned MaxAnalysisRecursionDepth
@ SPF_ABS
Floating point maxnum.
@ SPF_NABS
Absolute value.
@ SPF_UMIN
Signed minimum.
@ SPF_UMAX
Signed maximum.
@ SPF_SMAX
Unsigned minimum.
LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI Value * simplifyExtractValueInst(Value *Agg, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)
Given operands for an ExtractValueInst, fold the result or return null.
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
DWARFExpression::Operation Op
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)
Don't use information from its non-constant operands.
PredIterator< BasicBlock, Value::user_iterator > pred_iterator
static bool hasSingleValue(const ValueLatticeElement &Val)
constexpr unsigned BitWidth
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
A special type used by analysis passes to provide an address that identifies that particular analysis...
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
SelectPatternFlavor Flavor
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?