LLVM: lib/Transforms/InstCombine/InstructionCombining.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
102#include
103#include
104#include
105#include
106#include
107#include
108#include
109
110#define DEBUG_TYPE "instcombine"
112#include
113
114using namespace llvm;
116
118 "Number of instruction combining iterations performed");
119STATISTIC(NumOneIteration, "Number of functions with one iteration");
120STATISTIC(NumTwoIterations, "Number of functions with two iterations");
121STATISTIC(NumThreeIterations, "Number of functions with three iterations");
123 "Number of functions with four or more iterations");
124
125STATISTIC(NumCombined , "Number of insts combined");
126STATISTIC(NumConstProp, "Number of constant folds");
127STATISTIC(NumDeadInst , "Number of dead inst eliminated");
128STATISTIC(NumSunkInst , "Number of instructions sunk");
130STATISTIC(NumFactor , "Number of factorizations");
131STATISTIC(NumReassoc , "Number of reassociations");
133 "Controls which instructions are visited");
134
136 cl::desc("Enable code sinking"),
138
140 "instcombine-max-sink-users", cl::init(32),
141 cl::desc("Maximum number of undroppable users for instruction sinking"));
142
145 cl::desc("Maximum array size considered when doing a combine"));
146
147namespace llvm {
149}
150
151
152
153
154
155
156
157
160
161std::optional<Instruction *>
163
164 if (II.getCalledFunction()->isTargetIntrinsic()) {
165 return TTIForTargetIntrinsicsOnly.instCombineIntrinsic(*this, II);
166 }
167 return std::nullopt;
168}
169
172 bool &KnownBitsComputed) {
173
174 if (II.getCalledFunction()->isTargetIntrinsic()) {
175 return TTIForTargetIntrinsicsOnly.simplifyDemandedUseBitsIntrinsic(
176 *this, II, DemandedMask, Known, KnownBitsComputed);
177 }
178 return std::nullopt;
179}
180
183 APInt &PoisonElts2, APInt &PoisonElts3,
185 SimplifyAndSetOp) {
186
187 if (II.getCalledFunction()->isTargetIntrinsic()) {
188 return TTIForTargetIntrinsicsOnly.simplifyDemandedVectorEltsIntrinsic(
189 *this, II, DemandedElts, PoisonElts, PoisonElts2, PoisonElts3,
190 SimplifyAndSetOp);
191 }
192 return std::nullopt;
193}
194
196
197
198
199 return TTIForTargetIntrinsicsOnly.isValidAddrSpaceCast(FromAS, ToAS);
200}
201
202Value *InstCombinerImpl::EmitGEPOffset(GEPOperator *GEP, bool RewriteGEP) {
203 if (!RewriteGEP)
205
208 if (Inst)
209 Builder.SetInsertPoint(Inst);
210
212
213 if (Inst && ->hasAllConstantIndices() &&
214 ->getSourceElementType()->isIntegerTy(8)) {
216 *Inst, Builder.CreateGEP(Builder.getInt8Ty(), GEP->getPointerOperand(),
217 Offset, "", GEP->getNoWrapFlags()));
219 }
221}
222
225 bool RewriteGEPs) {
227 if (Sum)
230 else
232 };
233
234 Value *Sum = nullptr;
235 Value *OneUseSum = nullptr;
236 Value *OneUseBase = nullptr;
238 for (GEPOperator *GEP : reverse(GEPs)) {
240 {
241
242
243 IRBuilderBase::InsertPointGuard Guard(Builder);
245 if (RewriteGEPs && Inst)
246 Builder.SetInsertPoint(Inst);
247
249 if (Offset->getType() != IdxTy)
252 if (GEP->hasOneUse()) {
253
254 OneUseSum = Add(OneUseSum, Offset);
256 if (!OneUseBase)
257 OneUseBase = GEP->getPointerOperand();
258 continue;
259 }
260
261 if (OneUseSum)
263
264
265
266 if (RewriteGEPs && Inst &&
267 !(GEP->getSourceElementType()->isIntegerTy(8) &&
270 *Inst,
272 OneUseBase ? OneUseBase : GEP->getPointerOperand(), Offset, "",
275 }
276 }
277
279 OneUseSum = OneUseBase = nullptr;
281 }
282 if (OneUseSum)
283 Sum = Add(Sum, OneUseSum);
284 if (!Sum)
286 return Sum;
287}
288
289
290
291
292
293
294bool InstCombinerImpl::isDesirableIntType(unsigned BitWidth) const {
296 case 8:
297 case 16:
298 case 32:
299 return true;
300 default:
302 }
303}
304
305
306
307
308
309
310
311
312
313bool InstCombinerImpl::shouldChangeType(unsigned FromWidth,
314 unsigned ToWidth) const {
315 bool FromLegal = FromWidth == 1 || DL.isLegalInteger(FromWidth);
316 bool ToLegal = ToWidth == 1 || DL.isLegalInteger(ToWidth);
317
318
319
320 if (ToWidth < FromWidth && isDesirableIntType(ToWidth))
321 return true;
322
323
324
325 if ((FromLegal || isDesirableIntType(FromWidth)) && !ToLegal)
326 return false;
327
328
329
330 if (!FromLegal && !ToLegal && ToWidth > FromWidth)
331 return false;
332
333 return true;
334}
335
336
337
338
339
340
341bool InstCombinerImpl::shouldChangeType(Type *From, Type *To) const {
342
343
345 return false;
346
349 return shouldChangeType(FromWidth, ToWidth);
350}
351
352
353
354
355
356
359 if (!OBO || !OBO->hasNoSignedWrap())
360 return false;
361
362 const APInt *BVal, *CVal;
364 return false;
365
366
367 bool Overflow = false;
368 switch (I.getOpcode()) {
369 case Instruction::Add:
370 (void)BVal->sadd_ov(*CVal, Overflow);
371 break;
372 case Instruction::Sub:
373 (void)BVal->ssub_ov(*CVal, Overflow);
374 break;
375 case Instruction::Mul:
376 (void)BVal->smul_ov(*CVal, Overflow);
377 break;
378 default:
379
380 return false;
381 }
382 return !Overflow;
383}
384
387 return OBO && OBO->hasNoUnsignedWrap();
388}
389
392 return OBO && OBO->hasNoSignedWrap();
393}
394
395
396
397
400 if (!FPMO) {
401 I.clearSubclassOptionalData();
402 return;
403 }
404
406 I.clearSubclassOptionalData();
407 I.setFastMathFlags(FMF);
408}
409
410
411
412
413
417 if (!Cast || !Cast->hasOneUse())
418 return false;
419
420
421 auto CastOpcode = Cast->getOpcode();
422 if (CastOpcode != Instruction::ZExt)
423 return false;
424
425
427 return false;
428
429 auto AssocOpcode = BinOp1->getOpcode();
431 if (!BinOp2 || !BinOp2->hasOneUse() || BinOp2->getOpcode() != AssocOpcode)
432 return false;
433
437 return false;
438
439
440
441
442
443
444
448 if (!CastC2)
449 return false;
451 if (!FoldedC)
452 return false;
453
457 Cast->dropPoisonGeneratingFlags();
458 return true;
459}
460
461
462
463Value *InstCombinerImpl::simplifyIntToPtrRoundTripCast(Value *Val) {
465 if (IntToPtr && DL.getTypeSizeInBits(IntToPtr->getDestTy()) ==
466 DL.getTypeSizeInBits(IntToPtr->getSrcTy())) {
468 Type *CastTy = IntToPtr->getDestTy();
469 if (PtrToInt &&
471 PtrToInt->getSrcTy()->getPointerAddressSpace() &&
472 DL.getTypeSizeInBits(PtrToInt->getSrcTy()) ==
473 DL.getTypeSizeInBits(PtrToInt->getDestTy()))
474 return PtrToInt->getOperand(0);
475 }
476 return nullptr;
477}
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
502
503 do {
504
505
506
507 if (I.isCommutative() && getComplexity(I.getOperand(0)) <
510
511 if (I.isCommutative()) {
512 if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) {
516 }
517 }
518
521
522 if (I.isAssociative()) {
523
524 if (Op0 && Op0->getOpcode() == Opcode) {
527 Value *C = I.getOperand(1);
528
529
531
536
537
538
539
541
542
543
544 if (IsNUW)
545 I.setHasNoUnsignedWrap(true);
546
547 if (IsNSW)
548 I.setHasNoSignedWrap(true);
549
551 ++NumReassoc;
552 continue;
553 }
554 }
555
556
557 if (Op1 && Op1->getOpcode() == Opcode) {
558 Value *A = I.getOperand(0);
561
562
564
567
568
571 ++NumReassoc;
572 continue;
573 }
574 }
575 }
576
577 if (I.isAssociative() && I.isCommutative()) {
580 ++NumReassoc;
581 continue;
582 }
583
584
585 if (Op0 && Op0->getOpcode() == Opcode) {
588 Value *C = I.getOperand(1);
589
590
592
595
596
599 ++NumReassoc;
600 continue;
601 }
602 }
603
604
605 if (Op1 && Op1->getOpcode() == Opcode) {
606 Value *A = I.getOperand(0);
609
610
612
615
616
619 ++NumReassoc;
620 continue;
621 }
622 }
623
624
625
628 if (Op0 && Op1 &&
636 BinaryOperator *NewBO = (IsNUW && Opcode == Instruction::Add) ?
639
645 }
650
651
653 if (IsNUW)
654 I.setHasNoUnsignedWrap(true);
655
657 continue;
658 }
659 }
660
661
663 } while (true);
664}
665
666
667
670
671
672 if (LOp == Instruction::And)
673 return ROp == Instruction::Or || ROp == Instruction::Xor;
674
675
676 if (LOp == Instruction::Or)
677 return ROp == Instruction::And;
678
679
680
681 if (LOp == Instruction::Mul)
682 return ROp == Instruction::Add || ROp == Instruction::Sub;
683
684 return false;
685}
686
687
688
693
694
696
697
698
699
700}
701
702
703
706 return nullptr;
707
709}
710
711
712
713
714
715
719 assert(Op && "Expected a binary operator");
722 if (TopOpcode == Instruction::Add || TopOpcode == Instruction::Sub) {
725
727 Instruction::Shl, ConstantInt::get(Op->getType(), 1), C);
728 assert(RHS && "Constant folding of immediate constants failed");
729 return Instruction::Mul;
730 }
731
732 }
734 if (OtherOp && OtherOp->getOpcode() == Instruction::AShr &&
736
737 return Instruction::AShr;
738 }
739 }
740 return Op->getOpcode();
741}
742
743
744
749 assert(A && B && C && D && "All values must be provided");
750
751 Value *V = nullptr;
752 Value *RetVal = nullptr;
753 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
755
756
758
759
761
762
763 if (A == C || (InnerCommutative && A == D)) {
766
767
769
770
771
772 if (!V && (LHS->hasOneUse() || RHS->hasOneUse()))
773 V = Builder.CreateBinOp(TopLevelOpcode, B, D, RHS->getName());
774 if (V)
775 RetVal = Builder.CreateBinOp(InnerOpcode, A, V);
776 }
777 }
778
779
781
782
783 if (B == D || (InnerCommutative && B == C)) {
786
787
789
790
791
792 if (!V && (LHS->hasOneUse() || RHS->hasOneUse()))
793 V = Builder.CreateBinOp(TopLevelOpcode, A, C, LHS->getName());
794 if (V)
795 RetVal = Builder.CreateBinOp(InnerOpcode, V, B);
796 }
797 }
798
799 if (!RetVal)
800 return nullptr;
801
802 ++NumFactor;
804
805
807 bool HasNSW = false;
808 bool HasNUW = false;
810 HasNSW = I.hasNoSignedWrap();
811 HasNUW = I.hasNoUnsignedWrap();
812 }
814 HasNSW &= LOBO->hasNoSignedWrap();
815 HasNUW &= LOBO->hasNoUnsignedWrap();
816 }
817
819 HasNSW &= ROBO->hasNoSignedWrap();
820 HasNUW &= ROBO->hasNoUnsignedWrap();
821 }
822
823 if (TopLevelOpcode == Instruction::Add && InnerOpcode == Instruction::Mul) {
824
825
826
827
828
829
830
831 const APInt *CInt;
834
835
837 }
838 }
839 return RetVal;
840}
841
842
843
844
845
846
847
848
849
851 unsigned Opc = I->getOpcode();
852 unsigned ConstIdx = 1;
853 switch (Opc) {
854 default:
855 return nullptr;
856
857
858
859 case Instruction::Sub:
860 ConstIdx = 0;
861 break;
862 case Instruction::ICmp:
863
864
865
867 return nullptr;
868 break;
869 case Instruction::Or:
871 return nullptr;
872 [[fallthrough]];
873 case Instruction::Add:
874 break;
875 }
876
878
879 if ((I->getOperand(1 - ConstIdx),
881 return nullptr;
882
884
886 return nullptr;
887
889 Constant *BitWidthC = ConstantInt::get(Ty, Ty->getScalarSizeInBits());
890
891
895 if (!Cmp || !Cmp->isZeroValue())
896 return nullptr;
897 }
898
899
900 bool Consumes = false;
902 return nullptr;
904 assert(NotOp != nullptr &&
905 "Desync between isFreeToInvert and getFreelyInverted");
906
907 Value *CtpopOfNotOp = Builder.CreateIntrinsic(Ty, Intrinsic::ctpop, NotOp);
908
909 Value *R = nullptr;
910
911
912
913 switch (Opc) {
914 case Instruction::Sub:
916 break;
917 case Instruction::Or:
918 case Instruction::Add:
920 break;
921 case Instruction::ICmp:
924 break;
925 default:
927 }
928 assert(R != nullptr);
930}
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
957 auto IsValidBinOpc = [](unsigned Opc) {
958 switch (Opc) {
959 default:
960 return false;
961 case Instruction::And:
962 case Instruction::Or:
963 case Instruction::Xor:
964 case Instruction::Add:
965
966
967 return true;
968 }
969 };
970
971
972
973 auto IsCompletelyDistributable = [](unsigned BinOpc1, unsigned BinOpc2,
974 unsigned ShOpc) {
975 assert(ShOpc != Instruction::AShr);
976 return (BinOpc1 != Instruction::Add && BinOpc2 != Instruction::Add) ||
977 ShOpc == Instruction::Shl;
978 };
979
980 auto GetInvShift = [](unsigned ShOpc) {
981 assert(ShOpc != Instruction::AShr);
982 return ShOpc == Instruction::LShr ? Instruction::Shl : Instruction::LShr;
983 };
984
985 auto CanDistributeBinops = [&](unsigned BinOpc1, unsigned BinOpc2,
986 unsigned ShOpc, Constant *CMask,
988
989 if (BinOpc1 == Instruction::And)
990 return true;
991
992
993
994 if (!IsCompletelyDistributable(BinOpc1, BinOpc2, ShOpc))
995 return false;
996
997
998
999
1000 if (BinOpc2 == Instruction::And)
1001 return true;
1002
1003
1004
1008 CMask;
1009 };
1010
1011 auto MatchBinOp = [&](unsigned ShOpnum) -> Instruction * {
1013 Value *X, *Y, *ShiftedX, *Mask, *Shift;
1014 if ((I.getOperand(ShOpnum),
1016 return nullptr;
1017 if ((I.getOperand(1 - ShOpnum),
1022 return nullptr;
1023
1026 if (!IY || !IX)
1027 return nullptr;
1028
1029
1030 unsigned ShOpc = IY->getOpcode();
1031 if (ShOpc != IX->getOpcode())
1032 return nullptr;
1033
1034
1036 if (!BO2)
1037 return nullptr;
1038
1039 unsigned BinOpc = BO2->getOpcode();
1040
1041 if (!IsValidBinOpc(I.getOpcode()) || !IsValidBinOpc(BinOpc))
1042 return nullptr;
1043
1044 if (ShOpc == Instruction::AShr) {
1046 BinOpc == Instruction::Xor && match(Mask, m_AllOnes())) {
1048 Value *NewBinOp = Builder.CreateBinOp(I.getOpcode(), Y, NotX);
1051 }
1052
1053 return nullptr;
1054 }
1055
1056
1057
1058 if (BinOpc == I.getOpcode() &&
1059 IsCompletelyDistributable(I.getOpcode(), BinOpc, ShOpc)) {
1060 Value *NewBinOp2 = Builder.CreateBinOp(I.getOpcode(), X, Y);
1064 }
1065
1066
1067
1069 return nullptr;
1071 return nullptr;
1072
1073
1074 if (!CanDistributeBinops(I.getOpcode(), BinOpc, ShOpc, CMask, CShift))
1075 return nullptr;
1076
1081 Value *NewBinOp1 = Builder.CreateBinOp(I.getOpcode(), Y, NewBinOp2);
1083 NewBinOp1, CShift);
1084 };
1085
1087 return R;
1088 return MatchBinOp(1);
1089}
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1102
1103
1105 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
1106 Value *A, *CondVal, *TrueVal, *FalseVal;
1108
1109 auto MatchSelectAndCast = [&](Value *CastOp, Value *SelectOp) {
1111 A->getType()->getScalarSizeInBits() == 1 &&
1114 };
1115
1116
1117
1118 if (MatchSelectAndCast(LHS, RHS))
1119 CastOp = LHS;
1120 else if (MatchSelectAndCast(RHS, LHS))
1121 CastOp = RHS;
1122 else
1123 return nullptr;
1124
1125 auto NewFoldedConst = [&](bool IsTrueArm, Value *V) {
1126 bool IsCastOpRHS = (CastOp == RHS);
1129
1130 if (IsTrueArm) {
1132 } else if (IsZExt) {
1133 unsigned BitWidth = V->getType()->getScalarSizeInBits();
1135 } else {
1137 }
1138
1139 return IsCastOpRHS ? Builder.CreateBinOp(Opc, V, C)
1141 };
1142
1143
1144
1145 if (CondVal == A) {
1146 Value *NewTrueVal = NewFoldedConst(false, TrueVal);
1148 NewFoldedConst(true, FalseVal));
1149 }
1150
1152 Value *NewTrueVal = NewFoldedConst(true, TrueVal);
1154 NewFoldedConst(false, FalseVal));
1155 }
1156
1157 return nullptr;
1158}
1159
1161 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
1167
1168 if (Op0)
1170 if (Op1)
1172
1173
1174
1175 if (Op0 && Op1 && LHSOpcode == RHSOpcode)
1177 return V;
1178
1179
1180
1181 if (Op0)
1185 return V;
1186
1187
1188
1189 if (Op1)
1193 return V;
1194
1195 return nullptr;
1196}
1197
1198
1199
1200
1201
1202
1204 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
1208
1209
1211 return R;
1212
1213
1215
1216
1219
1220
1221 auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();
1224
1225
1226 if (L && R) {
1227
1228 ++NumExpand;
1229 C = Builder.CreateBinOp(InnerOpcode, L, R);
1231 return C;
1232 }
1233
1234
1236
1237 ++NumExpand;
1238 C = Builder.CreateBinOp(TopLevelOpcode, B, C);
1240 return C;
1241 }
1242
1243
1245
1246 ++NumExpand;
1247 C = Builder.CreateBinOp(TopLevelOpcode, A, C);
1249 return C;
1250 }
1251 }
1252
1254
1255
1258
1259
1260 auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();
1263
1264
1265 if (L && R) {
1266
1267 ++NumExpand;
1268 A = Builder.CreateBinOp(InnerOpcode, L, R);
1270 return A;
1271 }
1272
1273
1275
1276 ++NumExpand;
1277 A = Builder.CreateBinOp(TopLevelOpcode, A, C);
1279 return A;
1280 }
1281
1282
1284
1285 ++NumExpand;
1286 A = Builder.CreateBinOp(TopLevelOpcode, A, B);
1288 return A;
1289 }
1290 }
1291
1293}
1294
1295static std::optional<std::pair<Value *, Value *>>
1297 if (LHS->getParent() != RHS->getParent())
1298 return std::nullopt;
1299
1300 if (LHS->getNumIncomingValues() < 2)
1301 return std::nullopt;
1302
1303 if ((LHS->blocks(), RHS->blocks()))
1304 return std::nullopt;
1305
1306 Value *L0 = LHS->getIncomingValue(0);
1307 Value *R0 = RHS->getIncomingValue(0);
1308
1309 for (unsigned I = 1, E = LHS->getNumIncomingValues(); I != E; ++I) {
1310 Value *L1 = LHS->getIncomingValue(I);
1311 Value *R1 = RHS->getIncomingValue(I);
1312
1313 if ((L0 == L1 && R0 == R1) || (L0 == R1 && R0 == L1))
1314 continue;
1315
1316 return std::nullopt;
1317 }
1318
1319 return std::optional(std::pair(L0, R0));
1320}
1321
1322std::optional<std::pair<Value *, Value *>>
1323InstCombinerImpl::matchSymmetricPair(Value *LHS, Value *RHS) {
1326 if (!LHSInst || !RHSInst || LHSInst->getOpcode() != RHSInst->getOpcode())
1327 return std::nullopt;
1329 case Instruction::PHI:
1331 case Instruction::Select: {
1337 return std::pair(TrueVal, FalseVal);
1338 return std::nullopt;
1339 }
1340 case Instruction::Call: {
1341
1344 if (LHSMinMax && RHSMinMax &&
1347 ((LHSMinMax->getLHS() == RHSMinMax->getLHS() &&
1348 LHSMinMax->getRHS() == RHSMinMax->getRHS()) ||
1349 (LHSMinMax->getLHS() == RHSMinMax->getRHS() &&
1350 LHSMinMax->getRHS() == RHSMinMax->getLHS())))
1351 return std::pair(LHSMinMax->getLHS(), LHSMinMax->getRHS());
1352 return std::nullopt;
1353 }
1354 default:
1355 return std::nullopt;
1356 }
1357}
1358
1365 if (!LHSIsSelect && !RHSIsSelect)
1366 return nullptr;
1367
1369 ? nullptr
1371
1375 FMF = I.getFastMathFlags();
1376 Builder.setFastMathFlags(FMF);
1377 }
1378
1381
1382 Value *Cond, *True = nullptr, *False = nullptr;
1383
1384
1385
1386
1387
1389
1390 if (Opcode != Instruction::Add || (!True && !False) || (True && False))
1391 return nullptr;
1396 }
1400 }
1401 return nullptr;
1402 };
1403
1404 if (LHSIsSelect && RHSIsSelect && A == D) {
1405
1409
1410 if (LHS->hasOneUse() && RHS->hasOneUse()) {
1411 if (False && !True)
1412 True = Builder.CreateBinOp(Opcode, B, E);
1413 else if (True && !False)
1414 False = Builder.CreateBinOp(Opcode, C, F);
1415 }
1416 } else if (LHSIsSelect && LHS->hasOneUse()) {
1417
1421 if (Value *NewSel = foldAddNegate(B, C, RHS))
1422 return NewSel;
1423 } else if (RHSIsSelect && RHS->hasOneUse()) {
1424
1428 if (Value *NewSel = foldAddNegate(E, F, LHS))
1429 return NewSel;
1430 }
1431
1432 if (!True || !False)
1433 return nullptr;
1434
1435 Value *NewSI = Builder.CreateSelect(Cond, True, False, I.getName(), SI);
1437 return NewSI;
1438}
1439
1440
1441
1445 if (U == IgnoredUser)
1446 continue;
1448 case Instruction::Select: {
1450 SI->swapValues();
1451 SI->swapProfMetadata();
1452 break;
1453 }
1454 case Instruction::Br: {
1457 if (BPI)
1458 BPI->swapSuccEdgesProbabilities(BI->getParent());
1459 break;
1460 }
1461 case Instruction::Xor:
1463
1465 break;
1466 default:
1468 "canFreelyInvertAllUsersOf() ?");
1469 }
1470 }
1471
1472
1475
1478 for (unsigned Idx = 0, End = DbgVal->getNumVariableLocationOps();
1479 Idx != End; ++Idx)
1480 if (DbgVal->getVariableLocationOp(Idx) == I)
1481 DbgVal->setExpression(
1483 }
1484}
1485
1486
1487
1488Value *InstCombinerImpl::dyn_castNegVal(Value *V) const {
1491 return NegV;
1492
1493
1496
1498 if (C->getType()->getElementType()->isIntegerTy())
1500
1502 for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {
1504 if (!Elt)
1505 return nullptr;
1506
1508 continue;
1509
1511 return nullptr;
1512 }
1514 }
1515
1516
1518 if (CV->getType()->isVectorTy() &&
1519 CV->getType()->getScalarType()->isIntegerTy() && CV->getSplatValue())
1521
1522 return nullptr;
1523}
1524
1525
1526
1527
1528
1529
1530
1531
1532Instruction *InstCombinerImpl::foldFBinOpOfIntCastsFromSign(
1533 BinaryOperator &BO, bool OpsFromSigned, std::array<Value *, 2> IntOps,
1535
1537 Type *IntTy = IntOps[0]->getType();
1538
1540
1541
1542 unsigned MaxRepresentableBits =
1544
1545
1546
1547 unsigned NumUsedLeadingBits[2] = {IntSz, IntSz};
1548
1549
1550
1551 auto IsNonZero = [&](unsigned OpNo) -> bool {
1552 if (OpsKnown[OpNo].hasKnownBits() &&
1553 OpsKnown[OpNo].getKnownBits(SQ).isNonZero())
1554 return true;
1556 };
1557
1558 auto IsNonNeg = [&](unsigned OpNo) -> bool {
1559
1560
1561
1562 return OpsKnown[OpNo].getKnownBits(SQ).isNonNegative();
1563 };
1564
1565
1566 auto IsValidPromotion = [&](unsigned OpNo) -> bool {
1567
1569 !IsNonNeg(OpNo))
1570 return false;
1571
1572
1573
1574
1575
1576
1577 if (MaxRepresentableBits < IntSz) {
1578
1579
1580
1581
1582 if (OpsFromSigned)
1583 NumUsedLeadingBits[OpNo] = IntSz - ComputeNumSignBits(IntOps[OpNo]);
1584
1585
1586 else {
1587 NumUsedLeadingBits[OpNo] =
1588 IntSz - OpsKnown[OpNo].getKnownBits(SQ).countMinLeadingZeros();
1589 }
1590 }
1591
1592
1593
1594
1595
1596 if (MaxRepresentableBits < NumUsedLeadingBits[OpNo])
1597 return false;
1598
1599 return !OpsFromSigned || BO.getOpcode() != Instruction::FMul ||
1600 IsNonZero(OpNo);
1601 };
1602
1603
1604 if (Op1FpC != nullptr) {
1605
1606 if (OpsFromSigned && BO.getOpcode() == Instruction::FMul &&
1608 return nullptr;
1609
1611 OpsFromSigned ? Instruction::FPToSI : Instruction::FPToUI, Op1FpC,
1612 IntTy, DL);
1613 if (Op1IntC == nullptr)
1614 return nullptr;
1616 : Instruction::UIToFP,
1617 Op1IntC, FPTy, DL) != Op1FpC)
1618 return nullptr;
1619
1620
1621 IntOps[1] = Op1IntC;
1622 }
1623
1624
1625 if (IntTy != IntOps[1]->getType())
1626 return nullptr;
1627
1628 if (Op1FpC == nullptr) {
1629 if (!IsValidPromotion(1))
1630 return nullptr;
1631 }
1632 if (!IsValidPromotion(0))
1633 return nullptr;
1634
1635
1637
1638 bool NeedsOverflowCheck = true;
1639
1640
1641 unsigned OverflowMaxOutputBits = OpsFromSigned ? 2 : 1;
1642 unsigned OverflowMaxCurBits =
1643 std::max(NumUsedLeadingBits[0], NumUsedLeadingBits[1]);
1644 bool OutputSigned = OpsFromSigned;
1646 case Instruction::FAdd:
1647 IntOpc = Instruction::Add;
1648 OverflowMaxOutputBits += OverflowMaxCurBits;
1649 break;
1650 case Instruction::FSub:
1651 IntOpc = Instruction::Sub;
1652 OverflowMaxOutputBits += OverflowMaxCurBits;
1653 break;
1654 case Instruction::FMul:
1655 IntOpc = Instruction::Mul;
1656 OverflowMaxOutputBits += OverflowMaxCurBits * 2;
1657 break;
1658 default:
1660 }
1661
1662 if (OverflowMaxOutputBits < IntSz) {
1663 NeedsOverflowCheck = false;
1664
1665
1666 if (IntOpc == Instruction::Sub)
1667 OutputSigned = true;
1668 }
1669
1670
1671
1672
1673 if (NeedsOverflowCheck &&
1674 !willNotOverflow(IntOpc, IntOps[0], IntOps[1], BO, OutputSigned))
1675 return nullptr;
1676
1677 Value *IntBinOp = Builder.CreateBinOp(IntOpc, IntOps[0], IntOps[1]);
1679 IntBO->setHasNoSignedWrap(OutputSigned);
1680 IntBO->setHasNoUnsignedWrap(!OutputSigned);
1681 }
1682 if (OutputSigned)
1683 return new SIToFPInst(IntBinOp, FPTy);
1684 return new UIToFPInst(IntBinOp, FPTy);
1685}
1686
1687
1688
1689
1690
1691
1693
1694
1696 return nullptr;
1697
1698 std::array<Value *, 2> IntOps = {nullptr, nullptr};
1700
1701
1702
1705 return nullptr;
1706
1710 return nullptr;
1711
1712
1714
1715
1716
1717
1718 if (Instruction *R = foldFBinOpOfIntCastsFromSign(BO, false,
1719 IntOps, Op1FpC, OpsKnown))
1720 return R;
1721 return foldFBinOpOfIntCastsFromSign(BO, true, IntOps,
1722 Op1FpC, OpsKnown);
1723}
1724
1725
1726
1727
1729
1730
1731
1737 ->getType()->isIntOrIntVectorTy(1))
1738 return nullptr;
1739
1740
1745 return createSelectInstWithUnknownProfile(X, TVal, FVal);
1746}
1747
1749 bool IsTrueArm) {
1751 for (Value *Op : I.operands()) {
1752 Value *V = nullptr;
1754 V = IsTrueArm ? SI->getTrueValue() : SI->getFalseValue();
1755 } else if (match(SI->getCondition(),
1760
1762 V = IsTrueArm ? ConstantInt::get(Op->getType(), 1)
1764 } else {
1765 V = Op;
1766 }
1767 Ops.push_back(V);
1768 }
1769
1771}
1772
1781
1783 bool FoldWithMultiUse,
1784 bool SimplifyBothArms) {
1785
1786 if (->hasOneUse() && !FoldWithMultiUse)
1787 return nullptr;
1788
1789 Value *TV = SI->getTrueValue();
1790 Value *FV = SI->getFalseValue();
1791
1792
1793 if (SI->getType()->isIntOrIntVectorTy(1))
1794 return nullptr;
1795
1796
1797
1799 for (Value *IntrinOp : Op.operands())
1801 for (Value *PhiOp : PN->operands())
1802 if (PhiOp == &Op)
1803 return nullptr;
1804
1805
1806
1807
1808
1809
1810
1811
1813 if (CI->hasOneUse()) {
1814 Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1);
1815 if (((TV == Op0 && FV == Op1) || (FV == Op0 && TV == Op1)) &&
1816 !CI->isCommutative())
1817 return nullptr;
1818 }
1819 }
1820
1821
1825 if (!NewTV && !NewFV)
1826 return nullptr;
1827
1828 if (SimplifyBothArms && !(NewTV && NewFV))
1829 return nullptr;
1830
1831
1832 if (!NewTV)
1834 if (!NewFV)
1837}
1838
1843
1844
1846 for (Value *Op : I.operands()) {
1847 if (Op == PN)
1848 Ops.push_back(InValue);
1849 else
1850 Ops.push_back(Op->DoPHITranslation(PN->getParent(), InBB));
1851 }
1852
1853
1854
1855
1856
1860 return NewVal;
1861
1862
1863
1866 if (TerminatorBI && TerminatorBI->isConditional() &&
1871 DL, LHSIsTrue);
1872 if (ImpliedCond)
1874 }
1875
1876 return nullptr;
1877}
1878
1880 bool AllowMultipleUses) {
1882 if (NumPHIValues == 0)
1883 return nullptr;
1884
1885
1886
1887
1889 bool IdenticalUsers = false;
1890 if (!AllowMultipleUses && !OneUse) {
1891
1894 if (UI != &I && .isIdenticalTo(UI))
1895 return nullptr;
1896 }
1897
1898 IdenticalUsers = true;
1899 }
1900
1901
1902 for (Value *Op : I.operands()) {
1903 if (Op == PN)
1904 continue;
1905
1906
1908 if ()
1909 continue;
1910
1911
1913 if (I->getParent() == PN->getParent())
1914 continue;
1915
1916
1918 continue;
1919
1920
1921 return nullptr;
1922 }
1923
1924
1925
1928 bool SeenNonSimplifiedInVal = false;
1929 for (unsigned i = 0; i != NumPHIValues; ++i) {
1932
1935 continue;
1936 }
1937
1938
1939
1940 auto WillFold = [&]() {
1942 return false;
1943
1944
1945 const APInt *Ignored;
1948 return true;
1949
1950
1952 cast(InVal)->getSrcTy()->isIntOrIntVectorTy(1) &&
1955 return true;
1956
1957 return false;
1958 };
1959
1960 if (WillFold()) {
1961 OpsToMoveUseToIncomingBB.push_back(i);
1962 NewPhiValues.push_back(nullptr);
1963 continue;
1964 }
1965
1966 if (!OneUse && !IdenticalUsers)
1967 return nullptr;
1968
1969 if (SeenNonSimplifiedInVal)
1970 return nullptr;
1971 SeenNonSimplifiedInVal = true;
1972
1973
1974
1975
1976
1977
1979 if (!BI || !BI->isUnconditional() || .isReachableFromEntry(InBB))
1980 return nullptr;
1981
1982 NewPhiValues.push_back(nullptr);
1983 OpsToMoveUseToIncomingBB.push_back(i);
1984
1985
1986
1987
1989 return nullptr;
1990 }
1991
1992
1993
1995 for (auto OpIndex : OpsToMoveUseToIncomingBB) {
1998
2000 if (!Clone) {
2001 Clone = I.clone();
2003 if (U == PN)
2004 U = Op;
2005 else
2006 U = U->DoPHITranslation(PN->getParent(), OpBB);
2007 }
2009 Clones.insert({OpBB, Clone});
2010
2012 }
2013
2014 NewPhiValues[OpIndex] = Clone;
2015 }
2016
2017
2022
2023 for (unsigned i = 0; i != NumPHIValues; ++i)
2025
2026 if (IdenticalUsers) {
2027
2032 continue;
2034 }
2038 }
2039 OneUse = true;
2040 }
2041
2042 if (OneUse) {
2044 }
2046}
2047
2050 return nullptr;
2051
2052
2056 if (!BO0 || !BO1 || !BO0->hasNUses(2) || !BO1->hasNUses(2) ||
2057 BO0->getOpcode() != Opc || BO1->getOpcode() != Opc ||
2058 !BO0->isAssociative() || !BO1->isAssociative() ||
2059 BO0->getParent() != BO1->getParent())
2060 return nullptr;
2061
2062 assert(BO.isCommutative() && BO0->isCommutative() && BO1->isCommutative() &&
2063 "Expected commutative instructions!");
2064
2065
2067 Value *Start0, *Step0, *Start1, *Step1;
2071 return nullptr;
2072
2074 "Expected PHIs with two incoming values!");
2075
2076
2081 if (!Init0 || !Init1 || !C0 || !C1)
2082 return nullptr;
2083
2084
2087 if ( ||
)
2088 return nullptr;
2089
2090
2092 "reduced.phi");
2093
2094
2096 if (Opc == Instruction::FAdd || Opc == Instruction::FMul) {
2097
2098 FastMathFlags Intersect = BO0->getFastMathFlags() &
2100 NewBO->setFastMathFlags(Intersect);
2101 } else {
2104 Flags.AllKnownNonZero = false;
2105 Flags.mergeFlags(*BO0);
2106 Flags.mergeFlags(*BO1);
2107 Flags.mergeFlags(BO);
2108 Flags.applyFlags(*NewBO);
2109 }
2110 NewBO->takeName(&BO);
2111
2115 if (V == Init0) {
2120 "Invalid incoming block!");
2121 NewPN->addIncoming(Init, BB);
2122 } else if (V == BO0) {
2127 "Invalid incoming block!");
2128 NewPN->addIncoming(NewBO, BB);
2129 } else
2131 }
2132
2133 LLVM_DEBUG(dbgs() << " Combined " << *PN0 << "\n " << *BO0
2134 << "\n with " << *PN1 << "\n " << *BO1
2135 << '\n');
2136
2137
2140
2147
2149}
2150
2152
2154 return NewBO;
2155
2156
2157
2158
2161 if (!Phi0 || !Phi1 || !Phi0->hasOneUse() || !Phi1->hasOneUse() ||
2162 Phi0->getNumOperands() != Phi1->getNumOperands())
2163 return nullptr;
2164
2165
2166 if (BO.getParent() != Phi0->getParent() ||
2167 BO.getParent() != Phi1->getParent())
2168 return nullptr;
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2180 false);
2181 if (C) {
2183 auto CanFoldIncomingValuePair = [&](std::tuple<Use &, Use &> T) {
2184 auto &Phi0Use = std::get<0>(T);
2185 auto &Phi1Use = std::get<1>(T);
2186 if (Phi0->getIncomingBlock(Phi0Use) != Phi1->getIncomingBlock(Phi1Use))
2187 return false;
2188 Value *Phi0UseV = Phi0Use.get();
2189 Value *Phi1UseV = Phi1Use.get();
2190 if (Phi0UseV == C)
2191 NewIncomingValues.push_back(Phi1UseV);
2192 else if (Phi1UseV == C)
2193 NewIncomingValues.push_back(Phi0UseV);
2194 else
2195 return false;
2196 return true;
2197 };
2198
2199 if (all_of(zip(Phi0->operands(), Phi1->operands()),
2200 CanFoldIncomingValuePair)) {
2202 PHINode::Create(Phi0->getType(), Phi0->getNumOperands());
2203 assert(NewIncomingValues.size() == Phi0->getNumOperands() &&
2204 "The number of collected incoming values should equal the number "
2205 "of the original PHINode operands!");
2206 for (unsigned I = 0; I < Phi0->getNumOperands(); I++)
2207 NewPhi->addIncoming(NewIncomingValues[I], Phi0->getIncomingBlock(I));
2208 return NewPhi;
2209 }
2210 }
2211
2212 if (Phi0->getNumOperands() != 2 || Phi1->getNumOperands() != 2)
2213 return nullptr;
2214
2215
2219 ConstBB = Phi0->getIncomingBlock(0);
2220 OtherBB = Phi0->getIncomingBlock(1);
2222 ConstBB = Phi0->getIncomingBlock(1);
2223 OtherBB = Phi0->getIncomingBlock(0);
2224 } else {
2225 return nullptr;
2226 }
2227 if ((Phi1->getIncomingValueForBlock(ConstBB), m_ImmConstant(C1)))
2228 return nullptr;
2229
2230
2231
2232
2234 if (!PredBlockBranch || PredBlockBranch->isConditional() ||
2235 .isReachableFromEntry(OtherBB))
2236 return nullptr;
2237
2238
2239
2240
2241 for (auto BBIter = BO.getParent()->begin(); &*BBIter != &BO; ++BBIter)
2243 return nullptr;
2244
2245
2247 if (!NewC)
2248 return nullptr;
2249
2250
2251
2252 Builder.SetInsertPoint(PredBlockBranch);
2254 Phi0->getIncomingValueForBlock(OtherBB),
2255 Phi1->getIncomingValueForBlock(OtherBB));
2257 NotFoldedNewBO->copyIRFlags(&BO);
2258
2259
2263 return NewPhi;
2264}
2265
2267 bool IsOtherParamConst = isa(I.getOperand(1));
2268
2272 return NewSel;
2275 return NewPhi;
2276 }
2277 return nullptr;
2278}
2279
2281
2282
2283
2284 if (GEP.hasAllZeroIndices() && !Src.hasAllZeroIndices() &&
2285 !Src.hasOneUse())
2286 return false;
2287 return true;
2288}
2289
2290
2291
2292
2293
2294
2295
2301 return nullptr;
2303 }
2304
2307 return nullptr;
2308
2313 for (unsigned I = 0; I < NumElts; ++I) {
2314 Constant *CElt = C->getAggregateElement(I);
2315 if (ShMask[I] >= 0) {
2316 assert(ShMask[I] < (int)NumElts && "Not expecting narrowing shuffle");
2317 Constant *NewCElt = NewVecC[ShMask[I]];
2318
2319
2320
2321
2322
2323
2324 if (!CElt || ((NewCElt) && NewCElt != CElt) ||
2325 I >= NewCNumElts)
2326 return nullptr;
2327 NewVecC[ShMask[I]] = CElt;
2328 }
2329 }
2331}
2332
2333
2340 if (!SplatLHS)
2343}
2344
2347 return nullptr;
2348
2355
2356 auto foldConstantsThroughSubVectorInsertSplat =
2357 [&](Value *MaybeSubVector, Value *MaybeSplat,
2362 (MaybeSubVector,
2365 return nullptr;
2366 SubVector =
2369 if (!SubVector || !Dest)
2370 return nullptr;
2371 auto *InsertVector =
2372 Builder.CreateInsertVector(Dest->getType(), Dest, SubVector, Idx);
2374 };
2375
2376
2377
2378
2379
2380 if (Instruction *Folded = foldConstantsThroughSubVectorInsertSplat(
2381 LHS, RHS, false))
2382 return Folded;
2383 if (Instruction *Folded = foldConstantsThroughSubVectorInsertSplat(
2384 RHS, LHS, true))
2385 return Folded;
2386
2387
2388
2389
2390 Value *L0, *L1, *R0, *R1;
2394 LHS->hasOneUse() && RHS->hasOneUse() &&
2397
2398
2399
2400
2401
2402 Value *NewBO0 = Builder.CreateBinOp(Opcode, L0, R0);
2405 Value *NewBO1 = Builder.CreateBinOp(Opcode, L1, R1);
2409 }
2410
2411 auto createBinOpReverse = [&](Value *X, Value *Y) {
2417 M, Intrinsic::vector_reverse, V->getType());
2419 };
2420
2421
2422
2423
2426
2428 (LHS->hasOneUse() || RHS->hasOneUse() ||
2429 (LHS == RHS && LHS->hasNUses(2))))
2430 return createBinOpReverse(V1, V2);
2431
2432
2434 return createBinOpReverse(V1, RHS);
2435 }
2436
2438 return createBinOpReverse(LHS, V2);
2439
2440 auto createBinOpVPReverse = [&](Value *X, Value *Y, Value *EVL) {
2444
2449 M, Intrinsic::experimental_vp_reverse, V->getType());
2451 };
2452
2456
2459 (LHS->hasOneUse() || RHS->hasOneUse() ||
2460 (LHS == RHS && LHS->hasNUses(2))))
2461 return createBinOpVPReverse(V1, V2, EVL);
2462
2463
2465 return createBinOpVPReverse(V1, RHS, EVL);
2466 }
2467
2471 return createBinOpVPReverse(LHS, V2, EVL);
2472
2473
2474
2475
2477 return nullptr;
2478
2484 };
2485
2486
2487
2491 (LHS->hasOneUse() || RHS->hasOneUse() || LHS == RHS)) {
2492
2493 return createBinOpShuffle(V1, V2, Mask);
2494 }
2495
2496
2497
2504
2505
2506
2507
2508 if (LShuf->isSelect() &&
2510 RShuf->isSelect() &&
2512
2513
2514
2515
2518 return NewBO;
2519 }
2520 }
2521
2522
2523
2524
2525
2526
2532 "Shuffle should not change scalar type");
2533
2537
2538
2541
2542
2543
2544 Value *NewLHS = ConstOp1 ? V1 : NewC;
2545 Value *NewRHS = ConstOp1 ? NewC : V1;
2546 return createBinOpShuffle(NewLHS, NewRHS, Mask);
2547 }
2548 }
2549
2550
2552
2555
2558 int SplatIndex;
2563 X->getType() != Inst.getType() ||
2565 return nullptr;
2566
2567
2568
2569
2573 return nullptr;
2574 }
2575
2576
2577
2578
2581 Value *NewSplat = Builder.CreateShuffleVector(NewBO, NewMask);
2583
2584
2585
2587 R->copyFastMathFlags(&Inst);
2588 R->andIRFlags(RHS);
2589 }
2591 NewInstBO->copyIRFlags(R);
2592 return R;
2593 }
2594
2595 return nullptr;
2596}
2597
2598
2599
2600
2602
2604
2605
2606
2607 if (BO.getOpcode() == Instruction::Sub)
2609
2613 return nullptr;
2614
2615
2616
2617 CastInst::CastOps CastOpc = IsSext ? Instruction::SExt : Instruction::ZExt;
2621 (Op0->hasOneUse() || Op1->hasOneUse()))) {
2622
2623
2626 return nullptr;
2628 if (!NarrowC)
2629 return nullptr;
2630 Y = NarrowC;
2631 }
2632
2633
2634 if (BO.getOpcode() == Instruction::Sub)
2636
2637
2638
2640 return nullptr;
2641
2642
2643
2644 Value *NarrowBO = Builder.CreateBinOp(BO.getOpcode(), X, Y, "narrow");
2646 if (IsSext)
2647 NewBinOp->setHasNoSignedWrap();
2648 else
2649 NewBinOp->setHasNoUnsignedWrap();
2650 }
2652}
2653
2654
2655
2660
2661
2662
2665 if (.hasAllConstantIndices())
2666 return nullptr;
2667
2674 return nullptr;
2675
2676
2677
2678
2681 Type *Ty = GEP.getSourceElementType();
2682 Value *NewTrueC = Builder.CreateGEP(Ty, TrueC, IndexC, "", NW);
2683 Value *NewFalseC = Builder.CreateGEP(Ty, FalseC, IndexC, "", NW);
2685}
2686
2687
2688
2689
2693 if (GEP.getNumIndices() != 1)
2694 return nullptr;
2697 const APInt *C1;
2699 return nullptr;
2700 Value *VarIndex;
2701 const APInt *C2;
2703 unsigned IndexSizeInBits = DL.getIndexTypeSizeInBits(PtrTy);
2705 return nullptr;
2706 if (C1->getBitWidth() != IndexSizeInBits ||
2708 return nullptr;
2711 return nullptr;
2714 if (NewOffset.isZero() ||
2715 (Src->hasOneUse() && GEP.getOperand(1)->hasOneUse())) {
2717 if (GEP.hasNoUnsignedWrap() &&
2723 }
2724
2725 Value *GEPConst =
2728 }
2729
2730 return nullptr;
2731}
2732
2733
2734
2737 if (.hasAllConstantIndices())
2738 return nullptr;
2739
2743 while (true) {
2744 if (!InnerGEP)
2745 return nullptr;
2746
2748 if (InnerGEP->hasAllConstantIndices())
2749 break;
2750
2751 if (!InnerGEP->hasOneUse())
2752 return nullptr;
2753
2754 Skipped.push_back(InnerGEP);
2756 }
2757
2758
2759
2760 if (Skipped.empty())
2761 return nullptr;
2762
2763
2764
2765 if (!InnerGEP->hasOneUse())
2766 return nullptr;
2767
2768
2769 Type *Ty = GEP.getType();
2770 if (InnerGEP->getType() != Ty)
2771 return nullptr;
2772
2775 if (.accumulateConstantOffset(DL, Offset) ||
2776 !InnerGEP->accumulateConstantOffset(DL, Offset))
2777 return nullptr;
2778
2779 IC.replaceOperand(*Skipped.back(), 0, InnerGEP->getPointerOperand());
2781 SkippedGEP->setNoWrapFlags(NW);
2782
2787}
2788
2791
2792
2793
2795 return nullptr;
2796
2798 return I;
2799
2801 return I;
2802
2803 if (Src->getResultElementType() != GEP.getSourceElementType())
2804 return nullptr;
2805
2806
2807 bool EndsWithSequential = false;
2810 EndsWithSequential = I.isSequential();
2811 if (!EndsWithSequential)
2812 return nullptr;
2813
2814
2815
2816 Value *SO1 = Src->getOperand(Src->getNumOperands() - 1);
2817 Value *GO1 = GEP.getOperand(1);
2818
2819
2820
2821
2822
2824 return nullptr;
2825
2828
2829
2830 if (Sum == nullptr)
2831 return nullptr;
2832
2834 Indices.append(Src->op_begin() + 1, Src->op_end() - 1);
2836 Indices.append(GEP.op_begin() + 2, GEP.op_end());
2837
2838
2839 unsigned NumNonZeroIndices = count_if(Indices, [](Value *Idx) {
2841 return ||
->isNullValue();
2842 });
2843 if (NumNonZeroIndices > 1)
2844 return nullptr;
2845
2848 Src->getSourceElementType(), Src->getOperand(0), Indices, "",
2850}
2851
2854 bool &DoesConsume, unsigned Depth) {
2855 static Value *const NonNull = reinterpret_cast<Value *>(uintptr_t(1));
2856
2859 DoesConsume = true;
2860 return A;
2861 }
2862
2864
2867
2869 return nullptr;
2870
2871
2872
2873 if (!WillInvertAllUses)
2874 return nullptr;
2875
2876
2877
2880 return Builder->CreateCmp(I->getInversePredicate(), I->getOperand(0),
2881 I->getOperand(1));
2882 return NonNull;
2883 }
2884
2885
2886
2889 DoesConsume, Depth))
2892 DoesConsume, Depth))
2894 return nullptr;
2895 }
2896
2897
2898
2901 DoesConsume, Depth))
2904 DoesConsume, Depth))
2906 return nullptr;
2907 }
2908
2909
2910
2913 DoesConsume, Depth))
2915 return nullptr;
2916 }
2917
2918
2919
2922 DoesConsume, Depth))
2924 return nullptr;
2925 }
2926
2928
2929
2932
2934 bool LocalDoesConsume = DoesConsume;
2936 LocalDoesConsume, Depth))
2937 return nullptr;
2939 LocalDoesConsume, Depth)) {
2940 DoesConsume = LocalDoesConsume;
2941 if (Builder != nullptr) {
2943 DoesConsume, Depth);
2944 assert(NotB != nullptr &&
2945 "Unable to build inverted value for known freely invertable op");
2947 return Builder->CreateBinaryIntrinsic(
2949 return Builder->CreateSelect(Cond, NotA, NotB);
2950 }
2951 return NonNull;
2952 }
2953 }
2954
2956 bool LocalDoesConsume = DoesConsume;
2958 for (Use &U : PN->operands()) {
2959 BasicBlock *IncomingBlock = PN->getIncomingBlock(U);
2961 U.get(), false,
2963 if (NewIncomingVal == nullptr)
2964 return nullptr;
2965
2966 if (NewIncomingVal == V)
2967 return nullptr;
2969 IncomingValues.emplace_back(NewIncomingVal, IncomingBlock);
2970 }
2971
2972 DoesConsume = LocalDoesConsume;
2973 if (Builder != nullptr) {
2975 Builder->SetInsertPoint(PN);
2977 Builder->CreatePHI(PN->getType(), PN->getNumIncomingValues());
2978 for (auto [Val, Pred] : IncomingValues)
2980 return NewPN;
2981 }
2982 return NonNull;
2983 }
2984
2987 DoesConsume, Depth))
2988 return Builder ? Builder->CreateSExt(AV, V->getType()) : NonNull;
2989 return nullptr;
2990 }
2991
2994 DoesConsume, Depth))
2995 return Builder ? Builder->CreateTrunc(AV, V->getType()) : NonNull;
2996 return nullptr;
2997 }
2998
2999
3000
3001
3003 bool IsLogical, Value *A,
3005 bool LocalDoesConsume = DoesConsume;
3007 LocalDoesConsume, Depth))
3008 return nullptr;
3010 LocalDoesConsume, Depth)) {
3012 LocalDoesConsume, Depth);
3013 DoesConsume = LocalDoesConsume;
3014 if (IsLogical)
3015 return Builder ? Builder->CreateLogicalOp(Opcode, NotA, NotB) : NonNull;
3016 return Builder ? Builder->CreateBinOp(Opcode, NotA, NotB) : NonNull;
3017 }
3018
3019 return nullptr;
3020 };
3021
3023 return TryInvertAndOrUsingDeMorgan(Instruction::And, false, A,
3024 B);
3025
3027 return TryInvertAndOrUsingDeMorgan(Instruction::Or, false, A,
3028 B);
3029
3031 return TryInvertAndOrUsingDeMorgan(Instruction::And, true, A,
3032 B);
3033
3035 return TryInvertAndOrUsingDeMorgan(Instruction::Or, true, A,
3036 B);
3037
3038 return nullptr;
3039}
3040
3041
3043 Value *PtrOp = GEP.getOperand(0);
3044 Type *GEPEltType = GEP.getSourceElementType();
3046 return false;
3047
3048
3049
3051 return true;
3052
3053
3054
3055 if (GEP.getNumIndices() == 1 &&
3059 return true;
3060
3061
3062
3064 return PtrOpGep && PtrOpGep->hasAllConstantIndices() &&
3066 const APInt *C;
3067 return match(V, m_APInt(C)) && !C->isZero();
3068 });
3069}
3070
3074 if (!Op1)
3075 return nullptr;
3076
3077
3078
3079
3080
3081
3082
3083 if (Op1 == &GEP)
3084 return nullptr;
3086
3087 int DI = -1;
3088
3091 if (!Op2 || Op1->getNumOperands() != Op2->getNumOperands() ||
3092 Op1->getSourceElementType() != Op2->getSourceElementType())
3093 return nullptr;
3094
3095
3096 if (Op2 == &GEP)
3097 return nullptr;
3098
3099
3100 Type *CurTy = nullptr;
3101
3102 for (unsigned J = 0, F = Op1->getNumOperands(); J != F; ++J) {
3103 if (Op1->getOperand(J)->getType() != Op2->getOperand(J)->getType())
3104 return nullptr;
3105
3106 if (Op1->getOperand(J) != Op2->getOperand(J)) {
3107 if (DI == -1) {
3108
3109
3110
3111
3112
3113
3114 if (J > 1) {
3115 assert(CurTy && "No current type?");
3117 return nullptr;
3118 }
3119
3120 DI = J;
3121 } else {
3122
3123
3124
3125
3126
3127
3128 return nullptr;
3129 }
3130 }
3131
3132
3133 if (J > 0) {
3134 if (J == 1) {
3135 CurTy = Op1->getSourceElementType();
3136 } else {
3137 CurTy =
3139 }
3140 }
3141 }
3142
3143 NW &= Op2->getNoWrapFlags();
3144 }
3145
3146
3147
3148
3149 if (DI != -1 && !PN->hasOneUse())
3150 return nullptr;
3151
3153 NewGEP->setNoWrapFlags(NW);
3154
3155 if (DI == -1) {
3156
3157
3158 } else {
3159
3160
3161
3163 {
3165 Builder.SetInsertPoint(PN);
3166 NewPN = Builder.CreatePHI(Op1->getOperand(DI)->getType(),
3168 }
3169
3173
3174 NewGEP->setOperand(DI, NewPN);
3175 }
3176
3177 NewGEP->insertBefore(*GEP.getParent(), GEP.getParent()->getFirstInsertionPt());
3178 return NewGEP;
3179}
3180
3182 Value *PtrOp = GEP.getOperand(0);
3184 Type *GEPType = GEP.getType();
3185 Type *GEPEltType = GEP.getSourceElementType();
3188 SQ.getWithInstruction(&GEP)))
3190
3191
3192
3193
3195 auto VWidth = GEPFVTy->getNumElements();
3196 APInt PoisonElts(VWidth, 0);
3199 PoisonElts)) {
3200 if (V != &GEP)
3202 return &GEP;
3203 }
3204 }
3205
3206
3207
3208 bool MadeChange = false;
3209
3210
3211
3212 Type *NewScalarIndexTy =
3213 DL.getIndexType(GEP.getPointerOperandType()->getScalarType());
3214
3217 ++I, ++GTI) {
3218
3220 continue;
3221
3222 Type *IndexTy = (*I)->getType();
3223 Type *NewIndexType =
3227 : NewScalarIndexTy;
3228
3229
3230
3232 if (EltTy->isSized() && DL.getTypeAllocSize(EltTy).isZero())
3235 MadeChange = true;
3236 }
3237
3238 if (IndexTy != NewIndexType) {
3239
3240
3241
3244 if (GEP.hasNoUnsignedWrap() && GEP.hasNoUnsignedSignedWrap())
3245 *I = Builder.CreateZExt(*I, NewIndexType, "", true);
3246 else
3247 *I = Builder.CreateSExt(*I, NewIndexType);
3248 } else {
3249 *I = Builder.CreateTrunc(*I, NewIndexType, "", GEP.hasNoUnsignedWrap(),
3250 GEP.hasNoUnsignedSignedWrap());
3251 }
3252 MadeChange = true;
3253 }
3254 }
3255 if (MadeChange)
3256 return &GEP;
3257
3258
3259 if (!GEPEltType->isIntegerTy(8) && GEP.hasAllConstantIndices()) {
3260 APInt Offset(DL.getIndexTypeSizeInBits(GEPType), 0);
3261 if (GEP.accumulateConstantOffset(DL, Offset))
3264 GEP.getNoWrapFlags()));
3265 }
3266
3270 Builder.CreatePtrAdd(PtrOp, Offset, "", GEP.getNoWrapFlags());
3272 }
3273
3274
3276 if (LastIdx && LastIdx->isNullValue() && !LastIdx->getType()->isVectorTy()) {
3278 GEP, Builder.CreateGEP(GEP.getSourceElementType(), PtrOp,
3279 drop_end(Indices), "", GEP.getNoWrapFlags()));
3280 }
3281
3282
3284 if (FirstIdx && FirstIdx->isNullValue() &&
3285 !FirstIdx->getType()->isVectorTy()) {
3287 ++GTI;
3290 GEP.getPointerOperand(),
3292 GEP.getNoWrapFlags()));
3293 }
3294
3295
3296
3297
3299 return Op->getType()->isVectorTy() && getSplatValue(Op);
3300 })) {
3302 for (auto &Op : GEP.operands()) {
3303 if (Op->getType()->isVectorTy())
3306 continue;
3307 }
3309 }
3310
3311 Value *Res = Builder.CreateGEP(GEP.getSourceElementType(), NewOps[0],
3312 ArrayRef(NewOps).drop_front(), GEP.getName(),
3313 GEP.getNoWrapFlags());
3316 Res = Builder.CreateVectorSplat(EC, Res);
3317 }
3319 }
3320
3321 bool SeenNonZeroIndex = false;
3322 for (auto [IdxNum, Idx] : enumerate(Indices)) {
3324 if (C && C->isNullValue())
3325 continue;
3326
3327 if (!SeenNonZeroIndex) {
3328 SeenNonZeroIndex = true;
3329 continue;
3330 }
3331
3332
3334 Value *FrontGEP =
3335 Builder.CreateGEP(GEPEltType, PtrOp, FrontIndices,
3336 GEP.getName() + ".split", GEP.getNoWrapFlags());
3337
3343 BackIndices, GEP.getNoWrapFlags());
3344 }
3345
3346
3350 }
3351
3354 return I;
3355
3356 if (GEP.getNumIndices() == 1) {
3357 unsigned AS = GEP.getPointerAddressSpace();
3358 if (GEP.getOperand(1)->getType()->getScalarSizeInBits() ==
3359 DL.getIndexSizeInBits(AS)) {
3360 uint64_t TyAllocSize = DL.getTypeAllocSize(GEPEltType).getFixedValue();
3361
3362 if (TyAllocSize == 1) {
3363
3364
3365
3366
3367 Value *X = GEP.getPointerOperand();
3371 GEPType == Y->getType()) {
3372 bool HasNonAddressBits =
3373 DL.getAddressSizeInBits(AS) != DL.getPointerSizeInBits(AS);
3375 GEP.replaceUsesWithIf(Y, [&](Use &U) {
3376 bool ShouldReplace =
3379 Changed |= ShouldReplace;
3380 return ShouldReplace;
3381 });
3383 }
3384 } else if (auto *ExactIns =
3386
3388 if (ExactIns->isExact()) {
3396 GEP.getPointerOperand(), V,
3397 GEP.getNoWrapFlags());
3398 }
3399 }
3400 if (ExactIns->isExact() && ExactIns->hasOneUse()) {
3401
3402
3403
3404
3406 std::optional NewC;
3415 if (Rem == 0)
3416 NewC = Quot;
3419 int64_t Rem;
3421
3422 if (!Quot.isAllOnes() && Rem == 0)
3423 NewC = Quot;
3424 }
3425
3426 if (NewC.has_value()) {
3429 ConstantInt::get(V->getType(), *NewC));
3432 GEP.getPointerOperand(), NewOp,
3433 GEP.getNoWrapFlags());
3434 }
3435 }
3436 }
3437 }
3438 }
3439
3441 return nullptr;
3442
3443 if (.isInBounds()) {
3444 unsigned IdxWidth =
3446 APInt BasePtrOffset(IdxWidth, 0);
3447 Value *UnderlyingPtrOp =
3449 bool CanBeNull, CanBeFreed;
3451 DL, CanBeNull, CanBeFreed);
3452 if (!CanBeNull && !CanBeFreed && DerefBytes != 0) {
3453 if (GEP.accumulateConstantOffset(DL, BasePtrOffset) &&
3455 APInt AllocSize(IdxWidth, DerefBytes);
3456 if (BasePtrOffset.ule(AllocSize)) {
3458 GEP.getSourceElementType(), PtrOp, Indices, GEP.getName());
3459 }
3460 }
3461 }
3462 }
3463
3464
3465 if (GEP.hasNoUnsignedSignedWrap() && .hasNoUnsignedWrap() &&
3467 return isKnownNonNegative(Idx, SQ.getWithInstruction(&GEP));
3468 })) {
3470 return &GEP;
3471 }
3472
3473
3474
3475 if (GEP.getNumIndices() == 1) {
3476
3477
3478 auto GetPreservedNoWrapFlags = [&](bool AddIsNUW) {
3479
3480
3481 if (GEP.hasNoUnsignedWrap() && AddIsNUW)
3482 return GEP.getNoWrapFlags();
3484 };
3485
3486
3487 Value *Idx1, *Idx2;
3488 if (match(GEP.getOperand(1),
3490
3491
3492
3493
3494
3496 GEPNoWrapFlags NWFlags = GetPreservedNoWrapFlags(NUW);
3497 auto *NewPtr =
3498 Builder.CreateGEP(GEP.getSourceElementType(), GEP.getPointerOperand(),
3499 Idx1, "", NWFlags);
3501 Builder.CreateGEP(GEP.getSourceElementType(),
3502 NewPtr, Idx2, "", NWFlags));
3503 }
3507
3508
3509
3510
3511
3512
3513 bool NUW = match(GEP.getOperand(1),
3515 GEPNoWrapFlags NWFlags = GetPreservedNoWrapFlags(NUW);
3516 auto *NewPtr = Builder.CreateGEP(
3517 GEP.getSourceElementType(), GEP.getPointerOperand(),
3518 Builder.CreateSExt(Idx1, GEP.getOperand(1)->getType()), "", NWFlags);
3521 Builder.CreateGEP(GEP.getSourceElementType(), NewPtr,
3522 Builder.CreateSExt(C, GEP.getOperand(1)->getType()),
3523 "", NWFlags));
3524 }
3525 }
3526
3528 return R;
3529
3530 return nullptr;
3531}
3532
3536 return true;
3539
3541}
3542
3543
3544
3548
3549 return false;
3550
3552
3553 return false;
3554
3556 return false;
3557
3558
3559
3560
3562 return Dest && Dest->Ptr == UsedV;
3563}
3564
3565static std::optional
3572
3573 do {
3577 switch (I->getOpcode()) {
3578 default:
3579
3580 return std::nullopt;
3581
3582 case Instruction::AddrSpaceCast:
3583 case Instruction::BitCast:
3584 case Instruction::GetElementPtr:
3587 continue;
3588
3589 case Instruction::ICmp: {
3591
3592
3593
3595 return std::nullopt;
3596 unsigned OtherIndex = (ICI->getOperand(0) == PI) ? 1 : 0;
3598 return std::nullopt;
3599
3600
3601
3602
3603 auto AlignmentAndSizeKnownValid = [](CallBase *CB) {
3604
3605
3606
3607 const APInt *Alignment;
3609 return match(CB->getArgOperand(0), m_APInt(Alignment)) &&
3611 Alignment->isPowerOf2() && Size->urem(*Alignment).isZero();
3612 };
3614 LibFunc TheLibFunc;
3615 if (CB && TLI.getLibFunc(*CB->getCalledFunction(), TheLibFunc) &&
3616 TLI.has(TheLibFunc) && TheLibFunc == LibFunc_aligned_alloc &&
3617 !AlignmentAndSizeKnownValid(CB))
3618 return std::nullopt;
3620 continue;
3621 }
3622
3623 case Instruction::Call:
3624
3626 switch (II->getIntrinsicID()) {
3627 default:
3628 return std::nullopt;
3629
3630 case Intrinsic::memmove:
3631 case Intrinsic::memcpy:
3632 case Intrinsic::memset: {
3634 if (MI->isVolatile())
3635 return std::nullopt;
3636
3637
3641 return std::nullopt;
3642 Access |= NewAccess;
3643 [[fallthrough]];
3644 }
3645 case Intrinsic::assume:
3646 case Intrinsic::invariant_start:
3647 case Intrinsic::invariant_end:
3648 case Intrinsic::lifetime_start:
3649 case Intrinsic::lifetime_end:
3650 case Intrinsic::objectsize:
3652 continue;
3653 case Intrinsic::launder_invariant_group:
3654 case Intrinsic::strip_invariant_group:
3657 continue;
3658 }
3659 }
3660
3664 continue;
3665 }
3666
3671 continue;
3672 }
3673
3678 continue;
3679 }
3680
3681 return std::nullopt;
3682
3683 case Instruction::Store: {
3685 if (SI->isVolatile() || SI->getPointerOperand() != PI)
3686 return std::nullopt;
3688 return std::nullopt;
3691 continue;
3692 }
3693
3694 case Instruction::Load: {
3697 return std::nullopt;
3699 return std::nullopt;
3702 continue;
3703 }
3704 }
3706 }
3707 } while (!Worklist.empty());
3708
3711}
3712
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3727
3728
3729
3731 std::unique_ptr DIB;
3734 DIB.reset(new DIBuilder(*MI.getModule(), false));
3735 }
3736
3737
3738
3739 bool KnowInitUndef = false;
3740 bool KnowInitZero = false;
3745 KnowInitUndef = true;
3746 else if (Init->isNullValue())
3747 KnowInitZero = true;
3748 }
3749
3750
3751 auto &F = *MI.getFunction();
3752 if (F.hasFnAttribute(Attribute::SanitizeMemory) ||
3753 F.hasFnAttribute(Attribute::SanitizeAddress))
3754 KnowInitUndef = false;
3755
3756 auto Removable =
3758 if (Removable) {
3760
3761
3763 continue;
3764
3766
3768 if (II->getIntrinsicID() == Intrinsic::objectsize) {
3771 II, DL, &TLI, AA, true, &InsertedInstructions);
3772 for (Instruction *Inserted : InsertedInstructions)
3776 User = nullptr;
3777 continue;
3778 }
3780 if (KnowInitZero && isRefSet(*Removable)) {
3782 Builder.SetInsertPoint(MTI);
3783 auto *M = Builder.CreateMemSet(
3784 MTI->getRawDest(),
3786 MTI->getLength(), MTI->getDestAlign());
3787 M->copyMetadata(*MTI);
3788 }
3789 }
3790 }
3791 }
3794 continue;
3795
3797
3801 C->isFalseWhenEqual()));
3803 for (auto *DVR : DVRs)
3804 if (DVR->isAddressOfVariable())
3806 } else {
3807
3808
3811 assert(KnowInitZero || KnowInitUndef);
3814 } else
3817 }
3819 }
3820
3822
3823 Module *M = II->getModule();
3826 F, II->getNormalDest(), II->getUnwindDest(), {}, "", II->getParent());
3827 NewII->setDebugLoc(II->getDebugLoc());
3828 }
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855 for (auto *DVR : DVRs)
3856 if (DVR->isAddressOfVariable() || DVR->getExpression()->startsWithDeref())
3857 DVR->eraseFromParent();
3858
3860 }
3861 return nullptr;
3862}
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3884
3885
3886
3887
3888
3889 if (!PredBB)
3890 return nullptr;
3891
3892
3893
3897 return nullptr;
3898
3899
3900
3901
3902
3903 if (FreeInstrBB->size() != 2) {
3905 if (&Inst == &FI || &Inst == FreeInstrBBTerminator)
3906 continue;
3908 if (!Cast || !Cast->isNoopCast(DL))
3909 return nullptr;
3910 }
3911 }
3912
3920 TrueBB, FalseBB)))
3921 return nullptr;
3923 return nullptr;
3924
3925
3927 return nullptr;
3929 "Broken CFG: missing edge from predecessor to successor");
3930
3931
3932
3934 if (&Instr == FreeInstrBBTerminator)
3935 break;
3936 Instr.moveBeforePreserving(TI->getIterator());
3937 }
3939 "Only the branch instruction should remain");
3940
3941
3942
3943
3944
3945
3946
3947
3948
3950 Attrs = Attrs.removeParamAttribute(FI.getContext(), 0, Attribute::NonNull);
3951 Attribute Dereferenceable = Attrs.getParamAttr(0, Attribute::Dereferenceable);
3952 if (Dereferenceable.isValid()) {
3954 Attrs = Attrs.removeParamAttribute(FI.getContext(), 0,
3955 Attribute::Dereferenceable);
3956 Attrs = Attrs.addDereferenceableOrNullParamAttr(FI.getContext(), 0, Bytes);
3957 }
3959
3960 return &FI;
3961}
3962
3964
3966
3969 }
3970
3971
3972
3975
3976
3977
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3994 LibFunc Func;
3995 if (TLI.getLibFunc(FI, Func) && TLI.has(Func) && Func == LibFunc_free)
3997 return I;
3998 }
3999
4000 return nullptr;
4001}
4002
4005 if (!RetVal)
4006 return nullptr;
4007
4011 bool HasDereferenceable =
4012 F->getAttributes().getRetDereferenceableBytes() > 0;
4013 if (F->hasRetAttribute(Attribute::NonNull) ||
4014 (HasDereferenceable &&
4016 if (Value *V = simplifyNonNullOperand(RetVal, HasDereferenceable))
4018 }
4019 }
4020
4021 if (!AttributeFuncs::isNoFPClassCompatibleType(RetTy))
4022 return nullptr;
4023
4024 FPClassTest ReturnClass = F->getAttributes().getRetNoFPClass();
4025 if (ReturnClass == fcNone)
4026 return nullptr;
4027
4029 Value *Simplified =
4031 if (!Simplified)
4032 return nullptr;
4033
4035}
4036
4037
4039
4040
4041
4043 while (Instruction *Prev = I.getPrevNode()) {
4044
4045
4046
4047
4048 if (Prev->isEHPad())
4049 break;
4050
4052 break;
4053
4054
4055
4056
4057
4061 }
4063}
4064
4067 return nullptr;
4068}
4069
4072
4073
4074
4075
4076
4079 do {
4080 if (BBI != FirstInstr)
4081 --BBI;
4082 } while (BBI != FirstInstr && BBI->isDebugOrPseudoInst());
4083
4085 };
4086
4089 return &BI;
4090
4091 return nullptr;
4092}
4093
4096 if (.insert({From, To}).second)
4097 return;
4098
4099
4101 for (Use &U : PN.incoming_values())
4102 if (PN.getIncomingBlock(U) == From && (U)) {
4106 }
4107
4109}
4110
4111
4112
4118 std::next(I->getReverseIterator())))) {
4119 if (!Inst.use_empty() && !Inst.getType()->isTokenTy()) {
4122 }
4123 if (Inst.isEHPad() || Inst.getType()->isTokenTy())
4124 continue;
4125
4126 Inst.dropDbgRecords();
4129 }
4130
4136 }
4137
4138
4141}
4142
4148 return DeadEdges.contains({Pred, BB}) || DT.dominates(BB, Pred);
4149 }))
4150 continue;
4151
4153 }
4154}
4155
4160
4161 if (Succ == LiveSucc)
4162 continue;
4163
4165 }
4166
4168}
4169
4173
4174
4178
4180 if (BPI)
4181 BPI->swapSuccEdgesProbabilities(BI.getParent());
4183 }
4184
4185
4186
4187
4192 Value *NotX = Builder.CreateNot(X, "not." + X->getName());
4195 if (BPI)
4196 BPI->swapSuccEdgesProbabilities(BI.getParent());
4198 }
4199
4200
4201
4204
4205
4209
4213 if (BPI)
4214 BPI->swapSuccEdgesProbabilities(BI.getParent());
4216 return &BI;
4217 }
4218
4221 return nullptr;
4222 }
4226 return nullptr;
4227 }
4228
4229
4230
4231
4235 if (DT.dominates(Edge0, U)) {
4238 continue;
4239 }
4241 if (DT.dominates(Edge1, U)) {
4244 }
4245 }
4246 }
4247
4248 DC.registerBranch(&BI);
4249 return nullptr;
4250}
4251
4252
4253
4254
4257 bool IsTrueArm) {
4258 unsigned CstOpIdx = IsTrueArm ? 1 : 2;
4260 if ()
4261 return nullptr;
4262
4263 BasicBlock *CstBB = SI.findCaseValue(C)->getCaseSuccessor();
4264 if (CstBB != SI.getDefaultDest())
4265 return nullptr;
4266 Value *X = Select->getOperand(3 - CstOpIdx);
4268 const APInt *RHSC;
4271 return nullptr;
4272 if (IsTrueArm)
4274
4275
4277 for (auto Case : SI.cases())
4278 if (!CR.contains(Case.getCaseValue()->getValue()))
4279 return nullptr;
4280
4281 return X;
4282}
4283
4289
4290 for (auto Case : SI.cases()) {
4293 "Result of expression should be constant");
4295 }
4297 }
4298
4301
4302 for (auto Case : SI.cases()) {
4305 "Result of expression should be constant");
4307 }
4309 }
4310
4314 all_of(SI.cases(), [&](const auto &Case) {
4315 return Case.getCaseValue()->getValue().countr_zero() >= ShiftAmt;
4316 })) {
4317
4321 Value *NewCond = Op0;
4323
4325 NewCond = Builder.CreateAnd(
4327 }
4328 for (auto Case : SI.cases()) {
4329 const APInt &CaseVal = Case.getCaseValue()->getValue();
4331 : CaseVal.lshr(ShiftAmt);
4332 Case.setValue(ConstantInt::get(SI.getContext(), ShiftedCase));
4333 }
4335 }
4336 }
4337
4338
4343
4344 if (all_of(SI.cases(), [&](const auto &Case) {
4345 const APInt &CaseVal = Case.getCaseValue()->getValue();
4346 return IsZExt ? CaseVal.isIntN(NewWidth)
4347 : CaseVal.isSignedIntN(NewWidth);
4348 })) {
4349 for (auto &Case : SI.cases()) {
4350 APInt TruncatedCase = Case.getCaseValue()->getValue().trunc(NewWidth);
4351 Case.setValue(ConstantInt::get(SI.getContext(), TruncatedCase));
4352 }
4354 }
4355 }
4356
4357
4365 }
4366
4370
4371
4372
4373 for (const auto &C : SI.cases()) {
4374 LeadingKnownZeros =
4375 std::min(LeadingKnownZeros, C.getCaseValue()->getValue().countl_zero());
4376 LeadingKnownOnes =
4377 std::min(LeadingKnownOnes, C.getCaseValue()->getValue().countl_one());
4378 }
4379
4380 unsigned NewWidth = Known.getBitWidth() - std::max(LeadingKnownZeros, LeadingKnownOnes);
4381
4382
4383
4384
4385
4386 if (NewWidth > 0 && NewWidth < Known.getBitWidth() &&
4387 shouldChangeType(Known.getBitWidth(), NewWidth)) {
4391
4392 for (auto Case : SI.cases()) {
4393 APInt TruncatedCase = Case.getCaseValue()->getValue().trunc(NewWidth);
4394 Case.setValue(ConstantInt::get(SI.getContext(), TruncatedCase));
4395 }
4397 }
4398
4401 return nullptr;
4402 }
4405 SI.findCaseValue(CI)->getCaseSuccessor());
4406 return nullptr;
4407 }
4408
4409 return nullptr;
4410}
4411
4413InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {
4415 if (!WO)
4416 return nullptr;
4417
4419 const APInt *C = nullptr;
4421 if (*EV.idx_begin() == 0 && (OvID == Intrinsic::smul_with_overflow ||
4422 OvID == Intrinsic::umul_with_overflow)) {
4423
4424 if (C->isAllOnes())
4426
4427 if (C->isPowerOf2()) {
4428 return BinaryOperator::CreateShl(
4429 WO->getLHS(),
4430 ConstantInt::get(WO->getLHS()->getType(), C->logBase2()));
4431 }
4432 }
4433 }
4434
4435
4436
4437
4438 if (!WO->hasOneUse())
4439 return nullptr;
4440
4441
4442
4445 Value *LHS = WO->getLHS(), *RHS = WO->getRHS();
4446
4450 }
4451
4452 assert(*EV.idx_begin() == 1 && "Unexpected extract index for overflow inst");
4453
4454
4455 if (OvID == Intrinsic::usub_with_overflow)
4456 return new ICmpInst(ICmpInst::ICMP_ULT, WO->getLHS(), WO->getRHS());
4457
4458
4459
4460 if (OvID == Intrinsic::smul_with_overflow &&
4461 WO->getLHS()->getType()->isIntOrIntVectorTy(1))
4462 return BinaryOperator::CreateAnd(WO->getLHS(), WO->getRHS());
4463
4464
4465 if (OvID == Intrinsic::umul_with_overflow && WO->getLHS() == WO->getRHS()) {
4466 unsigned BitWidth = WO->getLHS()->getType()->getScalarSizeInBits();
4467
4469 return new ICmpInst(
4471 ConstantInt::get(WO->getLHS()->getType(),
4473 }
4474
4475
4476
4477
4478 if (C) {
4479
4480
4482 WO->getBinaryOp(), *C, WO->getNoWrapKind());
4483
4485 APInt NewRHSC, Offset;
4487 auto *OpTy = WO->getRHS()->getType();
4488 auto *NewLHS = WO->getLHS();
4490 NewLHS = Builder.CreateAdd(NewLHS, ConstantInt::get(OpTy, Offset));
4492 ConstantInt::get(OpTy, NewRHSC));
4493 }
4494
4495 return nullptr;
4496}
4497
4501
4502
4504 return nullptr;
4508
4509 const APFloat *ConstVal = nullptr;
4510 Value *VarOp = nullptr;
4511 bool ConstIsTrue = false;
4512
4514 VarOp = FalseVal;
4515 ConstIsTrue = true;
4517 VarOp = TrueVal;
4518 ConstIsTrue = false;
4519 } else {
4520 return nullptr;
4521 }
4522
4523 Builder.SetInsertPoint(&EV);
4524
4526 Builder.CreateCall(FrexpCall->getCalledFunction(), {VarOp}, "frexp");
4528
4529 Value *NewEV = Builder.CreateExtractValue(NewFrexp, 0, "mantissa");
4530
4531 int Exp;
4533
4534 Constant *ConstantMantissa = ConstantFP::get(TrueVal->getType(), Mantissa);
4535
4536 Value *NewSel = Builder.CreateSelectFMF(
4537 Cond, ConstIsTrue ? ConstantMantissa : NewEV,
4538 ConstIsTrue ? NewEV : ConstantMantissa, SelectInst, "select.frexp");
4539 return NewSel;
4540}
4543
4546
4548 SQ.getWithInstruction(&EV)))
4550
4551 Value *Cond, *TrueVal, *FalseVal;
4554 auto *SelInst =
4556 if (Value *Result =
4559 }
4561
4562 const unsigned *exti, *exte, *insi, *inse;
4563 for (exti = EV.idx_begin(), insi = IV->idx_begin(),
4564 exte = EV.idx_end(), inse = IV->idx_end();
4565 exti != exte && insi != inse;
4566 ++exti, ++insi) {
4567 if (*insi != *exti)
4568
4569
4570
4571
4572
4573
4574
4575
4578 }
4579 if (exti == exte && insi == inse)
4580
4581
4582
4583
4585 if (exti == exte) {
4586
4587
4588
4589
4590
4591
4592
4593
4594 Value *NewEV = Builder.CreateExtractValue(IV->getAggregateOperand(),
4598 }
4599 if (insi == inse)
4600
4601
4602
4603
4604
4605
4606
4607
4610 }
4611
4612 if (Instruction *R = foldExtractOfOverflowIntrinsic(EV))
4613 return R;
4614
4616
4618 STy && STy->isScalableTy())
4619 return nullptr;
4620
4621
4622
4623
4624
4625
4626 if (L->isSimple() && L->hasOneUse()) {
4627
4629
4631 for (unsigned Idx : EV.indices())
4633
4634
4635
4636 Builder.SetInsertPoint(L);
4638 L->getPointerOperand(), Indices);
4640
4641
4643
4644
4646 }
4647 }
4648
4651 return Res;
4652
4653
4654
4657 return R;
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667 return nullptr;
4668}
4669
4670
4672 switch (Personality) {
4676
4677
4678 return false;
4680 return false;
4682
4683
4684 return false;
4696 }
4698}
4699
4706
4708
4709
4710
4713
4714
4715
4716 bool MakeNewInstruction = false;
4718 bool CleanupFlag = LI.isCleanup();
4719
4721 for (unsigned i = 0, e = LI.getNumClauses(); i != e; ++i) {
4722 bool isLastClause = i + 1 == e;
4724
4727
4728
4729
4730 if (AlreadyCaught.insert(TypeInfo).second) {
4731
4732 NewClauses.push_back(CatchClause);
4733 } else {
4734
4735 MakeNewInstruction = true;
4736 }
4737
4738
4739
4740 if (isCatchAll(Personality, TypeInfo)) {
4741 if (!isLastClause)
4742 MakeNewInstruction = true;
4743 CleanupFlag = false;
4744 break;
4745 }
4746 } else {
4747
4748
4749
4750
4751
4752
4753
4754 assert(LI.isFilter(i) && "Unsupported landingpad clause!");
4757 unsigned NumTypeInfos = FilterType->getNumElements();
4758
4759
4760
4761
4762 if (!NumTypeInfos) {
4763 NewClauses.push_back(FilterClause);
4764 if (!isLastClause)
4765 MakeNewInstruction = true;
4766 CleanupFlag = false;
4767 break;
4768 }
4769
4770 bool MakeNewFilter = false;
4773
4774 assert(NumTypeInfos > 0 && "Should have handled empty filter already!");
4777
4778 if (isCatchAll(Personality, TypeInfo)) {
4779
4780 MakeNewInstruction = true;
4781 continue;
4782 }
4783
4784
4785
4786 NewFilterElts.push_back(TypeInfo);
4787 if (NumTypeInfos > 1)
4788 MakeNewFilter = true;
4789 } else {
4792 NewFilterElts.reserve(NumTypeInfos);
4793
4794
4795
4796
4797 bool SawCatchAll = false;
4798 for (unsigned j = 0; j != NumTypeInfos; ++j) {
4801 if (isCatchAll(Personality, TypeInfo)) {
4802
4803 SawCatchAll = true;
4804 break;
4805 }
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826 if (SeenInFilter.insert(TypeInfo).second)
4828 }
4829
4830 if (SawCatchAll) {
4831
4832 MakeNewInstruction = true;
4833 continue;
4834 }
4835
4836
4837 if (NewFilterElts.size() < NumTypeInfos)
4838 MakeNewFilter = true;
4839 }
4840 if (MakeNewFilter) {
4842 NewFilterElts.size());
4844 MakeNewInstruction = true;
4845 }
4846
4847 NewClauses.push_back(FilterClause);
4848
4849
4850
4851
4852
4853 if (MakeNewFilter && !NewFilterElts.size()) {
4854 assert(MakeNewInstruction && "New filter but not a new instruction!");
4855 CleanupFlag = false;
4856 break;
4857 }
4858 }
4859 }
4860
4861
4862
4863
4864
4865
4866 for (unsigned i = 0, e = NewClauses.size(); i + 1 < e; ) {
4867 unsigned j;
4868
4869 for (j = i; j != e; ++j)
4871 break;
4872
4873
4874
4875
4876 for (unsigned k = i; k + 1 < j; ++k)
4877 if (shorter_filter(NewClauses[k+1], NewClauses[k])) {
4878
4879
4880 std::stable_sort(NewClauses.begin() + i, NewClauses.begin() + j,
4882 MakeNewInstruction = true;
4883 break;
4884 }
4885
4886
4887 i = j + 1;
4888 }
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901 for (unsigned i = 0; i + 1 < NewClauses.size(); ++i) {
4902
4905 if (!FTy)
4906
4907 continue;
4909
4910
4911 for (unsigned j = NewClauses.size() - 1; j != i; --j) {
4912 Value *LFilter = NewClauses[j];
4914 if (!LTy)
4915
4916 continue;
4917
4918
4920
4921 if (!FElts) {
4922
4923 NewClauses.erase(J);
4924 MakeNewInstruction = true;
4925
4926 continue;
4927 }
4928 unsigned LElts = LTy->getNumElements();
4929
4930 if (FElts > LElts)
4931
4932 continue;
4933
4935
4936
4938 assert(FElts <= LElts && "Should have handled this case earlier!");
4939
4940 NewClauses.erase(J);
4941 MakeNewInstruction = true;
4942 }
4943
4944 continue;
4945 }
4948
4949
4950 assert(FElts > 0 && "Should have eliminated the empty filter earlier!");
4951 for (unsigned l = 0; l != LElts; ++l)
4952 if (LArray->getOperand(l)->isNullValue()) {
4953
4954 NewClauses.erase(J);
4955 MakeNewInstruction = true;
4956 break;
4957 }
4958
4959 continue;
4960 }
4961
4962
4963
4964
4966 bool AllFound = true;
4967 for (unsigned f = 0; f != FElts; ++f) {
4969 AllFound = false;
4970 for (unsigned l = 0; l != LElts; ++l) {
4972 if (LTypeInfo == FTypeInfo) {
4973 AllFound = true;
4974 break;
4975 }
4976 }
4977 if (!AllFound)
4978 break;
4979 }
4980 if (AllFound) {
4981
4982 NewClauses.erase(J);
4983 MakeNewInstruction = true;
4984 }
4985
4986 }
4987 }
4988
4989
4990
4991 if (MakeNewInstruction) {
4993 NewClauses.size());
4996
4997
4998
4999 if (NewClauses.empty())
5000 CleanupFlag = true;
5002 return NLI;
5003 }
5004
5005
5006
5007 if (LI.isCleanup() != CleanupFlag) {
5008 assert(!CleanupFlag && "Adding a cleanup, not removing one?!");
5010 return &LI;
5011 }
5012
5013 return nullptr;
5014}
5015
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030 auto CanPushFreeze = [](Value *V) {
5032 return false;
5033
5034
5035
5036
5037
5039 false);
5040 };
5041
5042
5043
5044
5048 Worklist.push_back(OrigUse);
5050 auto *U = Worklist.pop_back_val();
5051 Value *V = U->get();
5052 if (!CanPushFreeze(V)) {
5053
5054 if (U == OrigUse)
5055 return nullptr;
5056
5058 Builder.SetInsertPoint(UserI);
5059 Value *Frozen = Builder.CreateFreeze(V, V->getName() + ".fr");
5060 U->set(Frozen);
5061 continue;
5062 }
5063
5065 if (!Visited.insert(I).second)
5066 continue;
5067
5068
5072 continue;
5074 }
5075
5076 I->dropPoisonGeneratingAnnotations();
5077 this->Worklist.add(I);
5078 }
5079
5080 return OrigUse->get();
5081}
5082
5085
5086
5087
5088
5089
5090 Use *StartU = nullptr;
5094
5095 Worklist.push_back(U.get());
5096 continue;
5097 }
5098
5099
5100 if (StartU)
5101 return nullptr;
5102 StartU = &U;
5103 }
5104
5105 if (!StartU || Worklist.empty())
5106 return nullptr;
5107
5108 Value *StartV = StartU->get();
5111
5112
5113 if (StartNeedsFreeze && StartBB->getTerminator() == StartV)
5114 return nullptr;
5115
5120 if (!Visited.insert(V).second)
5121 continue;
5122
5123 if (Visited.size() > 32)
5124 return nullptr;
5125
5126
5128 continue;
5129
5132 false))
5133 return nullptr;
5134
5137 }
5138
5140 I->dropPoisonGeneratingAnnotations();
5141
5142 if (StartNeedsFreeze) {
5144 Value *FrozenStartV = Builder.CreateFreeze(StartV,
5145 StartV->getName() + ".fr");
5147 }
5149}
5150
5153
5155 return false;
5156
5157
5158
5159
5160
5161
5164 MoveBefore =
5166 } else {
5167 auto MoveBeforeOpt = cast(Op)->getInsertionPointAfterDef();
5168 if (!MoveBeforeOpt)
5169 return false;
5170 MoveBefore = *MoveBeforeOpt;
5171 }
5172
5173
5174 MoveBefore.setHeadBit(false);
5175
5177 if (&FI != &*MoveBefore) {
5178 FI.moveBefore(*MoveBefore->getParent(), MoveBefore);
5180 }
5181
5182 Op->replaceUsesWithIf(&FI, [&](Use &U) -> bool {
5183 bool Dominates = DT.dominates(&FI, U);
5185 return Dominates;
5186 });
5187
5189}
5190
5191
5193 for (auto *U : V->users()) {
5195 return true;
5197 return true;
5198 }
5199 return false;
5200}
5201
5203 Value *Op0 = I.getOperand(0);
5204
5207
5208
5211 return NV;
5213 return NV;
5214 }
5215
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233 auto getUndefReplacement = [&](Type *Ty) {
5234 auto pickCommonConstantFromPHI = [](PHINode &PN) -> Value * {
5235
5236
5237 Constant *BestValue = nullptr;
5238 for (Value *V : PN.incoming_values()) {
5240 continue;
5241
5243 if ()
5244 return nullptr;
5245
5247 return nullptr;
5248
5249 if (BestValue && BestValue != C)
5250 return nullptr;
5251
5252 BestValue = C;
5253 }
5254 return BestValue;
5255 };
5256
5258 Value *BestValue = nullptr;
5259 for (auto *U : I.users()) {
5260 Value *V = NullValue;
5267 V = NullValue;
5269 if (Value *MaybeV = pickCommonConstantFromPHI(*PHI))
5270 V = MaybeV;
5271 }
5272
5273 if (!BestValue)
5274 BestValue = V;
5275 else if (BestValue != V)
5276 BestValue = NullValue;
5277 }
5278 assert(BestValue && "Must have at least one use");
5279 assert(BestValue != &I && "Cannot replace with itself");
5280 return BestValue;
5281 };
5282
5284
5285
5286
5288 return nullptr;
5290 }
5291
5292 auto getFreezeVectorReplacement = [](Constant *C) -> Constant * {
5295 if (!VTy)
5296 return nullptr;
5297 unsigned NumElts = VTy->getNumElements();
5299 for (unsigned i = 0; i != NumElts; ++i) {
5300 Constant *EltC = C->getAggregateElement(i);
5302 BestValue = EltC;
5303 break;
5304 }
5305 }
5307 };
5308
5310 if (match(Op0, m_Constant(C)) && C->containsUndefOrPoisonElement() &&
5311 ->containsConstantExpression()) {
5312 if (Constant *Repl = getFreezeVectorReplacement(C))
5314 }
5315
5316
5318 return &I;
5319
5320 return nullptr;
5321}
5322
5323
5324
5325
5328 if (!CB)
5329
5330
5331
5332 return false;
5334 if (!Dest)
5335 return false;
5337 if (!AI)
5338
5339 return false;
5340
5341
5342
5345 auto pushUsers = [&](const Instruction &I) {
5346 for (const User *U : I.users()) {
5347 if (Visited.insert(U).second)
5349 }
5350 };
5351 pushUsers(*AI);
5352 while (!AllocaUsers.empty()) {
5355 pushUsers(*UserI);
5356 continue;
5357 }
5358 if (UserI == CB)
5359 continue;
5360
5361 return false;
5362 }
5363 return true;
5364}
5365
5366
5367
5368
5369
5373
5374
5375 if (isa(I) || I->isEHPad() || I->mayThrow() || ->willReturn() ||
5376 I->isTerminator())
5377 return false;
5378
5379
5380
5381
5382
5384 return false;
5385
5386
5388 return false;
5389
5390
5392 if (CI->isConvergent())
5393 return false;
5394 }
5395
5396
5397
5398 if (I->mayWriteToMemory()) {
5400 return false;
5401 }
5402
5403
5404
5405 if (I->mayReadFromMemory() &&
5406 ->hasMetadata(LLVMContext::MD_invariant_load)) {
5407
5408
5409
5411 return false;
5413 E = I->getParent()->end();
5414 Scan != E; ++Scan)
5415 if (Scan->mayWriteToMemory())
5416 return false;
5417 }
5418
5419 I->dropDroppableUses([&](const Use *U) {
5421 if (I && I->getParent() != DestBlock) {
5423 return true;
5424 }
5425 return false;
5426 });
5427
5428
5429
5431 I->moveBefore(*DestBlock, InsertPos);
5432 ++NumSunkInst;
5433
5434
5435
5436
5437
5438
5441 if (!DbgVariableRecords.empty())
5443 DbgVariableRecords);
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454 return true;
5455}
5456
5461
5462
5463
5464
5466 for (auto &DVR : DbgVariableRecords)
5467 if (DVR->getParent() != DestBlock)
5468 DbgVariableRecordsToSalvage.push_back(DVR);
5469
5470
5471
5474 if (DVR->getParent() == SrcBlock)
5475 DbgVariableRecordsToSink.push_back(DVR);
5476
5477
5478
5479
5480
5482 return B->getInstruction()->comesBefore(A->getInstruction());
5483 };
5485
5486
5487
5488
5489 using InstVarPair = std::pair<const Instruction *, DebugVariable>;
5491 if (DbgVariableRecordsToSink.size() > 1) {
5493
5496 DebugVariable(DVR->getVariable(), DVR->getExpression(),
5497 DVR->getDebugLoc()->getInlinedAt());
5498 CountMap[std::make_pair(DVR->getInstruction(), DbgUserVariable)] += 1;
5499 }
5500
5501
5502
5504 for (auto It : CountMap) {
5505 if (It.second > 1) {
5506 FilterOutMap[It.first] = nullptr;
5507 DupSet.insert(It.first.first);
5508 }
5509 }
5510
5511
5512
5513 for (const Instruction *Inst : DupSet) {
5517 DebugVariable(DVR.getVariable(), DVR.getExpression(),
5518 DVR.getDebugLoc()->getInlinedAt());
5519 auto FilterIt =
5520 FilterOutMap.find(std::make_pair(Inst, DbgUserVariable));
5521 if (FilterIt == FilterOutMap.end())
5522 continue;
5523 if (FilterIt->second != nullptr)
5524 continue;
5525 FilterIt->second = &DVR;
5526 }
5527 }
5528 }
5529
5530
5531
5536 continue;
5537
5539 DebugVariable(DVR->getVariable(), DVR->getExpression(),
5540 DVR->getDebugLoc()->getInlinedAt());
5541
5542
5543
5544 if (!FilterOutMap.empty()) {
5545 InstVarPair IVP = std::make_pair(DVR->getInstruction(), DbgUserVariable);
5546 auto It = FilterOutMap.find(IVP);
5547
5548
5549 if (It != FilterOutMap.end() && It->second != DVR)
5550 continue;
5551 }
5552
5553 if (!SunkVariables.insert(DbgUserVariable).second)
5554 continue;
5555
5556 if (DVR->isDbgAssign())
5557 continue;
5558
5561 }
5562
5563
5564 if (DVRClones.empty())
5565 return;
5566
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578 assert(InsertPos.getHeadBit());
5580 InsertPos->getParent()->insertDbgRecordBefore(DVRClone, InsertPos);
5581 LLVM_DEBUG(dbgs() << "SINK: " << *DVRClone << '\n');
5582 }
5583}
5584
5586 while (.isEmpty()) {
5587
5588
5590
5591
5592
5593
5596 ++NumDeadInst;
5597 continue;
5598 }
5599
5601 }
5602
5604 if (I == nullptr) continue;
5605
5606
5609 ++NumDeadInst;
5610 continue;
5611 }
5612
5614 continue;
5615
5616
5617
5618
5619 auto getOptionalSinkBlockForInst =
5620 [this](Instruction *I) -> std::optional<BasicBlock *> {
5622 return std::nullopt;
5623
5626 unsigned NumUsers = 0;
5627
5628 for (Use &U : I->uses()) {
5631
5632
5634 if (II->getIntrinsicID() != Intrinsic::assume ||
5635 ->getOperandBundle("dereferenceable"))
5636 continue;
5637 }
5638
5640 return std::nullopt;
5641
5643
5646 UserBB = PN->getIncomingBlock(U);
5647
5648
5649
5650 if (UserParent && UserParent != UserBB)
5651 return std::nullopt;
5652 UserParent = UserBB;
5653
5654
5655
5656 if (NumUsers == 0) {
5657
5658
5659 if (UserParent == BB || .isReachableFromEntry(UserParent))
5660 return std::nullopt;
5661
5663
5664
5665
5666
5667
5668
5669
5670
5672 return std::nullopt;
5673
5674 assert(DT.dominates(BB, UserParent) && "Dominance relation broken?");
5675 }
5676
5677 NumUsers++;
5678 }
5679
5680
5681 if (!UserParent)
5682 return std::nullopt;
5683
5684 return UserParent;
5685 };
5686
5687 auto OptBB = getOptionalSinkBlockForInst(I);
5688 if (OptBB) {
5689 auto *UserParent = *OptBB;
5690
5694
5695
5696
5697 for (Use &U : I->operands())
5700 }
5701 }
5702
5703
5705 Builder.CollectMetadataToCopy(
5706 I, {LLVMContext::MD_dbg, LLVMContext::MD_annotation});
5707
5708#ifndef NDEBUG
5709 std::string OrigI;
5710#endif
5712 LLVM_DEBUG(dbgs() << "IC: Visiting: " << OrigI << '\n');
5713
5715 ++NumCombined;
5716
5717 if (Result != I) {
5719 << " New = " << *Result << '\n');
5720
5721
5722
5723
5724 Result->setDebugLoc(Result->getDebugLoc().orElse(I->getDebugLoc()));
5725
5726 Result->copyMetadata(*I, LLVMContext::MD_annotation);
5727
5728 I->replaceAllUsesWith(Result);
5729
5730
5731 Result->takeName(I);
5732
5733
5734 BasicBlock *InstParent = I->getParent();
5736
5737
5739
5742 else
5744 }
5745
5746 Result->insertInto(InstParent, InsertPos);
5747
5748
5749 Worklist.pushUsersToWorkList(*Result);
5751
5753 } else {
5755 << " New = " << *I << '\n');
5756
5757
5758
5761 } else {
5762 Worklist.pushUsersToWorkList(*I);
5764 }
5765 }
5767 }
5768 }
5769
5772}
5773
5774
5775
5776
5777
5778
5779
5783
5784public:
5786
5787 if (->hasMetadataOtherThanDebugLoc())
5788 return;
5789
5790 auto Track = [](Metadata *ScopeList, auto &Container) {
5792 if (!MDScopeList || !Container.insert(MDScopeList).second)
5793 return;
5794 for (const auto &MDOperand : MDScopeList->operands())
5796 Container.insert(MDScope);
5797 };
5798
5799 Track(I->getMetadata(LLVMContext::MD_alias_scope), UsedAliasScopesAndLists);
5800 Track(I->getMetadata(LLVMContext::MD_noalias), UsedNoAliasScopesAndLists);
5801 }
5802
5805 if (!Decl)
5806 return false;
5807
5809 "llvm.experimental.noalias.scope.decl in use ?");
5812 "llvm.experimental.noalias.scope should refer to a single scope");
5815 return !UsedAliasScopesAndLists.contains(MD) ||
5816 !UsedNoAliasScopesAndLists.contains(MD);
5817
5818
5819 return true;
5820 }
5821};
5822
5823
5824
5825
5826
5827
5828
5829
5830
5837
5840 if (Succ != LiveSucc && DeadEdges.insert({BB, Succ}).second)
5841 for (PHINode &PN : Succ->phis())
5842 for (Use &U : PN.incoming_values())
5846 }
5847 };
5848
5851 return DeadEdges.contains({Pred, BB}) || DT.dominates(BB, Pred);
5852 })) {
5853 HandleOnlyLiveSuccessor(BB, nullptr);
5854 continue;
5855 }
5856 LiveBlocks.insert(BB);
5857
5859
5860 if (!Inst.use_empty() &&
5861 (Inst.getNumOperands() == 0 || isa(Inst.getOperand(0))))
5863 LLVM_DEBUG(dbgs() << "IC: ConstFold to: " << *C << " from: " << Inst
5864 << '\n');
5865 Inst.replaceAllUsesWith(C);
5866 ++NumConstProp;
5868 Inst.eraseFromParent();
5870 continue;
5871 }
5872
5873
5874 for (Use &U : Inst.operands()) {
5876 continue;
5877
5879 Constant *&FoldRes = FoldedConstants[C];
5880 if (!FoldRes)
5882
5883 if (FoldRes != C) {
5884 LLVM_DEBUG(dbgs() << "IC: ConstFold operand of: " << Inst
5885 << "\n Old = " << *C
5886 << "\n New = " << *FoldRes << '\n');
5887 U = FoldRes;
5889 }
5890 }
5891
5892
5893
5894
5895 if (!Inst.isDebugOrPseudoInst()) {
5896 InstrsForInstructionWorklist.push_back(&Inst);
5897 SeenAliasScopes.analyse(&Inst);
5898 }
5899 }
5900
5901
5902
5906
5907 HandleOnlyLiveSuccessor(BB, nullptr);
5908 continue;
5909 }
5911 bool CondVal = Cond->getZExtValue();
5912 HandleOnlyLiveSuccessor(BB, BI->getSuccessor(!CondVal));
5913 continue;
5914 }
5917
5918 HandleOnlyLiveSuccessor(BB, nullptr);
5919 continue;
5920 }
5922 HandleOnlyLiveSuccessor(BB,
5923 SI->findCaseValue(Cond)->getCaseSuccessor());
5924 continue;
5925 }
5926 }
5927 }
5928
5929
5930
5931
5933 if (LiveBlocks.count(&BB))
5934 continue;
5935
5936 unsigned NumDeadInstInBB;
5938
5940 NumDeadInst += NumDeadInstInBB;
5941 }
5942
5943
5944
5945
5946
5947
5948 Worklist.reserve(InstrsForInstructionWorklist.size());
5950
5951
5954 ++NumDeadInst;
5957 Inst->eraseFromParent();
5959 continue;
5960 }
5961
5963 }
5964
5966}
5967
5979
5986 auto &DL = F.getDataLayout();
5988 .hasFnAttribute("instcombine-no-verify-fixpoint");
5989
5990
5991
5998 }));
5999
6001
6002
6003
6004 bool MadeIRChange = false;
6007
6008
6009 unsigned Iteration = 0;
6010 while (true) {
6011 if (Iteration >= Opts.MaxIterations && !VerifyFixpoint) {
6013 << " on " << F.getName()
6014 << " reached; stopping without verifying fixpoint\n");
6015 break;
6016 }
6017
6018 ++Iteration;
6019 ++NumWorklistIterations;
6020 LLVM_DEBUG(dbgs() << "\n\nINSTCOMBINE ITERATION #" << Iteration << " on "
6021 << F.getName() << "\n");
6022
6023 InstCombinerImpl IC(Worklist, Builder, F, AA, AC, TLI, TTI, DT, ORE, BFI,
6024 BPI, PSI, DL, RPOT);
6027 MadeChangeInThisIteration |= IC.run();
6028 if (!MadeChangeInThisIteration)
6029 break;
6030
6031 MadeIRChange = true;
6034 "Instruction Combining on " + Twine(F.getName()) +
6036 " iterations. " +
6037 "Use 'instcombine' or function attribute "
6038 "'instcombine-no-verify-fixpoint' to suppress this error.");
6039 }
6040 }
6041
6042 if (Iteration == 1)
6043 ++NumOneIteration;
6044 else if (Iteration == 2)
6045 ++NumTwoIterations;
6046 else if (Iteration == 3)
6047 ++NumThreeIterations;
6048 else
6049 ++NumFourOrMoreIterations;
6050
6051 return MadeIRChange;
6052}
6053
6055
6059 OS, MapClassName2PassName);
6060 OS << '<';
6061 OS << "max-iterations=" << Options.MaxIterations << ";";
6062 OS << (Options.VerifyFixpoint ? "" : "no-") << "verify-fixpoint";
6063 OS << '>';
6064}
6065
6066char InstCombinePass::ID = 0;
6067
6071
6072 if (LRT.shouldSkip(&ID))
6074
6080
6085 auto *BFI = (PSI && PSI->hasProfileSummary()) ?
6088
6090 BFI, BPI, PSI, Options)) {
6091
6092 LRT.update(&ID, false);
6094 }
6095
6096
6098 LRT.update(&ID, true);
6101 return PA;
6102}
6103
6119
6122 return false;
6123
6124
6131
6132
6138 nullptr;
6140 if (auto *WrapperPass =
6142 BPI = &WrapperPass->getBPI();
6143
6146}
6147
6149
6153
6155 "Combine redundant instructions", false, false)
6167
6168
6172
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
static bool isSigned(unsigned int Opcode)
This is the interface for a simple mod/ref and alias analysis over globals.
shuff Hexagon Optimize Shuffle Vector
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
iv Induction Variable Users
static bool leftDistributesOverRight(Instruction::BinaryOps LOp, bool HasNUW, bool HasNSW, Intrinsic::ID ROp)
Return whether "X LOp (Y ROp Z)" is always equal to "(X LOp Y) ROp (X LOp Z)".
This file provides internal interfaces used to implement the InstCombine.
This file provides the primary interface to the instcombine pass.
static Value * simplifySwitchOnSelectUsingRanges(SwitchInst &SI, SelectInst *Select, bool IsTrueArm)
Definition InstructionCombining.cpp:4255
static bool isUsedWithinShuffleVector(Value *V)
Definition InstructionCombining.cpp:5192
static bool isNeverEqualToUnescapedAlloc(Value *V, const TargetLibraryInfo &TLI, Instruction *AI)
Definition InstructionCombining.cpp:3533
static Constant * constantFoldBinOpWithSplat(unsigned Opcode, Constant *Vector, Constant *Splat, bool SplatLHS, const DataLayout &DL)
Definition InstructionCombining.cpp:2334
static bool shorter_filter(const Value *LHS, const Value *RHS)
Definition InstructionCombining.cpp:4700
static Instruction * combineConstantOffsets(GetElementPtrInst &GEP, InstCombinerImpl &IC)
Combine constant offsets separated by variable offsets.
Definition InstructionCombining.cpp:2735
static Instruction * foldSelectGEP(GetElementPtrInst &GEP, InstCombiner::BuilderTy &Builder)
Thread a GEP operation with constant indices through the constant true/false arms of a select.
Definition InstructionCombining.cpp:2663
static bool shouldMergeGEPs(GEPOperator &GEP, GEPOperator &Src)
Definition InstructionCombining.cpp:2280
static cl::opt< unsigned > MaxArraySize("instcombine-maxarray-size", cl::init(1024), cl::desc("Maximum array size considered when doing a combine"))
static cl::opt< unsigned > ShouldLowerDbgDeclare("instcombine-lower-dbg-declare", cl::Hidden, cl::init(true))
static bool hasNoSignedWrap(BinaryOperator &I)
Definition InstructionCombining.cpp:390
static bool simplifyAssocCastAssoc(BinaryOperator *BinOp1, InstCombinerImpl &IC)
Combine constant operands of associative operations either before or after a cast to eliminate one of...
Definition InstructionCombining.cpp:414
static bool combineInstructionsOverFunction(Function &F, InstructionWorklist &Worklist, AliasAnalysis *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, TargetTransformInfo &TTI, DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI, ProfileSummaryInfo *PSI, const InstCombineOptions &Opts)
Definition InstructionCombining.cpp:5980
static Value * simplifyInstructionWithPHI(Instruction &I, PHINode *PN, Value *InValue, BasicBlock *InBB, const DataLayout &DL, const SimplifyQuery SQ)
Definition InstructionCombining.cpp:1839
static bool shouldCanonicalizeGEPToPtrAdd(GetElementPtrInst &GEP)
Return true if we should canonicalize the gep to an i8 ptradd.
Definition InstructionCombining.cpp:3042
static void ClearSubclassDataAfterReassociation(BinaryOperator &I)
Conservatively clears subclassOptionalData after a reassociation or commutation.
Definition InstructionCombining.cpp:398
static Value * getIdentityValue(Instruction::BinaryOps Opcode, Value *V)
This function returns identity value for given opcode, which can be used to factor patterns like (X *...
Definition InstructionCombining.cpp:704
static Value * foldFrexpOfSelect(ExtractValueInst &EV, IntrinsicInst *FrexpCall, SelectInst *SelectInst, InstCombiner::BuilderTy &Builder)
Definition InstructionCombining.cpp:4498
static std::optional< std::pair< Value *, Value * > > matchSymmetricPhiNodesPair(PHINode *LHS, PHINode *RHS)
Definition InstructionCombining.cpp:1296
static Value * foldOperationIntoSelectOperand(Instruction &I, SelectInst *SI, Value *NewOp, InstCombiner &IC)
Definition InstructionCombining.cpp:1773
static Instruction * canonicalizeGEPOfConstGEPI8(GetElementPtrInst &GEP, GEPOperator *Src, InstCombinerImpl &IC)
Definition InstructionCombining.cpp:2690
static Instruction * tryToMoveFreeBeforeNullTest(CallInst &FI, const DataLayout &DL)
Move the call to free before a NULL test.
Definition InstructionCombining.cpp:3879
static Value * simplifyOperationIntoSelectOperand(Instruction &I, SelectInst *SI, bool IsTrueArm)
Definition InstructionCombining.cpp:1748
static bool rightDistributesOverLeft(Instruction::BinaryOps LOp, Instruction::BinaryOps ROp)
Return whether "(X LOp Y) ROp Z" is always equal to "(X ROp Z) LOp (Y ROp Z)".
Definition InstructionCombining.cpp:689
static Value * tryFactorization(BinaryOperator &I, const SimplifyQuery &SQ, InstCombiner::BuilderTy &Builder, Instruction::BinaryOps InnerOpcode, Value *A, Value *B, Value *C, Value *D)
This tries to simplify binary operations by factorizing out common terms (e.
Definition InstructionCombining.cpp:745
static bool isRemovableWrite(CallBase &CB, Value *UsedV, const TargetLibraryInfo &TLI)
Given a call CB which uses an address UsedV, return true if we can prove the call's only possible eff...
Definition InstructionCombining.cpp:3545
static Instruction::BinaryOps getBinOpsForFactorization(Instruction::BinaryOps TopOpcode, BinaryOperator *Op, Value *&LHS, Value *&RHS, BinaryOperator *OtherOp)
This function predicates factorization using distributive laws.
Definition InstructionCombining.cpp:717
static bool hasNoUnsignedWrap(BinaryOperator &I)
Definition InstructionCombining.cpp:385
static bool SoleWriteToDeadLocal(Instruction *I, TargetLibraryInfo &TLI)
Check for case where the call writes to an otherwise dead alloca.
Definition InstructionCombining.cpp:5326
static cl::opt< unsigned > MaxSinkNumUsers("instcombine-max-sink-users", cl::init(32), cl::desc("Maximum number of undroppable users for instruction sinking"))
static Instruction * foldGEPOfPhi(GetElementPtrInst &GEP, PHINode *PN, IRBuilderBase &Builder)
Definition InstructionCombining.cpp:3071
static std::optional< ModRefInfo > isAllocSiteRemovable(Instruction *AI, SmallVectorImpl< WeakTrackingVH > &Users, const TargetLibraryInfo &TLI, bool KnowInit)
Definition InstructionCombining.cpp:3566
static bool isCatchAll(EHPersonality Personality, Constant *TypeInfo)
Return 'true' if the given typeinfo will match anything.
Definition InstructionCombining.cpp:4671
static cl::opt< bool > EnableCodeSinking("instcombine-code-sinking", cl::desc("Enable code sinking"), cl::init(true))
static bool maintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C)
Definition InstructionCombining.cpp:357
static GEPNoWrapFlags getMergedGEPNoWrapFlags(GEPOperator &GEP1, GEPOperator &GEP2)
Determine nowrap flags for (gep (gep p, x), y) to (gep p, (x + y)) transform.
Definition InstructionCombining.cpp:2656
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
uint64_t IntrinsicInst * II
static bool IsSelect(MachineInstr &MI)
#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 unsigned getNumElements(Type *Ty)
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static unsigned getScalarSizeInBits(Type *Ty)
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 SymbolRef::Type getType(const Symbol *Sym)
This pass exposes codegen information to IR-level passes.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const uint32_t IV[8]
bool isNoAliasScopeDeclDead(Instruction *Inst)
Definition InstructionCombining.cpp:5803
void analyse(Instruction *I)
Definition InstructionCombining.cpp:5785
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI unsigned int semanticsPrecision(const fltSemantics &)
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
static LLVM_ABI void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
Dual division/remainder interface.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
static LLVM_ABI void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
LLVM_ABI APInt smul_ov(const APInt &RHS, bool &Overflow) const
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
size_t size() const
size - Get the array size.
Class to represent array types.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
uint64_t getNumElements() const
Type * getElementType() const
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_ABI void registerAssumption(AssumeInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM_ABI uint64_t getDereferenceableBytes() const
Returns the number of dereferenceable bytes from the dereferenceable attribute.
bool isValid() const
Return true if the attribute is any kind of attribute.
Legacy wrapper pass to provide the BasicAAResult object.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const
Return a const iterator range over the instructions in the block, skipping any debug instructions.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI bool isEntryBlock() const
Return true if this is the entry block of the containing function.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction & front() const
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI const_iterator getFirstNonPHIOrDbgOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a debug intrinsic,...
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...
static LLVM_ABI BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static BinaryOperator * CreateNUW(BinaryOps Opc, Value *V1, Value *V2, const Twine &Name="")
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Conditional or Unconditional Branch instruction.
LLVM_ABI void swapSuccessors()
Swap the successors of this branch instruction.
bool isConditional() const
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
Value * getCondition() const
Analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
Represents analyses that only rely on functions' control flow.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
void setAttributes(AttributeList A)
Set the attributes for this call.
bool doesNotThrow() const
Determine if the call cannot unwind.
Value * getArgOperand(unsigned i) const
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_UGT
unsigned greater than
@ ICMP_ULT
unsigned less than
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,...
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
ConstantArray - Constant Array Declarations.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
A vector constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getNot(Constant *C)
static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
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 ConstantInt * getBool(LLVMContext &Context, bool V)
This class represents a range of values.
LLVM_ABI bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const
Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.
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 bool contains(const APInt &Val) const
Return true if the specified value is in the set.
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.
Constant Vector Declarations.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
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...
static LLVM_ABI Constant * replaceUndefsWith(Constant *C, Constant *Replacement)
Try to replace undefined constant C or undefined elements in C with Replacement.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
const Constant * stripPointerCasts() const
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
A parsed version of the target data layout string in and methods for querying it.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
static bool shouldExecute(CounterInfo &Counter)
Identifies a unique instance of a variable.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Utility class for floating point operations which can have information about relaxed accuracy require...
Convenience struct for specifying and reasoning about fast-math flags.
This class represents a freeze function that returns random concrete value if an operand is either a ...
FunctionPass class - This class is used to implement most global optimizations.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
const BasicBlock & getEntryBlock() const
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags inBounds()
static GEPNoWrapFlags all()
static GEPNoWrapFlags noUnsignedWrap()
GEPNoWrapFlags intersectForReassociate(GEPNoWrapFlags Other) const
Given (gep (gep p, x), y), determine the nowrap flags for (gep (gep, p, y), x).
bool hasNoUnsignedWrap() const
GEPNoWrapFlags intersectForOffsetAdd(GEPNoWrapFlags Other) const
Given (gep (gep p, x), y), determine the nowrap flags for (gep p, x+y).
static GEPNoWrapFlags none()
GEPNoWrapFlags getNoWrapFlags() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static LLVM_ABI Type * getTypeAtIndex(Type *Ty, Value *Idx)
Return the type of the element at the given index of an indexable type.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static LLVM_ABI Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Create an "inbounds" getelementptr.
Legacy wrapper pass to provide the GlobalsAAResult object.
This instruction compares its operands according to the predicate given to the constructor.
CmpPredicate getCmpPredicate() const
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
Common base class shared among various IRBuilders.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
Provides an 'InsertHelper' that calls a user-provided callback after performing the default insertion...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This instruction inserts a struct field of array element value into an aggregate value.
static InsertValueInst * Create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
LLVM_ABI InstCombinePass(InstCombineOptions Opts={})
Definition InstructionCombining.cpp:6054
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Definition InstructionCombining.cpp:6056
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition InstructionCombining.cpp:6068
Instruction * foldBinOpOfSelectAndCastOfSelectCondition(BinaryOperator &I)
Tries to simplify binops of select and cast of the select condition.
Definition InstructionCombining.cpp:1101
Instruction * foldBinOpIntoSelectOrPhi(BinaryOperator &I)
This is a convenience wrapper function for the above two functions.
Definition InstructionCombining.cpp:2266
bool SimplifyAssociativeOrCommutative(BinaryOperator &I)
Performs a few simplifications for operators which are associative or commutative.
Definition InstructionCombining.cpp:499
Instruction * visitGEPOfGEP(GetElementPtrInst &GEP, GEPOperator *Src)
Definition InstructionCombining.cpp:2789
Value * foldUsingDistributiveLaws(BinaryOperator &I)
Tries to simplify binary operations which some other binary operation distributes over.
Definition InstructionCombining.cpp:1203
Instruction * foldBinOpShiftWithShift(BinaryOperator &I)
Definition InstructionCombining.cpp:955
Instruction * visitUnreachableInst(UnreachableInst &I)
Definition InstructionCombining.cpp:4065
Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)
Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...
Definition InstructionCombining.cpp:1879
void handleUnreachableFrom(Instruction *I, SmallVectorImpl< BasicBlock * > &Worklist)
Definition InstructionCombining.cpp:4113
Value * SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &PoisonElts, unsigned Depth=0, bool AllowMultipleUsers=false) override
The specified value produces a vector with any number of elements.
Instruction * visitFreeze(FreezeInst &I)
Definition InstructionCombining.cpp:5202
void handlePotentiallyDeadBlocks(SmallVectorImpl< BasicBlock * > &Worklist)
Definition InstructionCombining.cpp:4143
bool prepareWorklist(Function &F)
Perform early cleanup and prepare the InstCombine worklist.
Definition InstructionCombining.cpp:5831
Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false, bool SimplifyBothArms=false)
Given an instruction with a select as one operand and a constant as the other operand,...
Definition InstructionCombining.cpp:1782
Instruction * visitFree(CallInst &FI, Value *FreedOp)
Definition InstructionCombining.cpp:3963
Instruction * visitExtractValueInst(ExtractValueInst &EV)
Definition InstructionCombining.cpp:4541
void handlePotentiallyDeadSuccessors(BasicBlock *BB, BasicBlock *LiveSucc)
Definition InstructionCombining.cpp:4156
Instruction * visitUnconditionalBranchInst(BranchInst &BI)
Definition InstructionCombining.cpp:4070
Instruction * foldBinopWithRecurrence(BinaryOperator &BO)
Try to fold binary operators whose operands are simple interleaved recurrences to a single recurrence...
Definition InstructionCombining.cpp:2048
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * visitLandingPadInst(LandingPadInst &LI)
Definition InstructionCombining.cpp:4707
Instruction * visitReturnInst(ReturnInst &RI)
Definition InstructionCombining.cpp:4003
Instruction * visitSwitchInst(SwitchInst &SI)
Definition InstructionCombining.cpp:4284
Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)
For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.
Definition InstructionCombining.cpp:2151
bool mergeStoreIntoSuccessor(StoreInst &SI)
Try to transform: if () { *P = v1; } else { *P = v2 } or: *P = v1; if () { *P = v2; }...
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Definition InstructionCombining.cpp:850
void CreateNonTerminatorUnreachable(Instruction *InsertAt)
Create and insert the idiom we use to indicate a block is unreachable without having to rewrite the C...
Value * pushFreezeToPreventPoisonFromPropagating(FreezeInst &FI)
Definition InstructionCombining.cpp:5017
bool run()
Run the combiner over the entire worklist until it is empty.
Definition InstructionCombining.cpp:5585
Instruction * foldVectorBinop(BinaryOperator &Inst)
Canonicalize the position of binops relative to shufflevector.
Definition InstructionCombining.cpp:2345
bool removeInstructionsBeforeUnreachable(Instruction &I)
Definition InstructionCombining.cpp:4038
Value * SimplifySelectsFeedingBinaryOp(BinaryOperator &I, Value *LHS, Value *RHS)
Definition InstructionCombining.cpp:1359
void tryToSinkInstructionDbgVariableRecords(Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock, BasicBlock *DestBlock, SmallVectorImpl< DbgVariableRecord * > &DPUsers)
Definition InstructionCombining.cpp:5457
void addDeadEdge(BasicBlock *From, BasicBlock *To, SmallVectorImpl< BasicBlock * > &Worklist)
Definition InstructionCombining.cpp:4094
Constant * unshuffleConstant(ArrayRef< int > ShMask, Constant *C, VectorType *NewCTy)
Find a constant NewC that has property: shuffle(NewC, ShMask) = C Returns nullptr if such a constant ...
Definition InstructionCombining.cpp:2296
Instruction * visitAllocSite(Instruction &FI)
Definition InstructionCombining.cpp:3713
Instruction * visitGetElementPtrInst(GetElementPtrInst &GEP)
Definition InstructionCombining.cpp:3181
Instruction * visitBranchInst(BranchInst &BI)
Definition InstructionCombining.cpp:4170
Value * tryFactorizationFolds(BinaryOperator &I)
This tries to simplify binary operations by factorizing out common terms (e.
Definition InstructionCombining.cpp:1160
Instruction * foldFreezeIntoRecurrence(FreezeInst &I, PHINode *PN)
Definition InstructionCombining.cpp:5083
Value * SimplifyDemandedUseFPClass(Value *V, FPClassTest DemandedMask, KnownFPClass &Known, Instruction *CxtI, unsigned Depth=0)
Attempts to replace V with a simpler value based on the demanded floating-point classes.
bool tryToSinkInstruction(Instruction *I, BasicBlock *DestBlock)
Try to move the specified instruction from its current block into the beginning of DestBlock,...
Definition InstructionCombining.cpp:5370
bool freezeOtherUses(FreezeInst &FI)
Definition InstructionCombining.cpp:5151
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)
Freely adapt every user of V as-if V was changed to !V.
Definition InstructionCombining.cpp:1442
The core instruction combiner logic.
const DataLayout & getDataLayout() const
IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)
Return true if the specified value is free to invert (apply ~ to).
static unsigned getComplexity(Value *V)
Assign a complexity or rank value to LLVM Values.
unsigned ComputeNumSignBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const
Instruction * InsertNewInstBefore(Instruction *New, BasicBlock::iterator Old)
Inserts an instruction New before instruction Old.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
uint64_t MaxArraySizeForCombine
Maximum size of array considered when transforming.
static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI)
void replaceUse(Use &U, Value *NewValue)
Replace use and add the previously used value to the worklist.
static bool isCanonicalPredicate(CmpPredicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
InstructionWorklist & Worklist
A worklist of the instructions that need to be simplified.
Instruction * InsertNewInstWith(Instruction *New, BasicBlock::iterator Old)
Same as InsertNewInstBefore, but also sets the debug loc.
BranchProbabilityInfo * BPI
ReversePostOrderTraversal< BasicBlock * > & RPOT
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
std::optional< Instruction * > targetInstCombineIntrinsic(IntrinsicInst &II)
Definition InstructionCombining.cpp:162
void addToWorklist(Instruction *I)
Value * getFreelyInvertedImpl(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume, unsigned Depth)
Return nonnull value if V is free to invert under the condition of WillInvertAllUses.
Definition InstructionCombining.cpp:2852
SmallDenseSet< std::pair< const BasicBlock *, const BasicBlock * >, 8 > BackEdges
Backedges, used to avoid pushing instructions across backedges in cases where this may result in infi...
std::optional< Value * > targetSimplifyDemandedVectorEltsIntrinsic(IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2, APInt &UndefElts3, std::function< void(Instruction *, unsigned, APInt, APInt &)> SimplifyAndSetOp)
Definition InstructionCombining.cpp:181
void computeBackEdges()
Definition InstructionCombining.cpp:5968
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
static Constant * getSafeVectorConstantForBinop(BinaryOperator::BinaryOps Opcode, Constant *In, bool IsRHSConstant)
Some binary operators require special handling to avoid poison and undefined behavior.
SmallDenseSet< std::pair< BasicBlock *, BasicBlock * >, 8 > DeadEdges
Edges that are known to never be taken.
std::optional< Value * > targetSimplifyDemandedUseBitsIntrinsic(IntrinsicInst &II, APInt DemandedMask, KnownBits &Known, bool &KnownBitsComputed)
Definition InstructionCombining.cpp:170
bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const
Definition InstructionCombining.cpp:195
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
bool isBackEdge(const BasicBlock *From, const BasicBlock *To)
void visit(Iterator Start, Iterator End)
The legacy pass manager's instcombine pass.
InstructionCombiningPass()
Definition InstructionCombining.cpp:6150
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition InstructionCombining.cpp:6104
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Definition InstructionCombining.cpp:6120
InstructionWorklist - This is the worklist management logic for InstCombine and other simplification ...
void add(Instruction *I)
Add instruction to the worklist.
LLVM_ABI void dropUBImplyingAttrsAndMetadata(ArrayRef< unsigned > Keep={})
Drop any attributes or metadata that can cause immediate undefined behavior.
static bool isBitwiseLogicOp(unsigned Opcode)
Determine if the Opcode is and/or/xor.
LLVM_ABI void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)
Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI void setAAMetadata(const AAMDNodes &N)
Sets the AA metadata on this instruction from the AAMDNodes structure.
LLVM_ABI bool isAssociative() const LLVM_READONLY
Return true if the instruction is associative:
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
bool isTerminator() const
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
LLVM_ABI bool willReturn() const LLVM_READONLY
Return true if the instruction will return (unwinding is considered as a form of returning control fl...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isBitwiseLogicOp() const
Return true if this is and/or/xor.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
static InvokeInst * Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr, InsertPosition InsertBefore=nullptr)
The landingpad instruction holds all of the information necessary to generate correct exception handl...
bool isCleanup() const
Return 'true' if this landingpad instruction is a cleanup.
unsigned getNumClauses() const
Get the number of clauses for this landing pad.
static LLVM_ABI LandingPadInst * Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedClauses is a hint for the number of incoming clauses that this landingpad w...
LLVM_ABI void addClause(Constant *ClauseVal)
Add a catch or filter clause to the landing pad.
bool isCatch(unsigned Idx) const
Return 'true' if the clause and index Idx is a catch clause.
bool isFilter(unsigned Idx) const
Return 'true' if the clause and index Idx is a filter clause.
Constant * getClause(unsigned Idx) const
Get the value of the clause at index Idx.
void setCleanup(bool V)
Indicate that this landingpad instruction is a cleanup.
A function/module analysis which provides an empty LastRunTrackingInfo.
This is an alternative analysis pass to BlockFrequencyInfoWrapperPass.
static void getLazyBFIAnalysisUsage(AnalysisUsage &AU)
Helper for client passes to set up the analysis usage on behalf of this pass.
An instruction for reading from memory.
Value * getPointerOperand()
bool isVolatile() const
Return true if this is a load from a volatile memory location.
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
Tracking metadata reference owned by Metadata.
This is the common base class for memset/memcpy/memmove.
static LLVM_ABI MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static ICmpInst::Predicate getPredicate(Intrinsic::ID ID)
Returns the comparison predicate underlying the intrinsic.
A Module instance is used to store all the information related to an LLVM module.
MDNode * getScopeList() const
Utility class for integer operators which may exhibit overflow - Add, Sub, Mul, and Shl.
bool hasNoSignedWrap() const
Test whether this operation is known to never undergo signed overflow, aka the nsw property.
bool hasNoUnsignedWrap() const
Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
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.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AnalysisType & getAnalysis() const
getAnalysis() - This function is used by subclasses to get to the analysis information ...
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable() - Subclasses use this function to get analysis information tha...
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool hasProfileSummary() const
Returns true if profile summary is available.
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Return a value (possibly void), from a function.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
This class represents the LLVM 'select' instruction.
const Value * getFalseValue() const
const Value * getCondition() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
const Value * getTrueValue() const
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
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.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
typename SuperClass::iterator iterator
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.
StringRef - Represent a constant reference to a string, i.e.
TargetFolder - Create constants with target dependent folding.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool has(LibFunc F) const
Tests whether a library function is available.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
bool isStructTy() const
True if this is an instance of StructType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive 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.
LLVM_ABI const fltSemantics & getFltSemantics() const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const
This is a wrapper around stripAndAccumulateConstantOffsets with the in-bounds requirement set to fals...
LLVM_ABI bool hasOneUser() const
Return true if there is exactly one user of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
bool hasUseList() const
Check if this Value has a use-list.
LLVM_ABI bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI uint64_t getPointerDereferenceableBytes(const DataLayout &DL, bool &CanBeNull, bool &CanBeFreed) const
Returns the number of bytes known to be dereferenceable for the pointer value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Base class of all SIMD vector types.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Value handle that is nullable, but tries to track the Value.
An efficient, type-erasing, non-owning reference to a callable.
Type * getIndexedType() const
const ParentTy * getParent() const
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
class_match< PoisonValue > m_Poison()
Match an arbitrary poison constant.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
PtrAdd_match< PointerOpTy, OffsetOpTy > m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)
Matches GEP with i8 source element type.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
class_match< BinaryOperator > m_BinOp()
Match an arbitrary binary operation and ignore it.
CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
auto m_PtrToIntOrAddr(const OpTy &Op)
Matches PtrToInt or PtrToAddr.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
OneOps_match< OpTy, Instruction::Freeze > m_Freeze(const OpTy &Op)
Matches FreezeInst.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
br_match m_UnconditionalBr(BasicBlock *&Succ)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)
Matches integer division operations.
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.
DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)
constantexpr_match m_ConstantExpr()
Match a constant expression or a constant that contains a constant expression.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
cst_pred_ty< is_nonnegative > m_NonNegative()
Match an integer or vector of non-negative values.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_IntrinsicIntrinsic::fabs(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)
Match a single index ExtractValue instruction.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
NNegZExt_match< OpTy > m_NNegZExt(const OpTy &Op)
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
Splat_match< T > m_ConstantSplat(const T &SubPattern)
Match a constant splat. TODO: Extend this to non-constant splats.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
ThreeOps_match< decltype(m_Value()), LHS, RHS, Instruction::Select, true > m_c_Select(const LHS &L, const RHS &R)
Match Select(C, LHS, RHS) or Select(C, RHS, LHS)
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
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".
CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)
CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
match_combine_or< OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap >, DisjointOr_match< LHS, RHS > > m_NSWAddLike(const LHS &L, const RHS &R)
Match either "add nsw" or "or disjoint".
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)
Matches a BinaryOperator with LHS and RHS in either order.
CastInst_match< OpTy, SIToFPInst > m_SIToFP(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
cstfp_pred_ty< is_non_zero_fp > m_NonZeroFP()
Match a floating-point non-zero.
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > > > m_MaxOrMin(const LHS &L, const RHS &R)
auto m_Undef()
Match an arbitrary undef constant.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
match_combine_or< OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap >, DisjointOr_match< LHS, RHS > > m_NUWAddLike(const LHS &L, const RHS &R)
Match either "add nuw" or "or disjoint".
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_VectorInsert(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
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.
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
LLVM_ABI Intrinsic::ID getInverseMinMaxIntrinsic(Intrinsic::ID MinMaxID)
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
FunctionAddr VTableAddr Value
void stable_sort(R &&Range)
LLVM_ABI void initializeInstructionCombiningPassPass(PassRegistry &)
LLVM_ABI unsigned removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB)
Remove all instructions from a basic block other than its terminator and any present EH pad instructi...
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Value * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, GEPNoWrapFlags NW, const SimplifyQuery &Q)
Given operands for a GetElementPtrInst, fold the result or return null.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
bool succ_empty(const Instruction *I)
LLVM_ABI Value * simplifyFreezeInst(Value *Op, const SimplifyQuery &Q)
Given an operand for a Freeze, see if we can fold the result.
LLVM_ABI FunctionPass * createInstructionCombiningPass()
Definition InstructionCombining.cpp:6173
LLVM_ABI void findDbgValues(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the dbg.values describing a value.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
LLVM_ABI Constant * ConstantFoldInstruction(const Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstruction - Try to constant fold the specified instruction.
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
LLVM_ABI std::optional< StringRef > getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI)
If a function is part of an allocation family (e.g.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI Value * lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL, const TargetLibraryInfo *TLI, bool MustSucceed)
Try to turn a call to @llvm.objectsize into an integer value of the given Type.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
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.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
gep_type_iterator gep_type_end(const User *GEP)
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI Value * getReallocatedOperand(const CallBase *CB)
If this is a call to a realloc function, return the reallocated operand.
APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM)
Equivalent of C standard library function.
LLVM_ABI bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates memory (either malloc,...
LLVM_ABI bool handleUnreachableTerminator(Instruction *I, SmallVectorImpl< Value * > &PoisonedValues)
If a terminator in an unreachable basic block has an operand of type Instruction, transform it into p...
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)
Given operands for an Add, fold the result or return null.
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)
Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...
LLVM_ABI Value * emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...
constexpr unsigned MaxAnalysisRecursionDepth
auto reverse(ContainerTy &&C)
bool isModSet(const ModRefInfo MRI)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI bool LowerDbgDeclare(Function &F)
Lowers dbg.declare records into appropriate set of dbg.value records.
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.
generic_gep_type_iterator<> gep_type_iterator
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, StoreInst *SI, DIBuilder &Builder)
Inserts a dbg.value record before a store to an alloca'd value that has an associated dbg....
LLVM_ABI void salvageDebugInfoForDbgValues(Instruction &I, ArrayRef< DbgVariableRecord * > DPInsns)
Implementation of salvageDebugInfo, applying only to instructions in Insns, rather than all debug use...
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
LLVM_ABI bool canCreateUndefOrPoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)
canCreateUndefOrPoison returns true if Op can create undef or poison from non-undef & non-poison oper...
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
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 Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_ABI bool replaceAllDbgUsesWith(Instruction &From, Value &To, Instruction &DomPoint, DominatorTree &DT)
Point debug users of From to To or salvage them.
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.
constexpr int PoisonMaskElem
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ Ref
The access may reference the value stored in memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)
Don't use information from its non-constant operands.
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
constexpr unsigned BitWidth
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)
Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
cl::opt< bool > ProfcheckDisableMetadataFixes("profcheck-disable-metadata-fixes", cl::Hidden, cl::init(false), cl::desc("Disable metadata propagation fixes discovered through Issue #147390"))
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI void initializeInstCombine(PassRegistry &)
Initialize all passes linked into the InstCombine library.
Definition InstructionCombining.cpp:6169
LLVM_ABI void findDbgUsers(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the debug info records describing a value.
LLVM_ABI Constant * ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2)
bool isRefSet(const ModRefInfo MRI)
LLVM_ABI std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)
Return true if RHS is known to be implied true by LHS.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned countMinLeadingOnes() const
Returns the minimum number of leading one bits.
unsigned getBitWidth() const
Get the bit width of this value.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
A CRTP mix-in to automatically provide informational APIs needed for passes.
SimplifyQuery getWithInstruction(const Instruction *I) const