LLVM: lib/Analysis/IVDescriptors.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
25
26using namespace llvm;
28
29#define DEBUG_TYPE "iv-descriptors"
30
33 for (const Use &Use : I->operands())
34 if (!Set.count(dyn_cast(Use)))
35 return false;
36 return true;
37}
38
40 switch (Kind) {
41 default:
42 break;
56 return true;
57 }
58 return false;
59}
60
63}
64
65
66
67
68
72 if (!Phi->hasOneUse())
73 return Phi;
74
75 const APInt *M = nullptr;
76 Instruction *I, *J = cast(Phi->use_begin()->getUser());
77
78
79
81 int32_t Bits = (*M + 1).exactLogBase2();
82 if (Bits > 0) {
86 return J;
87 }
88 }
89 return Phi;
90}
91
92
93
98 bool IsSigned = false;
100 uint64_t MaxBitWidth = DL.getTypeSizeInBits(Exit->getType());
101
102 if (DB) {
103
104
105
106
107
108 auto Mask = DB->getDemandedBits(Exit);
109 MaxBitWidth = Mask.getBitWidth() - Mask.countl_zero();
110 }
111
112 if (MaxBitWidth == DL.getTypeSizeInBits(Exit->getType()) && AC && DT) {
113
114
115
117 auto NumTypeBits = DL.getTypeSizeInBits(Exit->getType());
118 MaxBitWidth = NumTypeBits - NumSignBits;
120 if (!Bits.isNonNegative()) {
121
122
123
124 IsSigned = true;
125
126
127 ++MaxBitWidth;
128 }
129 }
131
132 return std::make_pair(Type::getIntNTy(Exit->getContext(), MaxBitWidth),
133 IsSigned);
134}
135
136
137
138
139
141 Type *RecurrenceType,
143 unsigned &MinWidthCastToRecurTy) {
144
148 MinWidthCastToRecurTy = -1U;
149
150 while (!Worklist.empty()) {
153 if (auto *Cast = dyn_cast(Val)) {
154 if (Cast->getSrcTy() == RecurrenceType) {
155
156
157
159 continue;
160 }
161 if (Cast->getDestTy() == RecurrenceType) {
162
163
164
165
166 MinWidthCastToRecurTy = std::min(
167 MinWidthCastToRecurTy, Cast->getSrcTy()->getScalarSizeInBits());
168 continue;
169 }
170 }
171
172
173 for (Value *O : cast(Val)->operands())
174 if (auto *I = dyn_cast(O))
177 }
178}
179
180
181
184
186 return false;
187
188 if (Kind == RecurKind::FAdd && Exit->getOpcode() != Instruction::FAdd)
189 return false;
190
193 return false;
194
195
196 if (Exit != ExactFPMathInst || Exit->hasNUsesOrMore(3))
197 return false;
198
199
200
201 auto *Op0 = Exit->getOperand(0);
202 auto *Op1 = Exit->getOperand(1);
204 return false;
206 return false;
207
208 LLVM_DEBUG(dbgs() << "LV: Found an ordered reduction: Phi: " << *Phi
209 << ", ExitInst: " << *Exit << "\n");
210
211 return true;
212}
213
218 if (Phi->getNumIncomingValues() != 2)
219 return false;
220
221
222 if (Phi->getParent() != TheLoop->getHeader())
223 return false;
224
225
226
228
229
230
231
232
234
235
236
237
239
240
241 bool FoundReduxOp = false;
242
243
244
245
246
247 bool FoundStartPHI = false;
248
249
250
251
252 unsigned NumCmpSelectPatternInst = 0;
253 InstDesc ReduxDesc(false, nullptr);
254
255
256 Type *RecurrenceType = Phi->getType();
258 unsigned MinWidthCastToRecurrenceType;
260 bool IsSigned = false;
261
264
265
266
267
268
269
272 return false;
273 } else if (RecurrenceType->isIntegerTy()) {
275 return false;
277 Start = lookThroughAnd(Phi, RecurrenceType, VisitedInsts, CastInsts);
278 } else {
279
280 return false;
281 }
282
284 VisitedInsts.insert(Start);
285
286
287
289
290
291
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313 while (!Worklist.empty()) {
315
316
317
318 if (auto *SI = dyn_cast(Cur)) {
319 if (!SE) {
320 LLVM_DEBUG(dbgs() << "Store instructions are not processed without "
321 << "Scalar Evolution Analysis\n");
322 return false;
323 }
324
325 const SCEV *PtrScev = SE->getSCEV(SI->getPointerOperand());
326
328 const SCEV *OtherScev =
330
331 if (OtherScev != PtrScev) {
332 LLVM_DEBUG(dbgs() << "Storing reduction value to different addresses "
333 << "inside the loop: " << *SI->getPointerOperand()
334 << " and "
336 return false;
337 }
338 }
339
340
342 LLVM_DEBUG(dbgs() << "Storing reduction value to non-uniform address "
343 << "inside the loop: " << *SI->getPointerOperand()
344 << '\n');
345 return false;
346 }
347
348
350 continue;
351 }
352
353
354
355
357 return false;
358
359 bool IsAPhi = isa(Cur);
360
361
362 if (Cur != Phi && IsAPhi && Cur->getParent() == Phi->getParent())
363 return false;
364
365
366
367 if (!Cur->isCommutative() && !IsAPhi && !isa(Cur) &&
368 !isa(Cur) && !isa(Cur) &&
369 !VisitedInsts.count(dyn_cast(Cur->getOperand(0))))
370 return false;
371
372
373
374
375 if (Cur != Start) {
376 ReduxDesc =
377 isRecurrenceInstr(TheLoop, Phi, Cur, Kind, ReduxDesc, FuncFMF, SE);
378 ExactFPMathInst = ExactFPMathInst == nullptr
380 : ExactFPMathInst;
382 return false;
383
384 if (isa(ReduxDesc.getPatternInst()) && !IsAPhi) {
386 if (auto *Sel = dyn_cast(ReduxDesc.getPatternInst())) {
387
388
389
390
391 if (auto *FCmp = dyn_cast(Sel->getCondition()))
392 CurFMF |= FCmp->getFastMathFlags();
393 }
394 FMF &= CurFMF;
395 }
396
397
398
401 }
402
403 bool IsASelect = isa(Cur);
404
405
406
409 return false;
410
411
414 return false;
415
416
417 if (IsAPhi && Cur != Phi && (Cur, VisitedInsts))
418 return false;
419
421 (isa(Cur) || isa(Cur)))
422 ++NumCmpSelectPatternInst;
424 (isa(Cur) || isa(Cur)))
425 ++NumCmpSelectPatternInst;
426
427
428 FoundReduxOp |= !IsAPhi && Cur != Start;
429
430
431
432
437
438
439
442 return false;
443
444
446 if (!TheLoop->contains(Parent)) {
447
448
449 if (ExitInstruction == Cur)
450 continue;
451
452
453
454
455
456 if (ExitInstruction != nullptr || Cur == Phi)
457 return false;
458
459
460
461
463 return false;
464
465 ExitInstruction = Cur;
466 continue;
467 }
468
469
470
471
472 InstDesc IgnoredVal(false, nullptr);
473 if (VisitedInsts.insert(UI).second) {
474 if (isa(UI)) {
476 } else {
477 StoreInst *SI = dyn_cast(UI);
478 if (SI && SI->getPointerOperand() == Cur) {
479
480
481 return false;
482 }
484 }
485 } else if (!isa(UI) &&
486 ((!isa(UI) && !isa(UI) &&
487 !isa(UI)) ||
490 .isRecurrence() &&
492 return false;
493
494
495 if (UI == Phi)
496 FoundStartPHI = true;
497 }
500 }
501
502
503
504
506 NumCmpSelectPatternInst != 0)
507 return false;
508
510 return false;
511
513
514
515
517 LLVM_DEBUG(dbgs() << "Not a final reduction value stored: "
519 return false;
520 }
521
522
523
524 if (ExitInstruction &&
526 LLVM_DEBUG(dbgs() << "Last store Instruction of reduction value does not "
527 "store last calculated value of the reduction: "
529 return false;
530 }
531
532
533
534 if (!ExitInstruction)
536 }
537
538 if (!FoundStartPHI || !FoundReduxOp || !ExitInstruction)
539 return false;
540
541 const bool IsOrdered =
543
544 if (Start != Phi) {
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569 Type *ComputedType;
570 std::tie(ComputedType, IsSigned) =
572 if (ComputedType != RecurrenceType)
573 return false;
574 }
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589 collectCastInstrs(TheLoop, ExitInstruction, RecurrenceType, CastInsts,
590 MinWidthCastToRecurrenceType);
591
592
593
594
595
596
597
598
600 FMF, ExactFPMathInst, RecurrenceType, IsSigned,
601 IsOrdered, CastInsts, MinWidthCastToRecurrenceType);
602 RedDes = RD;
603
604 return true;
605}
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
631
632
635 if (auto *Select = dyn_cast(*I->user_begin()))
637 }
638
642
644 Value *NonPhi = nullptr;
645
646 if (OrigPhi == dyn_cast(SI->getTrueValue()))
647 NonPhi = SI->getFalseValue();
648 else if (OrigPhi == dyn_cast(SI->getFalseValue()))
649 NonPhi = SI->getTrueValue();
650 else
652
653
654
655
658
661}
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
693
694
695
696
699
700
701 Value *NonRdxPhi = nullptr;
707
708 auto IsIncreasingLoopInduction = [&](Value *V) {
709 Type *Ty = V->getType();
711 return false;
712
713 auto *AR = dyn_cast(SE.getSCEV(V));
714 if (!AR || AR->getLoop() != TheLoop)
715 return false;
716
717 const SCEV *Step = AR->getStepRecurrence(SE);
719 return false;
720
723
724
725
726
727
728
729
733 LLVM_DEBUG(dbgs() << "LV: FindLastIV valid range is " << ValidRange
734 << ", and the signed range of " << *AR << " is "
735 << IVRange << "\n");
736
737
738 return ValidRange.contains(IVRange);
739 };
740
741
742
743
744
745 if (!IsIncreasingLoopInduction(NonRdxPhi))
747
750}
751
755 assert((isa(I) || isa(I) || isa(I)) &&
756 "Expected a cmp or select or call instruction");
759
760
761
764 if (auto *Select = dyn_cast(*I->user_begin()))
766 }
767
768
769 if (!isa(I) &&
773
774
795
797}
798
799
800
801
802
803
804
805
806
807
810 SelectInst *SI = dyn_cast(I);
811 if (!SI)
813
814 CmpInst *CI = dyn_cast(SI->getCondition());
815
818
819 Value *TrueVal = SI->getTrueValue();
820 Value *FalseVal = SI->getFalseValue();
821
822
823 if ((isa(TrueVal) && isa(FalseVal)) ||
824 (!isa(TrueVal) && !isa(FalseVal)))
826
827 Instruction *I1 = isa(TrueVal) ? dyn_cast(FalseVal)
828 : dyn_cast(TrueVal);
829 if (!I1 || !I1->isBinaryOp())
831
832 Value *Op1, *Op2;
835 I1->isFast()) ||
841
842 Instruction *IPhi = isa(Op1) ? dyn_cast(Op1)
843 : dyn_cast(Op2);
844 if (!IPhi || IPhi != FalseVal)
846
848}
849
854 switch (I->getOpcode()) {
855 default:
857 case Instruction::PHI:
859 case Instruction::Sub:
860 case Instruction::Add:
862 case Instruction::Mul:
864 case Instruction::And:
866 case Instruction::Or:
868 case Instruction::Xor:
870 case Instruction::FDiv:
871 case Instruction::FMul:
873 I->hasAllowReassoc() ? nullptr : I);
874 case Instruction::FSub:
875 case Instruction::FAdd:
877 I->hasAllowReassoc() ? nullptr : I);
878 case Instruction::Select:
884 [[fallthrough]];
885 case Instruction::FCmp:
886 case Instruction::ICmp:
887 case Instruction::Call:
890 auto HasRequiredFMF = [&]() {
892 return true;
893 if (isa(I) && I->hasNoNaNs() && I->hasNoSignedZeros())
894 return true;
895
896
899 };
905 I->hasAllowReassoc() ? nullptr : I);
907 }
908}
909
912 unsigned MaxNumUses) {
913 unsigned NumUses = 0;
914 for (const Use &U : I->operands()) {
915 if (Insts.count(dyn_cast(U)))
916 ++NumUses;
917 if (NumUses > MaxNumUses)
918 return true;
919 }
920
921 return false;
922}
923
930 Function &F = *Header->getParent();
933 F.getFnAttribute("no-nans-fp-math").getValueAsBool());
935 F.getFnAttribute("no-signed-zeros-fp-math").getValueAsBool());
936
938 SE)) {
939 LLVM_DEBUG(dbgs() << "Found an ADD reduction PHI." << *Phi << "\n");
940 return true;
941 }
943 SE)) {
944 LLVM_DEBUG(dbgs() << "Found a MUL reduction PHI." << *Phi << "\n");
945 return true;
946 }
948 SE)) {
949 LLVM_DEBUG(dbgs() << "Found an OR reduction PHI." << *Phi << "\n");
950 return true;
951 }
953 SE)) {
954 LLVM_DEBUG(dbgs() << "Found an AND reduction PHI." << *Phi << "\n");
955 return true;
956 }
958 SE)) {
959 LLVM_DEBUG(dbgs() << "Found a XOR reduction PHI." << *Phi << "\n");
960 return true;
961 }
963 SE)) {
964 LLVM_DEBUG(dbgs() << "Found a SMAX reduction PHI." << *Phi << "\n");
965 return true;
966 }
968 SE)) {
969 LLVM_DEBUG(dbgs() << "Found a SMIN reduction PHI." << *Phi << "\n");
970 return true;
971 }
973 SE)) {
974 LLVM_DEBUG(dbgs() << "Found a UMAX reduction PHI." << *Phi << "\n");
975 return true;
976 }
978 SE)) {
979 LLVM_DEBUG(dbgs() << "Found a UMIN reduction PHI." << *Phi << "\n");
980 return true;
981 }
983 SE)) {
984 LLVM_DEBUG(dbgs() << "Found an integer conditional select reduction PHI."
985 << *Phi << "\n");
986 return true;
987 }
989 DT, SE)) {
992 ? "F"
993 : "I")
994 << "FindLastIV reduction PHI." << *Phi << "\n");
995 return true;
996 }
998 SE)) {
999 LLVM_DEBUG(dbgs() << "Found an FMult reduction PHI." << *Phi << "\n");
1000 return true;
1001 }
1003 SE)) {
1004 LLVM_DEBUG(dbgs() << "Found an FAdd reduction PHI." << *Phi << "\n");
1005 return true;
1006 }
1008 SE)) {
1009 LLVM_DEBUG(dbgs() << "Found a float MAX reduction PHI." << *Phi << "\n");
1010 return true;
1011 }
1013 SE)) {
1014 LLVM_DEBUG(dbgs() << "Found a float MIN reduction PHI." << *Phi << "\n");
1015 return true;
1016 }
1018 SE)) {
1019 LLVM_DEBUG(dbgs() << "Found a float conditional select reduction PHI."
1020 << " PHI." << *Phi << "\n");
1021 return true;
1022 }
1024 SE)) {
1025 LLVM_DEBUG(dbgs() << "Found an FMulAdd reduction PHI." << *Phi << "\n");
1026 return true;
1027 }
1029 SE)) {
1030 LLVM_DEBUG(dbgs() << "Found a float MAXIMUM reduction PHI." << *Phi << "\n");
1031 return true;
1032 }
1034 SE)) {
1035 LLVM_DEBUG(dbgs() << "Found a float MINIMUM reduction PHI." << *Phi << "\n");
1036 return true;
1037 }
1038
1039 return false;
1040}
1041
1044
1045
1046 if (Phi->getParent() != TheLoop->getHeader() ||
1047 Phi->getNumIncomingValues() != 2)
1048 return false;
1049
1050
1051
1054 if (!Preheader || !Latch)
1055 return false;
1056
1057
1058 if (Phi->getBasicBlockIndex(Preheader) < 0 ||
1059 Phi->getBasicBlockIndex(Latch) < 0)
1060 return false;
1061
1062
1063
1064 auto *Previous = dyn_cast(Phi->getIncomingValueForBlock(Latch));
1065
1066
1067
1068
1069
1071 while (auto *PrevPhi = dyn_cast_or_null(Previous)) {
1072 if (PrevPhi->getParent() != Phi->getParent())
1073 return false;
1074 if (!SeenPhis.insert(PrevPhi).second)
1075 return false;
1076 Previous = dyn_cast(PrevPhi->getIncomingValueForBlock(Latch));
1077 }
1078
1079 if (!Previous || !TheLoop->contains(Previous) || isa(Previous))
1080 return false;
1081
1082
1083
1084
1085
1086
1087
1089 BasicBlock *PhiBB = Phi->getParent();
1091 auto TryToPushSinkCandidate = [&](Instruction *SinkCandidate) {
1092
1093 if (Previous == SinkCandidate)
1094 return false;
1095
1096 if (!Seen.insert(SinkCandidate).second)
1097 return true;
1099 SinkCandidate))
1100 return true;
1101
1102 if (SinkCandidate->getParent() != PhiBB ||
1103 SinkCandidate->mayHaveSideEffects() ||
1104 SinkCandidate->mayReadFromMemory() || SinkCandidate->isTerminator())
1105 return false;
1106
1107
1108
1109 if (isa(SinkCandidate))
1110 return true;
1111
1112
1113 WorkList.push_back(SinkCandidate);
1114 return true;
1115 };
1116
1118
1119 while (!WorkList.empty()) {
1122 if (!TryToPushSinkCandidate(cast(User)))
1123 return false;
1124 }
1125 }
1126
1127 return true;
1128}
1129
1131 switch (Kind) {
1133 return Instruction::Add;
1135 return Instruction::Mul;
1137 return Instruction::Or;
1139 return Instruction::And;
1141 return Instruction::Xor;
1143 return Instruction::FMul;
1146 return Instruction::FAdd;
1153 return Instruction::ICmp;
1160 return Instruction::FCmp;
1161 default:
1163 }
1164}
1165
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186 unsigned ExpectedUses = 1;
1187 if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp)
1188 ExpectedUses = 2;
1189
1191 for (auto *User : Cur->users()) {
1193 if (isa(UI))
1194 continue;
1195 if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
1196
1197
1198 if (isa(UI))
1199 return UI;
1200 continue;
1201 }
1202 return UI;
1203 }
1204 return nullptr;
1205 };
1206 auto isCorrectOpcode = [&](Instruction *Cur) {
1207 if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
1211 }
1212
1214 return true;
1215
1216 return Cur->getOpcode() == RedOp;
1217 };
1218
1219
1220 unsigned ExtraPhiUses = 0;
1222 if (auto ExitPhi = dyn_cast(LoopExitInstr)) {
1223 if (ExitPhi->getNumIncomingValues() != 2)
1224 return {};
1225
1226 Instruction *Inc0 = dyn_cast(ExitPhi->getIncomingValue(0));
1227 Instruction *Inc1 = dyn_cast(ExitPhi->getIncomingValue(1));
1228
1230 if (Inc0 == Phi)
1231 Chain = Inc1;
1232 else if (Inc1 == Phi)
1233 Chain = Inc0;
1234 else
1235 return {};
1236
1237 RdxInstr = Chain;
1238 ExtraPhiUses = 1;
1239 }
1240
1241
1242
1243
1244
1245 if (!isCorrectOpcode(RdxInstr) || !LoopExitInstr->hasNUses(2))
1246 return {};
1247
1248
1249
1250 if (!Phi->hasNUses(ExpectedUses + ExtraPhiUses))
1251 return {};
1252
1253 Instruction *Cur = getNextInstruction(Phi);
1254
1255
1256
1257 while (Cur != RdxInstr) {
1258 if (!Cur || !isCorrectOpcode(Cur) || !Cur->hasNUses(ExpectedUses))
1259 return {};
1260
1261 ReductionOperations.push_back(Cur);
1262 Cur = getNextInstruction(Cur);
1263 }
1264
1265 ReductionOperations.push_back(Cur);
1266 return ReductionOperations;
1267}
1268
1272 : StartValue(Start), IK(K), Step(Step), InductionBinOp(BOp) {
1273 assert(IK != IK_NoInduction && "Not an induction");
1274
1275
1276
1277 assert(StartValue && "StartValue is null");
1279 "StartValue is not a pointer for pointer induction");
1281 "StartValue is not an integer for integer induction");
1282
1283
1284 assert((!getConstIntStepValue() || !getConstIntStepValue()->isZero()) &&
1285 "Step value is zero");
1286
1288 "StepValue is not an integer");
1289
1291 "StepValue is not FP for FpInduction");
1292 assert((IK != IK_FpInduction ||
1293 (InductionBinOp &&
1294 (InductionBinOp->getOpcode() == Instruction::FAdd ||
1295 InductionBinOp->getOpcode() == Instruction::FSub))) &&
1296 "Binary opcode should be specified for FP induction");
1297
1298 if (Casts) {
1299 for (auto &Inst : *Casts) {
1300 RedundantCasts.push_back(Inst);
1301 }
1302 }
1303}
1304
1306 if (isa(Step))
1307 return dyn_cast(cast(Step)->getValue());
1308 return nullptr;
1309}
1310
1314
1315
1316 assert(Phi->getType()->isFloatingPointTy() && "Unexpected Phi type");
1317
1318 if (TheLoop->getHeader() != Phi->getParent())
1319 return false;
1320
1321
1322
1323 if (Phi->getNumIncomingValues() != 2)
1324 return false;
1325 Value *BEValue = nullptr, *StartValue = nullptr;
1326 if (TheLoop->contains(Phi->getIncomingBlock(0))) {
1327 BEValue = Phi->getIncomingValue(0);
1328 StartValue = Phi->getIncomingValue(1);
1329 } else {
1330 assert(TheLoop->contains(Phi->getIncomingBlock(1)) &&
1331 "Unexpected Phi node in the loop");
1332 BEValue = Phi->getIncomingValue(1);
1333 StartValue = Phi->getIncomingValue(0);
1334 }
1335
1336 BinaryOperator *BOp = dyn_cast(BEValue);
1337 if (!BOp)
1338 return false;
1339
1340 Value *Addend = nullptr;
1341 if (BOp->getOpcode() == Instruction::FAdd) {
1346 } else if (BOp->getOpcode() == Instruction::FSub)
1349
1350 if (!Addend)
1351 return false;
1352
1353
1354 if (auto *I = dyn_cast(Addend))
1356 return false;
1357
1358
1361 return true;
1362}
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1400
1401 assert(CastInsts.empty() && "CastInsts is expected to be empty.");
1402 auto *PN = cast(PhiScev->getValue());
1403 assert(PSE.getSCEV(PN) == AR && "Unexpected phi node SCEV expression");
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414 auto getDef = [&](const Value *Val) -> Value * {
1415 const BinaryOperator *BinOp = dyn_cast(Val);
1416 if (!BinOp)
1417 return nullptr;
1420 Value *Def = nullptr;
1421 if (L->isLoopInvariant(Op0))
1422 Def = Op1;
1423 else if (L->isLoopInvariant(Op1))
1424 Def = Op0;
1425 return Def;
1426 };
1427
1428
1429
1430 BasicBlock *Latch = L->getLoopLatch();
1431 if (!Latch)
1432 return false;
1433 Value *Val = PN->getIncomingValueForBlock(Latch);
1434 if (!Val)
1435 return false;
1436
1437
1438
1439
1440
1441 bool InCastSequence = false;
1442 auto *Inst = dyn_cast(Val);
1443 while (Val != PN) {
1444
1445
1446 if (!Inst || !L->contains(Inst)) {
1447 return false;
1448 }
1449 auto *AddRec = dyn_cast(PSE.getSCEV(Val));
1451 InCastSequence = true;
1452 if (InCastSequence) {
1453
1454
1455 if (!CastInsts.empty())
1456 if (!Inst->hasOneUse())
1457 return false;
1459 }
1460 Val = getDef(Val);
1461 if (!Val)
1462 return false;
1463 Inst = dyn_cast(Val);
1464 }
1465
1466 return InCastSequence;
1467}
1468
1472 Type *PhiTy = Phi->getType();
1473
1474
1475
1476
1477
1480 return false;
1481
1484
1486 const auto *AR = dyn_cast(PhiScev);
1487
1488
1489 if (Assume && !AR)
1491
1492 if (!AR) {
1493 LLVM_DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n");
1494 return false;
1495 }
1496
1497
1498 const auto *SymbolicPhi = dyn_cast(PhiScev);
1499
1500
1501
1502
1503
1504 if (PhiScev != AR && SymbolicPhi) {
1508 }
1509
1511}
1512
1517 Type *PhiTy = Phi->getType();
1518
1520 return false;
1521
1522
1523 const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi);
1524 const SCEVAddRecExpr *AR = dyn_cast(PhiScev);
1525
1526 if (!AR) {
1527 LLVM_DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n");
1528 return false;
1529 }
1530
1531 if (AR->getLoop() != TheLoop) {
1532
1533
1535 dbgs() << "LV: PHI is a recurrence with respect to an outer loop.\n");
1536 return false;
1537 }
1538
1539
1540
1541
1543 && "Invalid Phi node, not present in loop header");
1544
1545 Value *StartValue =
1547
1549 if (!Latch)
1550 return false;
1551
1553
1554
1555 const SCEVConstant *ConstStep = dyn_cast(Step);
1557 return false;
1558
1561 dyn_cast(Phi->getIncomingValueForBlock(Latch));
1563 CastsToIgnore);
1564 return true;
1565 }
1566
1568
1569
1571 return true;
1572}
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static bool getCastsForInductionPHI(PredicatedScalarEvolution &PSE, const SCEVUnknown *PhiScev, const SCEVAddRecExpr *AR, SmallVectorImpl< Instruction * > &CastInsts)
This function is called when we suspect that the update-chain of a phi node (whose symbolic SCEV expr...
static void collectCastInstrs(Loop *TheLoop, Instruction *Exit, Type *RecurrenceType, SmallPtrSetImpl< Instruction * > &Casts, unsigned &MinWidthCastToRecurTy)
Collect cast instructions that can be ignored in the vectorizer's cost model, given a reduction exit ...
static bool checkOrderedReduction(RecurKind Kind, Instruction *ExactFPMathInst, Instruction *Exit, PHINode *Phi)
static Instruction * lookThroughAnd(PHINode *Phi, Type *&RT, SmallPtrSetImpl< Instruction * > &Visited, SmallPtrSetImpl< Instruction * > &CI)
Determines if Phi may have been type-promoted.
static std::pair< Type *, bool > computeRecurrenceType(Instruction *Exit, DemandedBits *DB, AssumptionCache *AC, DominatorTree *DT)
Compute the minimal bit width needed to represent a reduction whose exit instruction is given by Exit...
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
BinaryOps getOpcode() const
This class is the base class for the comparison instructions.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
This is the shared class of boolean and integer constants.
This class represents a range of values.
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Convenience struct for specifying and reasoning about fast-math flags.
bool noSignedZeros() const
void setNoSignedZeros(bool B=true)
void setNoNaNs(bool B=true)
static FastMathFlags getFast()
A struct for saving information about induction variables.
@ IK_FpInduction
Floating point induction variable.
@ IK_PtrInduction
Pointer induction var. Step = C.
@ IK_IntInduction
Integer induction variable. Step = C.
static bool isInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, InductionDescriptor &D, const SCEV *Expr=nullptr, SmallVectorImpl< Instruction * > *CastsToIgnore=nullptr)
Returns true if Phi is an induction in the loop L.
static bool isFPInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, InductionDescriptor &D)
Returns true if Phi is a floating point induction in the loop L.
InductionDescriptor()=default
Default constructor - creates an invalid induction.
ConstantInt * getConstIntStepValue() const
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
BlockT * getHeader() const
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
Represents a single loop in the control flow graph.
bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
bool areAddRecsEqualWithPreds(const SCEVAddRecExpr *AR1, const SCEVAddRecExpr *AR2) const
Check if AR1 and AR2 are equal, while taking into account Equal predicates in Preds.
const SCEVAddRecExpr * getAsAddRec(Value *V)
Attempts to produce an AddRecExpr for V by adding additional SCEV predicates.
const SCEV * getSCEV(Value *V)
Returns the SCEV expression of V, in the context of the current SCEV predicate.
This POD struct holds information about a potential recurrence operation.
RecurKind getRecKind() const
Instruction * getPatternInst() const
bool isRecurrence() const
Instruction * getExactFPMathInst() const
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
static bool isFPMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating-point min/max kind.
static bool isFMulAddIntrinsic(Instruction *I)
Returns true if the instruction is a call to the llvm.fmuladd intrinsic.
static bool isFixedOrderRecurrence(PHINode *Phi, Loop *TheLoop, DominatorTree *DT)
Returns true if Phi is a fixed-order recurrence.
unsigned getOpcode() const
static bool hasMultipleUsesOf(Instruction *I, SmallPtrSetImpl< Instruction * > &Insts, unsigned MaxNumUses)
Returns true if instruction I has multiple uses in Insts.
static bool isReductionPHI(PHINode *Phi, Loop *TheLoop, RecurrenceDescriptor &RedDes, DemandedBits *DB=nullptr, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr, ScalarEvolution *SE=nullptr)
Returns true if Phi is a reduction in TheLoop.
static bool areAllUsesIn(Instruction *I, SmallPtrSetImpl< Instruction * > &Set)
Returns true if all uses of the instruction I is within the Set.
SmallVector< Instruction *, 4 > getReductionOpChain(PHINode *Phi, Loop *L) const
Attempts to find a chain of operations from Phi to LoopExitInst that can be treated as a set of reduc...
static bool isAnyOfRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
static InstDesc isFindLastIVPattern(Loop *TheLoop, PHINode *OrigPhi, Instruction *I, ScalarEvolution &SE)
Returns a struct describing whether the instruction is either a Select(ICmp(A, B),...
static InstDesc isAnyOfPattern(Loop *Loop, PHINode *OrigPhi, Instruction *I, InstDesc &Prev)
Returns a struct describing whether the instruction is either a Select(ICmp(A, B),...
static bool isFindLastIVRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
static InstDesc isConditionalRdxPattern(RecurKind Kind, Instruction *I)
Returns a struct describing if the instruction is a Select(FCmp(X, Y), (Z = X op PHINode),...
RecurKind getRecurrenceKind() const
StoreInst * IntermediateStore
Reductions may store temporary or final result to an invariant address.
static InstDesc isRecurrenceInstr(Loop *L, PHINode *Phi, Instruction *I, RecurKind Kind, InstDesc &Prev, FastMathFlags FuncFMF, ScalarEvolution *SE)
Returns a struct describing if the instruction 'I' can be a recurrence variable of type 'Kind' for a ...
static bool isFloatingPointRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating point kind.
static InstDesc isMinMaxPattern(Instruction *I, RecurKind Kind, const InstDesc &Prev)
Returns a struct describing if the instruction is a llvm.
static bool AddReductionVar(PHINode *Phi, RecurKind Kind, Loop *TheLoop, FastMathFlags FuncFMF, RecurrenceDescriptor &RedDes, DemandedBits *DB=nullptr, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr, ScalarEvolution *SE=nullptr)
Returns true if Phi is a reduction of type Kind and adds it to the RecurrenceDescriptor.
static bool isIntegerRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is an integer kind.
static bool isIntMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is an integer min/max kind.
static bool isMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is any min/max kind.
This node represents a polynomial recurrence on the trip count of the specified loop.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
const Loop * getLoop() const
This class represents a constant integer value.
This means that we are dealing with an entirely unknown SCEV value, and only represent it as its LLVM...
This class represents an analyzed expression in the program.
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
ConstantRange getSignedRange(const SCEV *S)
Determine the signed range for a particular SCEV.
bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
bool isKnownPositive(const SCEV *S)
Test if the given expression is known to be positive.
bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
const SCEV * getUnknown(Value *V)
This class represents the LLVM 'select' instruction.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
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.
Value * getValueOperand()
Value * getPointerOperand()
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
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
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.
iterator_range< user_iterator > users()
bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmin_pred_ty > > m_OrdOrUnordFMin(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point minimum function.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
OneUse_match< T > m_OneUse(const T &SubPattern)
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmax_pred_ty > > m_OrdOrUnordFMax(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point maximum function.
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(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 is an optimization pass for GlobalISel generic memory operations.
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
RecurKind
These are the kinds of recurrences that we support.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ IFindLastIV
FindLast reduction with select(icmp(),x,y) where one of (x,y) is increasing loop induction,...
@ FAnyOf
Any_of reduction with select(fcmp(),x,y) where one of (x,y) is loop invariant, and both x and y are i...
@ Or
Bitwise or logical OR of integers.
@ FMinimum
FP min with llvm.minimum semantics.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ FMax
FP max implemented in terms of select(cmp()).
@ FMaximum
FP max with llvm.maximum semantics.
@ FMulAdd
Sum of float products with llvm.fmuladd(a * b + sum).
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ And
Bitwise or logical AND of integers.
@ FFindLastIV
FindLast reduction with select(fcmp(),x,y) where one of (x,y) is increasing loop induction,...
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ FMin
FP min implemented in terms of select(cmp()).
@ IAnyOf
Any_of reduction with select(icmp(),x,y) where one of (x,y) is loop invariant, and both x and y are i...
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return the number of times the sign bit of the register is replicated into the other bits.
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?