LLVM: lib/Transforms/InstCombine/InstCombineCompares.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
34#include
35
36using namespace llvm;
38
39#define DEBUG_TYPE "instcombine"
40
41
42STATISTIC(NumSel, "Number of select opts");
43
44
45
47 bool IsSigned = false) {
48 bool Overflow;
49 if (IsSigned)
50 Result = In1.sadd_ov(In2, Overflow);
51 else
52 Result = In1.uadd_ov(In2, Overflow);
53
54 return Overflow;
55}
56
57
58
60 bool IsSigned = false) {
61 bool Overflow;
62 if (IsSigned)
63 Result = In1.ssub_ov(In2, Overflow);
64 else
65 Result = In1.usub_ov(In2, Overflow);
66
67 return Overflow;
68}
69
70
71
73 for (auto *U : I.users())
75 return true;
76 return false;
77}
78
79
80
81
82
85 return false;
86
87 if (C.isZero())
89
90 if (C.isOne()) {
93 return true;
94 }
95 } else if (C.isAllOnes()) {
98 return true;
99 }
100 }
101
102 return false;
103}
104
105
106
107
108
109
110
111
112
116 if (LI->isVolatile() || !GV || !GV->isConstant() ||
117 !GV->hasDefinitiveInitializer())
118 return nullptr;
119
121 TypeSize EltSize = DL.getTypeStoreSize(EltTy);
123 return nullptr;
124
127 return nullptr;
128
130 TypeSize GlobalSize = DL.getTypeAllocSize(Init->getType());
131
135
136
137 if (!ConstOffset.ult(Stride))
138 return nullptr;
139
140
142 return nullptr;
143
144
149 return nullptr;
150
151 enum { Overdefined = -3, Undefined = -2 };
152
153
154
155
156
157
158
159
160 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;
161
162
163
164 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;
165
166
167
168
169
170
171
172 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;
173
174
175
176
178
179
182 for (unsigned i = 0, e = ArrayElementCount; i != e; ++i, Offset += Stride) {
184 if (!Elt)
185 return nullptr;
186
187
188 if (AndCst) {
190 if (!Elt)
191 return nullptr;
192 }
193
194
197 if ()
198 return nullptr;
199
200
202
203
204 if (TrueRangeEnd == (int)i - 1)
205 TrueRangeEnd = i;
206 if (FalseRangeEnd == (int)i - 1)
207 FalseRangeEnd = i;
208 continue;
209 }
210
211
212
214 return nullptr;
215
216
217
219
220
221 if (IsTrueForElt) {
222
223 if (FirstTrueElement == Undefined)
224 FirstTrueElement = TrueRangeEnd = i;
225 else {
226
227 if (SecondTrueElement == Undefined)
228 SecondTrueElement = i;
229 else
230 SecondTrueElement = Overdefined;
231
232
233 if (TrueRangeEnd == (int)i - 1)
234 TrueRangeEnd = i;
235 else
236 TrueRangeEnd = Overdefined;
237 }
238 } else {
239
240 if (FirstFalseElement == Undefined)
241 FirstFalseElement = FalseRangeEnd = i;
242 else {
243
244 if (SecondFalseElement == Undefined)
245 SecondFalseElement = i;
246 else
247 SecondFalseElement = Overdefined;
248
249
250 if (FalseRangeEnd == (int)i - 1)
251 FalseRangeEnd = i;
252 else
253 FalseRangeEnd = Overdefined;
254 }
255 }
256
257
258 if (i < 64 && IsTrueForElt)
259 MagicBitvector |= 1ULL << i;
260
261
262
263
264 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&
265 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&
266 FalseRangeEnd == Overdefined)
267 return nullptr;
268 }
269
270
271
272
273
274
275
276
277
278
279
280 auto MaskIdx = [&](Value *Idx) {
284 Idx = Builder.CreateAnd(Idx, Mask);
285 }
286 return Idx;
287 };
288
289
290
291 if (SecondTrueElement != Overdefined) {
292 Idx = MaskIdx(Idx);
293
294 if (FirstTrueElement == Undefined)
296
297 Value *FirstTrueIdx = ConstantInt::get(Idx->getType(), FirstTrueElement);
298
299
300 if (SecondTrueElement == Undefined)
302
303
304 Value *C1 = Builder.CreateICmpEQ(Idx, FirstTrueIdx);
305 Value *SecondTrueIdx = ConstantInt::get(Idx->getType(), SecondTrueElement);
306 Value *C2 = Builder.CreateICmpEQ(Idx, SecondTrueIdx);
307 return BinaryOperator::CreateOr(C1, C2);
308 }
309
310
311
312 if (SecondFalseElement != Overdefined) {
313 Idx = MaskIdx(Idx);
314
315 if (FirstFalseElement == Undefined)
317
318 Value *FirstFalseIdx = ConstantInt::get(Idx->getType(), FirstFalseElement);
319
320
321 if (SecondFalseElement == Undefined)
323
324
325 Value *C1 = Builder.CreateICmpNE(Idx, FirstFalseIdx);
326 Value *SecondFalseIdx =
327 ConstantInt::get(Idx->getType(), SecondFalseElement);
328 Value *C2 = Builder.CreateICmpNE(Idx, SecondFalseIdx);
329 return BinaryOperator::CreateAnd(C1, C2);
330 }
331
332
333
334 if (TrueRangeEnd != Overdefined) {
335 assert(TrueRangeEnd != FirstTrueElement && "Should emit single compare");
336 Idx = MaskIdx(Idx);
337
338
339 if (FirstTrueElement) {
340 Value *Offs = ConstantInt::get(Idx->getType(), -FirstTrueElement);
341 Idx = Builder.CreateAdd(Idx, Offs);
342 }
343
345 ConstantInt::get(Idx->getType(), TrueRangeEnd - FirstTrueElement + 1);
347 }
348
349
350 if (FalseRangeEnd != Overdefined) {
351 assert(FalseRangeEnd != FirstFalseElement && "Should emit single compare");
352 Idx = MaskIdx(Idx);
353
354 if (FirstFalseElement) {
355 Value *Offs = ConstantInt::get(Idx->getType(), -FirstFalseElement);
356 Idx = Builder.CreateAdd(Idx, Offs);
357 }
358
360 ConstantInt::get(Idx->getType(), FalseRangeEnd - FirstFalseElement);
362 }
363
364
365
366
367 {
368 Type *Ty = nullptr;
369
370
371
372
373 if (ArrayElementCount <= Idx->getType()->getIntegerBitWidth())
375 else
376 Ty = DL.getSmallestLegalIntType(Init->getContext(), ArrayElementCount);
377
378 if (Ty) {
379 Idx = MaskIdx(Idx);
380 Value *V = Builder.CreateIntCast(Idx, Ty, false);
381 V = Builder.CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);
382 V = Builder.CreateAnd(ConstantInt::get(Ty, 1), V);
384 }
385 }
386
387 return nullptr;
388}
389
390
391
392
398
399
400
401
402
403
404
405
406
407 while (!WorkList.empty()) {
409
410 while (!WorkList.empty()) {
411 if (Explored.size() >= 100)
412 return false;
413
415
418 continue;
419 }
420
422
423
424 return false;
425
427
429 if (->isInBounds() || count_if(GEP->indices(), IsNonConst) > 1)
430 return false;
431
433 if (!Explored.contains(GEP->getOperand(0)))
435 }
436
437 if (WorkList.back() == V) {
439
441 }
442
444
446 return false;
449 }
450 }
451
452
453 for (auto *PN : PHIs)
454 for (Value *Op : PN->incoming_values())
457 }
458
459
460
461
462 for (Value *Val : Explored) {
464
467
468 if (Inst == Base || Inst == PHI || !Inst || ||
470 continue;
471
472 if (PHI->getParent() == Inst->getParent())
473 return false;
474 }
475 }
476 return true;
477}
478
479
480
482 bool Before = true) {
486 return;
487 }
489 if (!Before)
490 I = &*std::next(I->getIterator());
491 Builder.SetInsertPoint(I);
492 return;
493 }
495
496 BasicBlock &Entry = A->getParent()->getEntryBlock();
497 Builder.SetInsertPoint(&Entry, Entry.getFirstInsertionPt());
498 return;
499 }
500
501
502 assert(isa(V) && "Setting insertion point for unknown value!");
503}
504
505
506
511
512
513
514
515
516
517
519 Base->getContext(), DL.getIndexTypeSizeInBits(Start->getType()));
520
523
524
525 for (Value *Val : Explored) {
526 if (Val == Base)
527 continue;
528
529
531 NewInsts[PHI] =
533 PHI->getName() + ".idx", PHI->getIterator());
534 }
536
537
538 for (Value *Val : Explored) {
540 continue;
541
544 Value *Op = NewInsts[GEP->getOperand(0)];
547 NewInsts[GEP] = OffsetV;
548 else
549 NewInsts[GEP] = Builder.CreateAdd(
550 Op, OffsetV, GEP->getOperand(0)->getName() + ".add",
553 continue;
554 }
556 continue;
557
559 }
560
561
562 for (Value *Val : Explored) {
563 if (Val == Base)
564 continue;
565
566
569 for (unsigned I = 0, E = PHI->getNumIncomingValues(); I < E; ++I) {
570 Value *NewIncoming = PHI->getIncomingValue(I);
571
572 auto It = NewInsts.find(NewIncoming);
573 if (It != NewInsts.end())
574 NewIncoming = It->second;
575
576 NewPhi->addIncoming(NewIncoming, PHI->getIncomingBlock(I));
577 }
578 }
579 }
580
581 for (Value *Val : Explored) {
582 if (Val == Base)
583 continue;
584
586
587 Value *NewVal = Builder.CreateGEP(Builder.getInt8Ty(), Base, NewInsts[Val],
588 Val->getName() + ".ptr", NW);
590
591
593 }
594
595 return NewInsts[Start];
596}
597
598
599
600
605
607 return nullptr;
608
610 return nullptr;
611
615 false);
616
617
619 return nullptr;
620
621
625 return nullptr;
626
627
628
629
630
631
632
634
635
636
637
638
641}
642
643
644
647
648
649
650
651
653 return nullptr;
654
655
656
659
662 return true;
663
664
667 };
668
671
673 }
674
677 return I;
678 };
679
681 if (Base.Ptr == RHS && CanFold(Base.LHSNW) && .isExpensive()) {
682
683 Type *IdxTy = DL.getIndexType(GEPLHS->getType());
685 EmitGEPOffsets(Base.LHSGEPs, Base.LHSNW, IdxTy, true);
688 }
689
693 RHS->getType()->getPointerAddressSpace())) {
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
715 }
721
722
723
724 if (GEPLHS->getOperand(0) != GEPRHS->getOperand(0)) {
725 bool IndicesTheSame =
726 GEPLHS->getNumOperands() == GEPRHS->getNumOperands() &&
728 GEPRHS->getPointerOperand()->getType() &&
730 if (IndicesTheSame)
731 for (unsigned i = 1, e = GEPLHS->getNumOperands(); i != e; ++i)
732 if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) {
733 IndicesTheSame = false;
734 break;
735 }
736
737
739 if (IndicesTheSame &&
742
743
744
745
746
747 if (GEPLHS->isInBounds() && GEPRHS->isInBounds() &&
749 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&
753 Value *LOffset = EmitGEPOffset(GEPLHS);
754 Value *ROffset = EmitGEPOffset(GEPRHS);
755
756
757
758
761 if (LHSIndexTy != RHSIndexTy) {
764 ROffset = Builder.CreateTrunc(ROffset, LHSIndexTy);
765 } else
766 LOffset = Builder.CreateTrunc(LOffset, RHSIndexTy);
767 }
768
770 LOffset, ROffset);
772 }
773 }
774
775 if (GEPLHS->getOperand(0) == GEPRHS->getOperand(0) &&
776 GEPLHS->getNumOperands() == GEPRHS->getNumOperands() &&
778
779 unsigned NumDifferences = 0;
780 unsigned DiffOperand = 0;
781 for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
782 if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) {
784 Type *RHSType = GEPRHS->getOperand(i)->getType();
785
790
791 NumDifferences = 2;
792 break;
793 }
794
795 if (NumDifferences++)
796 break;
797 DiffOperand = i;
798 }
799
800 if (NumDifferences == 0)
802 I,
804
805
808 Value *RHSV = GEPRHS->getOperand(DiffOperand);
809 return NewICmp(NW, LHSV, RHSV);
810 }
811 }
812
813 if (Base.Ptr && CanFold(Base.LHSNW & Base.RHSNW) && .isExpensive()) {
814
815 Type *IdxTy = DL.getIndexType(GEPLHS->getType());
817 EmitGEPOffsets(Base.LHSGEPs, Base.LHSNW, IdxTy, true);
819 EmitGEPOffsets(Base.RHSGEPs, Base.RHSNW, IdxTy, true);
820 return NewICmp(Base.LHSNW & Base.RHSNW, L, R);
821 }
822 }
823
824
825
827}
828
830
831
832
833
834
835
836
837
838
839
840
841
842
843
846 bool Captured = false;
847
848
850
851 CmpCaptureTracker(AllocaInst *Alloca) : Alloca(Alloca) {}
852
853 void tooManyUses() override { Captured = true; }
854
856
858
859
860
861
863
864
865 ICmps[ICmp] |= 1u << U->getOperandNo();
867 }
868
869 Captured = true;
870 return Stop;
871 }
872 };
873
874 CmpCaptureTracker Tracker(Alloca);
876 if (Tracker.Captured)
877 return false;
878
880 for (auto [ICmp, Operands] : Tracker.ICmps) {
881 switch (Operands) {
882 case 1:
883 case 2: {
884
885
886 auto *Res = ConstantInt::get(ICmp->getType(),
891 break;
892 }
893 case 3:
894
895
896
897 break;
898 default:
900 }
901 }
902
904}
905
906
909
910
911
912 assert(! && "C should not be zero!");
913
914
915
916
921 }
922
923
924
925
928 ConstantInt::get(X->getType(), -C));
929
931
932
933
934
935
936
937
940 ConstantInt::get(X->getType(), SMax - C));
941
942
943
944
945
946
947
948
951 ConstantInt::get(X->getType(), SMax - (C - 1)));
952}
953
954
955
956
958 const APInt &AP1,
959 const APInt &AP2) {
960 assert(I.isEquality() && "Cannot fold icmp gt/lt");
961
963 if (I.getPredicate() == I.ICMP_NE)
965 return new ICmpInst(Pred, LHS, RHS);
966 };
967
968
970 return nullptr;
971
973 if (IsAShr) {
975 return nullptr;
977 return nullptr;
978 if (AP2.sgt(AP1))
979 return nullptr;
980 }
981
982 if (!AP1)
983
984 return getICmp(I.ICMP_UGT, A,
985 ConstantInt::get(A->getType(), AP2.logBase2()));
986
987 if (AP1 == AP2)
989
990 int Shift;
993 else
995
996 if (Shift > 0) {
997 if (IsAShr && AP1 == AP2.ashr(Shift)) {
998
999
1001 return getICmp(I.ICMP_UGE, A, ConstantInt::get(A->getType(), Shift));
1002 return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));
1003 } else if (AP1 == AP2.lshr(Shift)) {
1004 return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));
1005 }
1006 }
1007
1008
1009
1010 auto *TorF = ConstantInt::get(I.getType(), I.getPredicate() == I.ICMP_NE);
1012}
1013
1014
1015
1017 const APInt &AP1,
1018 const APInt &AP2) {
1019 assert(I.isEquality() && "Cannot fold icmp gt/lt");
1020
1022 if (I.getPredicate() == I.ICMP_NE)
1024 return new ICmpInst(Pred, LHS, RHS);
1025 };
1026
1027
1029 return nullptr;
1030
1031 unsigned AP2TrailingZeros = AP2.countr_zero();
1032
1033 if (!AP1 && AP2TrailingZeros != 0)
1034 return getICmp(
1036 ConstantInt::get(A->getType(), AP2.getBitWidth() - AP2TrailingZeros));
1037
1038 if (AP1 == AP2)
1040
1041
1042 int Shift = AP1.countr_zero() - AP2TrailingZeros;
1043
1044 if (Shift > 0 && AP2.shl(Shift) == AP1)
1045 return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));
1046
1047
1048
1049 auto *TorF = ConstantInt::get(I.getType(), I.getPredicate() == I.ICMP_NE);
1051}
1052
1053
1054
1055
1056
1057
1058
1059
1063
1064
1065
1066
1067
1068
1069
1072 return nullptr;
1073
1074
1076 return nullptr;
1078 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)
1079 return nullptr;
1080
1081
1082 ++NewWidth;
1083
1084
1087 return nullptr;
1088
1089
1090
1091
1094 return nullptr;
1095
1096
1097
1098
1099
1101 for (User *U : OrigAdd->users()) {
1102 if (U == AddWithCst)
1103 continue;
1104
1105
1106
1107
1108
1109
1112 return nullptr;
1113 }
1114
1115
1116
1117
1120 I.getModule(), Intrinsic::sadd_with_overflow, NewType);
1121
1123
1124
1125
1127
1128 Value *TruncA = Builder.CreateTrunc(A, NewType, A->getName() + ".trunc");
1129 Value *TruncB = Builder.CreateTrunc(B, NewType, B->getName() + ".trunc");
1130 CallInst *Call = Builder.CreateCall(F, {TruncA, TruncB}, "sadd");
1131 Value *Add = Builder.CreateExtractValue(Call, 0, "sadd.result");
1132 Value *ZExt = Builder.CreateZExt(Add, OrigAdd->getType());
1133
1134
1135
1138
1139
1141}
1142
1143
1144
1145
1146
1148
1149 if (.isEquality())
1150 return nullptr;
1155 return nullptr;
1157 return nullptr;
1158
1162}
1163
1164
1165
1170 return nullptr;
1171
1174
1177 XTy = X->getType();
1180 APInt(XBitWidth, XBitWidth - 1))))
1181 return nullptr;
1185 true))) {
1186 XTy = X->getType();
1187 } else
1188 return nullptr;
1189
1194}
1195
1196
1199 if ((Cmp.getOperand(1), m_Zero()))
1200 return nullptr;
1201
1202
1207 return new ICmpInst(Pred, B, Cmp.getOperand(1));
1209 return new ICmpInst(Pred, A, Cmp.getOperand(1));
1210 }
1211 }
1212
1214 return New;
1215
1216
1217
1218
1219
1226 return new ICmpInst(Pred, X, Cmp.getOperand(1));
1227 }
1228
1229
1230
1233
1235
1236
1238 return new ICmpInst(Pred, Y, Cmp.getOperand(1));
1239
1241
1242
1244 return new ICmpInst(Pred, X, Cmp.getOperand(1));
1245
1247 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {
1249
1250
1251
1252
1253
1255 return new ICmpInst(Pred, Y, Cmp.getOperand(1));
1256
1257
1258
1260 return new ICmpInst(Pred, X, Cmp.getOperand(1));
1261 }
1262
1263
1264
1265
1266
1267
1268
1269
1270 }
1271
1272
1273
1276 return new ICmpInst(Pred, Stripped,
1278
1279 return nullptr;
1280}
1281
1282
1283
1284
1285
1289 const APInt *Mask, *Neg;
1290
1291 if ((&Cmp,
1296 return nullptr;
1297
1298 if (*Neg != ~*Mask)
1299 return nullptr;
1300
1302 return nullptr;
1303
1304
1305 auto *NewAnd = Builder.CreateAnd(Num, *Mask);
1307
1308 return new ICmpInst(Pred, NewAnd, Zero);
1309}
1310
1311
1312
1313
1314
1315
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1329 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);
1331 ConstantInt *CI, *CI2;
1335 return Res;
1336
1337
1339 if ()
1340 return nullptr;
1341
1345 for (Value *V : Phi->incoming_values()) {
1348 if (!Res)
1349 return nullptr;
1350 Ops.push_back(Res);
1351 }
1352 Builder.SetInsertPoint(Phi);
1353 PHINode *NewPhi = Builder.CreatePHI(Cmp.getType(), Phi->getNumOperands());
1354 for (auto [V, Pred] : zip(Ops, Phi->blocks()))
1357 }
1358
1360 return R;
1361
1362 return nullptr;
1363}
1364
1365
1367
1368
1369 Value *X = Cmp.getOperand(0), *Y = Cmp.getOperand(1);
1372 return nullptr;
1373
1376
1379
1380
1381
1382
1383
1384
1385
1394
1395
1396
1397
1398
1399
1400 bool UnusedBit;
1402 if (Cmp.isEquality() || (IsSignBit && hasBranchUse(Cmp)))
1403 return nullptr;
1404
1405
1406
1407 if (Cmp.hasOneUse() &&
1409 return nullptr;
1410
1415 return nullptr;
1416 };
1417
1420 const APInt *DomC;
1421 if ((BI->getCondition(),
1423 continue;
1424
1425 BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));
1426 if (DT.dominates(Edge0, Cmp.getParent())) {
1427 if (auto *V = handleDomCond(DomPred, DomC))
1428 return V;
1429 } else {
1430 BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));
1431 if (DT.dominates(Edge1, Cmp.getParent()))
1432 if (auto *V =
1434 return V;
1435 }
1436 }
1437
1438 return nullptr;
1439}
1440
1441
1447 Type *SrcTy = X->getType();
1449 SrcBits = SrcTy->getScalarSizeInBits();
1450
1451
1452
1453 if (shouldChangeType(Trunc->getType(), SrcTy)) {
1455 return new ICmpInst(Pred, X, ConstantInt::get(SrcTy, C.sext(SrcBits)));
1457 return new ICmpInst(Pred, X, ConstantInt::get(SrcTy, C.zext(SrcBits)));
1458 }
1459
1460 if (C.isOne() && C.getBitWidth() > 1) {
1461
1462 Value *V = nullptr;
1465 ConstantInt::get(V->getType(), 1));
1466 }
1467
1468
1470 const APInt *Pow2;
1472 DstBits > Pow2->logBase2()) {
1473
1474
1475
1476 if (C.isZero()) {
1477 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;
1479 ConstantInt::get(SrcTy, DstBits - Pow2->logBase2()));
1480 }
1481
1482
1483 if (C.isPowerOf2())
1485 Pred, Y, ConstantInt::get(SrcTy, C.logBase2() - Pow2->logBase2()));
1486 }
1487
1489
1490
1491 if (!SrcTy->isVectorTy() && shouldChangeType(DstBits, SrcBits)) {
1495 Constant *WideC = ConstantInt::get(SrcTy, C.zext(SrcBits));
1497 }
1498
1499
1500
1502
1503
1504 if ((Known.Zero | Known.One).countl_one() >= SrcBits - DstBits) {
1505
1506 APInt NewRHS = C.zext(SrcBits);
1508 return new ICmpInst(Pred, X, ConstantInt::get(SrcTy, NewRHS));
1509 }
1510 }
1511
1512
1513
1514
1517 bool TrueIfSigned;
1520 DstBits == SrcBits - ShAmt) {
1525 }
1526
1527 return nullptr;
1528}
1529
1530
1531
1537 bool YIsSExt = false;
1538
1540 unsigned NoWrapFlags = cast(Cmp.getOperand(0))->getNoWrapKind() &
1542 if (Cmp.isSigned()) {
1543
1545 return nullptr;
1546 } else {
1547
1548
1549 if (!NoWrapFlags)
1550 return nullptr;
1551 }
1552
1553 if (X->getType() != Y->getType() &&
1554 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))
1555 return nullptr;
1556 if (!isDesirableIntType(X->getType()->getScalarSizeInBits()) &&
1557 isDesirableIntType(Y->getType()->getScalarSizeInBits())) {
1559 Pred = Cmp.getSwappedPredicate(Pred);
1560 }
1562 }
1563
1564 else if (!Cmp.isSigned() &&
1567
1568 }
1569
1572
1573 YIsSExt =
1575 } else
1576 return nullptr;
1577
1578 Type *TruncTy = Cmp.getOperand(0)->getType();
1580
1581
1582
1583 if (isDesirableIntType(TruncBits) &&
1584 !isDesirableIntType(X->getType()->getScalarSizeInBits()))
1585 return nullptr;
1586
1587 Value *NewY = Builder.CreateIntCast(Y, X->getType(), YIsSExt);
1588 return new ICmpInst(Pred, X, NewY);
1589}
1590
1591
1596 return I;
1597
1600 const APInt *XorC;
1602 return nullptr;
1603
1604
1605
1607 bool TrueIfSigned = false;
1608 if (isSignBitCheck(Cmp.getPredicate(), C, TrueIfSigned)) {
1609
1610
1611
1614
1615
1616 if (TrueIfSigned)
1619 else
1622 }
1623
1624 if (Xor->hasOneUse()) {
1625
1626 if (!Cmp.isEquality() && XorC->isSignMask()) {
1627 Pred = Cmp.getFlippedSignednessPredicate();
1628 return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), C ^ *XorC));
1629 }
1630
1631
1633 Pred = Cmp.getFlippedSignednessPredicate();
1634 Pred = Cmp.getSwappedPredicate(Pred);
1635 return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), C ^ *XorC));
1636 }
1637 }
1638
1639
1641
1642 if (*XorC == ~C && (C + 1).isPowerOf2())
1644
1645 if (*XorC == C && (C + 1).isPowerOf2())
1647 }
1649
1650 if (*XorC == -C && C.isPowerOf2())
1652 ConstantInt::get(X->getType(), ~C));
1653
1654 if (*XorC == C && (-C).isPowerOf2())
1656 ConstantInt::get(X->getType(), ~C));
1657 }
1658 return nullptr;
1659}
1660
1661
1662
1663
1670 PowerOf2 = C;
1672 PowerOf2 = C + 1;
1673 else
1674 return nullptr;
1676 return nullptr;
1678 const APInt *ShiftC;
1681 return nullptr;
1683 Type *XType = X->getType();
1685 return nullptr;
1686 Value *Add = Builder.CreateAdd(X, ConstantInt::get(XType, PowerOf2));
1689 return new ICmpInst(Pred, Add, ConstantInt::get(XType, Bound));
1690}
1691
1692
1695 const APInt &C1,
1696 const APInt &C2) {
1698 if (!Shift || !Shift->isShift())
1699 return nullptr;
1700
1701
1702
1703
1704
1705
1706 unsigned ShiftOpcode = Shift->getOpcode();
1707 bool IsShl = ShiftOpcode == Instruction::Shl;
1708 const APInt *C3;
1710 APInt NewAndCst, NewCmpCst;
1711 bool AnyCmpCstBitsShiftedOut;
1712 if (ShiftOpcode == Instruction::Shl) {
1713
1714
1715
1716
1718 return nullptr;
1719
1720 NewCmpCst = C1.lshr(*C3);
1721 NewAndCst = C2.lshr(*C3);
1722 AnyCmpCstBitsShiftedOut = NewCmpCst.shl(*C3) != C1;
1723 } else if (ShiftOpcode == Instruction::LShr) {
1724
1725
1726
1727
1728 NewCmpCst = C1.shl(*C3);
1729 NewAndCst = C2.shl(*C3);
1730 AnyCmpCstBitsShiftedOut = NewCmpCst.lshr(*C3) != C1;
1732 return nullptr;
1733 } else {
1734
1735
1736 assert(ShiftOpcode == Instruction::AShr && "Unknown shift opcode");
1737 NewCmpCst = C1.shl(*C3);
1738 NewAndCst = C2.shl(*C3);
1739 AnyCmpCstBitsShiftedOut = NewCmpCst.ashr(*C3) != C1;
1740 if (NewAndCst.ashr(*C3) != C2)
1741 return nullptr;
1742 }
1743
1744 if (AnyCmpCstBitsShiftedOut) {
1745
1746
1747
1752 } else {
1754 Shift->getOperand(0), ConstantInt::get(And->getType(), NewAndCst));
1755 return new ICmpInst(Cmp.getPredicate(), NewAnd,
1756 ConstantInt::get(And->getType(), NewCmpCst));
1757 }
1758 }
1759
1760
1761
1762
1763 if (Shift->hasOneUse() && C1.isZero() && Cmp.isEquality() &&
1766
1767 Value *NewShift =
1770
1771
1773 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1774 }
1775
1776 return nullptr;
1777}
1778
1779
1782 const APInt &C1) {
1784
1785
1786
1787
1788 if (isICMP_NE && Cmp.getType()->isVectorTy() && C1.isZero() &&
1790 return new TruncInst(And->getOperand(0), Cmp.getType());
1791
1792 const APInt *C2;
1795 return nullptr;
1796
1797
1801 ConstantInt::get(X->getType(), ~*C2));
1802
1806 ConstantInt::get(X->getType(), -*C2));
1807
1808
1809 if (->hasOneUse())
1810 return nullptr;
1811
1812 if (Cmp.isEquality() && C1.isZero()) {
1813
1814
1818 return new ICmpInst(NewPred, X, Zero);
1819 }
1820
1821 APInt NewC2 = *C2;
1823
1826
1827
1828
1830 Constant *NegBOC = ConstantInt::get(And->getType(), -NewC2);
1832 return new ICmpInst(NewPred, X, NegBOC);
1833 }
1834 }
1835
1836
1837
1838
1839
1840
1841
1842
1843
1847
1848
1849
1850 if (!Cmp.getType()->isVectorTy()) {
1851 Type *WideType = W->getType();
1853 Constant *ZextC1 = ConstantInt::get(WideType, C1.zext(WideScalarBits));
1854 Constant *ZextC2 = ConstantInt::get(WideType, C2->zext(WideScalarBits));
1855 Value *NewAnd = Builder.CreateAnd(W, ZextC2, And->getName());
1856 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);
1857 }
1858 }
1859
1861 return I;
1862
1863
1864
1865
1866
1867 if (!Cmp.isSigned() && C1.isZero() && And->getOperand(0)->hasOneUse() &&
1874 unsigned UsesRemoved = 0;
1875 if (And->hasOneUse())
1876 ++UsesRemoved;
1877 if (Or->hasOneUse())
1878 ++UsesRemoved;
1880 ++UsesRemoved;
1881
1882
1884 if (UsesRemoved >= RequireUsesRemoved) {
1887 true),
1888 One, Or->getName());
1889 Value *NewAnd = Builder.CreateAnd(A, NewOr, And->getName());
1890 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
1891 }
1892 }
1893 }
1894
1895
1896
1897
1898
1899
1900
1901
1902
1904 if (!Cmp.getParent()->getParent()->hasFnAttribute(
1905 Attribute::NoImplicitFloat) &&
1906 Cmp.isEquality() &&
1908 Type *FPType = V->getType()->getScalarType();
1909 if (FPType->isIEEELikeFPTy() && (C1.isZero() || C1 == *C2)) {
1910 APInt ExponentMask =
1912 if (*C2 == ExponentMask) {
1913 unsigned Mask = C1.isZero()
1916 if (isICMP_NE)
1919 }
1920 }
1921 }
1922
1923 return nullptr;
1924}
1925
1926
1931 return I;
1932
1934 bool TrueIfNeg;
1936
1937
1943 }
1944
1945
1947 Constant *MinSignedC = ConstantInt::get(
1948 X->getType(),
1951 return new ICmpInst(NewPred, X, MinSignedC);
1952 }
1953 }
1954
1955
1956
1957
1964 return Res;
1965
1966 if (!Cmp.isEquality())
1967 return nullptr;
1968
1969
1970
1971
1972 if (Cmp.getOperand(1) == Y && C.isNegatedPowerOf2()) {
1973 auto NewPred =
1976 }
1977
1978
1979
1980
1981
1983 X->getType()->isIntOrIntVectorTy(1) && (C.isZero() || C.isOne())) {
1984 Value *TruncY = Builder.CreateTrunc(Y, X->getType());
1988 }
1989 return BinaryOperator::CreateAnd(TruncY, X);
1990 }
1991
1992
1993
1994
1995
1996 if (C.isZero() &&
2001 }
2002
2003
2004
2005 {
2007 const APInt *Addend, *Msk;
2010 C.ule(*Msk)) {
2011 APInt NewComperand = (C - *Addend) & *Msk;
2012 Value *MaskA = Builder.CreateAnd(A, ConstantInt::get(A->getType(), *Msk));
2013 return new ICmpInst(Pred, MaskA,
2014 ConstantInt::get(MaskA->getType(), NewComperand));
2015 }
2016 }
2017
2018 return nullptr;
2019}
2020
2021
2024
2025
2026
2027
2028
2029
2030
2031
2032
2035
2036 while (!WorkList.empty()) {
2037 auto MatchOrOperatorArgument = [&](Value *OrOperatorArgument) {
2038 Value *Lhs, *Rhs;
2039
2040 if (match(OrOperatorArgument,
2043 return;
2044 }
2045
2046 if (match(OrOperatorArgument,
2049 return;
2050 }
2051
2052 WorkList.push_back(OrOperatorArgument);
2053 };
2054
2056 Value *OrOperatorLhs, *OrOperatorRhs;
2057
2058 if ((CurrentValue,
2060 return nullptr;
2061 }
2062
2063 MatchOrOperatorArgument(OrOperatorRhs);
2064 MatchOrOperatorArgument(OrOperatorLhs);
2065 }
2066
2068 auto BOpc = Pred == CmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;
2069 Value *LhsCmp = Builder.CreateICmp(Pred, CmpValues.rbegin()->first,
2070 CmpValues.rbegin()->second);
2071
2072 for (auto It = CmpValues.rbegin() + 1; It != CmpValues.rend(); ++It) {
2073 Value *RhsCmp = Builder.CreateICmp(Pred, It->first, It->second);
2074 LhsCmp = Builder.CreateBinOp(BOpc, LhsCmp, RhsCmp);
2075 }
2076
2077 return LhsCmp;
2078}
2079
2080
2085 if (C.isOne()) {
2086
2087 Value *V = nullptr;
2090 ConstantInt::get(V->getType(), 1));
2091 }
2092
2093 Value *OrOp0 = Or->getOperand(0), *OrOp1 = Or->getOperand(1);
2094
2095
2096
2100 Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(), C));
2101 return new ICmpInst(Pred, OrOp0, NewC);
2102 }
2103
2104 const APInt *MaskC;
2105 if (match(OrOp1, m_APInt(MaskC)) && Cmp.isEquality()) {
2106 if (*MaskC == C && (C + 1).isPowerOf2()) {
2107
2108
2109
2111 return new ICmpInst(Pred, OrOp0, OrOp1);
2112 }
2113
2114
2115
2116
2117
2118 if (Or->hasOneUse()) {
2120 Constant *NewC = ConstantInt::get(Or->getType(), C ^ (*MaskC));
2122 }
2123 }
2124
2125
2126
2128 bool TrueIfSigned;
2132 Constant *NewC = ConstantInt::get(X->getType(), TrueIfSigned ? 1 : 0);
2133 return new ICmpInst(NewPred, X, NewC);
2134 }
2135
2136 const APInt *OrC;
2137
2139 switch (Pred) {
2140
2142
2146 break;
2147
2149
2154 break;
2155 default:
2156 break;
2157 }
2158 }
2159
2160 if (!Cmp.isEquality() || .isZero() ||
->hasOneUse())
2161 return nullptr;
2162
2165
2166
2171 auto BOpc = Pred == CmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;
2173 }
2174
2177
2178 return nullptr;
2179}
2180
2181
2186 Type *MulTy = Mul->getType();
2188
2189
2190
2191
2192 if (Cmp.isEquality() && C.isZero() && X == Mul->getOperand(1) &&
2193 (Mul->hasNoUnsignedWrap() || Mul->hasNoSignedWrap()))
2195
2196 const APInt *MulC;
2198 return nullptr;
2199
2200
2201
2202
2203
2204 if (isSignTest(Pred, C) && Mul->hasNoSignedWrap()) {
2208 }
2209
2211 return nullptr;
2212
2213
2214
2215 if (Cmp.isEquality()) {
2216
2217 if (Mul->hasNoSignedWrap() && C.srem(*MulC).isZero()) {
2218 Constant *NewC = ConstantInt::get(MulTy, C.sdiv(*MulC));
2219 return new ICmpInst(Pred, X, NewC);
2220 }
2221
2222
2223
2224
2225
2226 if (C.urem(*MulC).isZero()) {
2227
2228
2229 if ((*MulC & 1).isOne() || Mul->hasNoUnsignedWrap()) {
2230 Constant *NewC = ConstantInt::get(MulTy, C.udiv(*MulC));
2231 return new ICmpInst(Pred, X, NewC);
2232 }
2233 }
2234 }
2235
2236
2237
2238
2239
2242
2243 if (C.isMinSignedValue() && MulC->isAllOnes())
2244 return nullptr;
2247
2249 NewC = ConstantInt::get(
2251 } else {
2253 "Unexpected predicate");
2254 NewC = ConstantInt::get(
2256 }
2259 NewC = ConstantInt::get(
2261 } else {
2263 "Unexpected predicate");
2264 NewC = ConstantInt::get(
2266 }
2267 }
2268
2269 return NewC ? new ICmpInst(Pred, X, NewC) : nullptr;
2270}
2271
2272
2276 const APInt *C2;
2278 return nullptr;
2279
2281 unsigned TypeBits = C.getBitWidth();
2283 if (Cmp.isUnsigned()) {
2285 return nullptr;
2289
2290
2291 if (!CIsPowerOf2) {
2292
2293
2294
2295
2300 }
2301
2302 unsigned CLog2 = Div.logBase2();
2303 return new ICmpInst(Pred, Y, ConstantInt::get(ShiftType, CLog2));
2304 } else if (Cmp.isSigned() && C2->isOne()) {
2305 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);
2306
2307
2310
2311
2312
2313
2314
2317 }
2318
2319 return nullptr;
2320}
2321
2322
2326 const APInt *ShiftVal;
2329
2331
2332
2333
2334
2335
2338
2339
2340
2344
2345
2346
2347
2348
2349
2350
2355
2356 const APInt *ShiftAmt;
2359
2360
2361
2362 unsigned TypeBits = C.getBitWidth();
2363 if (ShiftAmt->uge(TypeBits))
2364 return nullptr;
2365
2368
2369
2370
2371
2374
2375 APInt ShiftedC = C.ashr(*ShiftAmt);
2376 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));
2377 }
2379 C.ashr(*ShiftAmt).shl(*ShiftAmt) == C) {
2380 APInt ShiftedC = C.ashr(*ShiftAmt);
2381 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));
2382 }
2384
2385
2386
2387
2388 assert(.isMinSignedValue() && "Unexpected icmp slt");
2389 APInt ShiftedC = (C - 1).ashr(*ShiftAmt) + 1;
2390 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));
2391 }
2392 }
2393
2394
2395
2396
2399
2400 APInt ShiftedC = C.lshr(*ShiftAmt);
2401 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));
2402 }
2404 C.lshr(*ShiftAmt).shl(*ShiftAmt) == C) {
2405 APInt ShiftedC = C.lshr(*ShiftAmt);
2406 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));
2407 }
2409
2410
2411
2412
2413 assert(C.ugt(0) && "ult 0 should have been eliminated");
2414 APInt ShiftedC = (C - 1).lshr(*ShiftAmt) + 1;
2415 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));
2416 }
2417 }
2418
2419 if (Cmp.isEquality() && Shl->hasOneUse()) {
2420
2421 Constant *Mask = ConstantInt::get(
2422 ShType,
2425 Constant *LShrC = ConstantInt::get(ShType, C.lshr(*ShiftAmt));
2427 }
2428
2429
2430 bool TrueIfSigned = false;
2432
2433 Constant *Mask = ConstantInt::get(
2434 ShType,
2439 }
2440
2441
2442 if (Cmp.isUnsigned() && Shl->hasOneUse()) {
2443
2444 if ((C + 1).isPowerOf2() &&
2450 }
2451
2452 if (C.isPowerOf2() &&
2459 }
2460 }
2461
2462
2463
2464
2465
2466
2467
2469 if (Shl->hasOneUse() && Amt != 0 &&
2473
2475
2476
2477
2478
2479
2480
2482 Pred, ConstantInt::get(ShType->getContext(), C))) {
2483 CmpPred = FlippedStrictness->first;
2484 RHSC = cast(FlippedStrictness->second)->getValue();
2485 }
2486 }
2487
2491 ConstantInt::get(TruncTy, RHSC.ashr(*ShiftAmt).trunc(TypeBits - Amt));
2492 return new ICmpInst(CmpPred,
2493 Builder.CreateTrunc(X, TruncTy, "", false,
2495 NewC);
2496 }
2497 }
2498
2499 return nullptr;
2500}
2501
2502
2506
2507
2510 if (Cmp.isEquality() && Shr->isExact() && C.isZero())
2511 return new ICmpInst(Pred, X, Cmp.getOperand(1));
2512
2513 bool IsAShr = Shr->getOpcode() == Instruction::AShr;
2514 const APInt *ShiftValC;
2516 if (Cmp.isEquality())
2518
2519
2520
2521 bool TrueIfSigned;
2522 if (!IsAShr && ShiftValC->isNegative() &&
2527
2528
2529
2530
2531 if (!IsAShr && ShiftValC->isPowerOf2() &&
2534 assert(ShiftValC->uge(C) && "Expected simplify of compare");
2535 assert((IsUGT || .isZero()) && "Expected X u< 0 to simplify");
2536
2537 unsigned CmpLZ = IsUGT ? C.countl_zero() : (C - 1).countl_zero();
2538 unsigned ShiftLZ = ShiftValC->countl_zero();
2539 Constant *NewC = ConstantInt::get(Shr->getType(), CmpLZ - ShiftLZ);
2542 }
2543 }
2544
2545 const APInt *ShiftAmtC;
2547 return nullptr;
2548
2549
2550
2551 unsigned TypeBits = C.getBitWidth();
2552 unsigned ShAmtVal = ShiftAmtC->getLimitedValue(TypeBits);
2553 if (ShAmtVal >= TypeBits || ShAmtVal == 0)
2554 return nullptr;
2555
2556 bool IsExact = Shr->isExact();
2558
2559
2560
2561
2562 if (IsAShr && Shr->hasOneUse()) {
2564 (C - 1).isPowerOf2() && C.countLeadingZeros() > ShAmtVal) {
2565
2566
2567
2568
2569
2570 APInt ShiftedC = (C - 1).shl(ShAmtVal) + 1;
2571 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
2572 }
2574
2575
2576
2577 APInt ShiftedC = C.shl(ShAmtVal);
2578 if (ShiftedC.ashr(ShAmtVal) == C)
2579 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
2580 }
2582
2583 APInt ShiftedC = (C + 1).shl(ShAmtVal) - 1;
2584 if (.isMaxSignedValue() && !(C + 1).shl(ShAmtVal).isMinSignedValue() &&
2585 (ShiftedC + 1).ashr(ShAmtVal) == (C + 1))
2586 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
2587 }
2589
2590
2591
2592 APInt ShiftedC = (C + 1).shl(ShAmtVal) - 1;
2593 if ((ShiftedC + 1).ashr(ShAmtVal) == (C + 1) ||
2594 (C + 1).shl(ShAmtVal).isMinSignedValue())
2595 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
2596 }
2597
2598
2599
2600
2601
2602 if (C.getBitWidth() > 2 && C.getNumSignBits() <= ShAmtVal) {
2606 }
2610 }
2611 }
2612 } else if (!IsAShr) {
2614
2615
2616 APInt ShiftedC = C.shl(ShAmtVal);
2617 if (ShiftedC.lshr(ShAmtVal) == C)
2618 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
2619 }
2621
2622 APInt ShiftedC = (C + 1).shl(ShAmtVal) - 1;
2623 if ((ShiftedC + 1).lshr(ShAmtVal) == (C + 1))
2624 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));
2625 }
2626 }
2627
2628 if (!Cmp.isEquality())
2629 return nullptr;
2630
2631
2632
2633
2634
2635
2636 assert(((IsAShr && C.shl(ShAmtVal).ashr(ShAmtVal) == C) ||
2637 (!IsAShr && C.shl(ShAmtVal).lshr(ShAmtVal) == C)) &&
2638 "Expected icmp+shr simplify did not occur.");
2639
2640
2641
2643 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, C << ShAmtVal));
2644
2646
2647
2649 Constant *Mask = ConstantInt::get(ShrTy, Val);
2651 return new ICmpInst(Pred, And, ConstantInt::get(ShrTy, C << ShAmtVal));
2652 }
2653
2654 return nullptr;
2655}
2656
2662
2663
2664
2665
2666
2667
2668 const APInt *DivisorC;
2670 return nullptr;
2671
2675 "ult X, 0 should have been simplified already.");
2676 --NormalizedC;
2677 }
2678 if (C.isNegative())
2681 "srem X, 0 should have been simplified already.");
2682 if (!NormalizedC.uge(DivisorC->abs() - 1))
2683 return nullptr;
2684
2691 }
2692
2693
2694
2697 return nullptr;
2698
2699
2700
2701
2703 return nullptr;
2704
2705 const APInt *DivisorC;
2707 return nullptr;
2708
2709
2710
2712 .isZero()) ||
2714 .isStrictlyPositive()))
2715 return nullptr;
2716
2717
2720 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));
2722
2724 return new ICmpInst(Pred, And, ConstantInt::get(Ty, C));
2725
2726
2727
2728
2731
2732
2733
2734
2736}
2737
2738
2746
2747 const APInt *C2;
2749 return nullptr;
2750
2751 assert(*C2 != 0 && "udiv 0, X should have been simplified already.");
2752
2753
2755 assert(.isMaxValue() &&
2756 "icmp ugt X, UINT_MAX should have been simplified already.");
2758 ConstantInt::get(Ty, C2->udiv(C + 1)));
2759 }
2760
2761
2763 assert(C != 0 && "icmp ult X, 0 should have been simplified already.");
2765 ConstantInt::get(Ty, C2->udiv(C)));
2766 }
2767
2768 return nullptr;
2769}
2770
2771
2779 bool DivIsSigned = Div->getOpcode() == Instruction::SDiv;
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789 if (Cmp.isEquality() && Div->hasOneUse() && C.isSignBitSet() &&
2790 (!DivIsSigned || C.isMinSignedValue())) {
2791 Value *XBig = Builder.CreateICmp(Pred, X, ConstantInt::get(Ty, C));
2792 Value *YOne = Builder.CreateICmp(Pred, Y, ConstantInt::get(Ty, 1));
2793 auto Logic = Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;
2795 }
2796
2797
2798
2799
2800
2801
2802
2803 const APInt *C2;
2805 return nullptr;
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned())
2816 return nullptr;
2817
2818
2819
2820
2821
2823 return nullptr;
2824
2825
2826
2827
2828
2830
2831
2832
2833
2834 bool ProdOV = (DivIsSigned ? Prod.sdiv(*C2) : Prod.udiv(*C2)) != C;
2835
2836
2837
2839
2840
2841
2842
2843
2844
2845
2846
2847 int LoOverflow = 0, HiOverflow = 0;
2848 APInt LoBound, HiBound;
2849
2850 if (!DivIsSigned) {
2851
2852 LoBound = Prod;
2853 HiOverflow = LoOverflow = ProdOV;
2854 if (!HiOverflow) {
2855
2856
2857 HiOverflow = addWithOverflow(HiBound, LoBound, RangeSize, false);
2858 }
2860 if (C.isZero()) {
2861
2862 LoBound = -(RangeSize - 1);
2863 HiBound = RangeSize;
2864 } else if (C.isStrictlyPositive()) {
2865 LoBound = Prod;
2866 HiOverflow = LoOverflow = ProdOV;
2867 if (!HiOverflow)
2868 HiOverflow = addWithOverflow(HiBound, Prod, RangeSize, true);
2869 } else {
2870
2871 HiBound = Prod + 1;
2872 LoOverflow = HiOverflow = ProdOV ? -1 : 0;
2873 if (!LoOverflow) {
2874 APInt DivNeg = -RangeSize;
2875 LoOverflow = addWithOverflow(LoBound, HiBound, DivNeg, true) ? -1 : 0;
2876 }
2877 }
2878 } else if (C2->isNegative()) {
2881 if (C.isZero()) {
2882
2883 LoBound = RangeSize + 1;
2884 HiBound = -RangeSize;
2885 if (HiBound == *C2) {
2886 HiOverflow = 1;
2887 HiBound = APInt();
2888 }
2889 } else if (C.isStrictlyPositive()) {
2890
2891 HiBound = Prod + 1;
2892 HiOverflow = LoOverflow = ProdOV ? -1 : 0;
2893 if (!LoOverflow)
2894 LoOverflow =
2895 addWithOverflow(LoBound, HiBound, RangeSize, true) ? -1 : 0;
2896 } else {
2897 LoBound = Prod;
2898 LoOverflow = HiOverflow = ProdOV;
2899 if (!HiOverflow)
2900 HiOverflow = subWithOverflow(HiBound, Prod, RangeSize, true);
2901 }
2902
2903
2905 }
2906
2907 switch (Pred) {
2908 default:
2911 if (LoOverflow && HiOverflow)
2913 if (HiOverflow)
2915 X, ConstantInt::get(Ty, LoBound));
2916 if (LoOverflow)
2918 X, ConstantInt::get(Ty, HiBound));
2920 Cmp, insertRangeTest(X, LoBound, HiBound, DivIsSigned, true));
2922 if (LoOverflow && HiOverflow)
2924 if (HiOverflow)
2926 X, ConstantInt::get(Ty, LoBound));
2927 if (LoOverflow)
2929 X, ConstantInt::get(Ty, HiBound));
2931 Cmp, insertRangeTest(X, LoBound, HiBound, DivIsSigned, false));
2934 if (LoOverflow == +1)
2936 if (LoOverflow == -1)
2938 return new ICmpInst(Pred, X, ConstantInt::get(Ty, LoBound));
2941 if (HiOverflow == +1)
2943 if (HiOverflow == -1)
2948 }
2949
2950 return nullptr;
2951}
2952
2953
2957 Value *X = Sub->getOperand(0), *Y = Sub->getOperand(1);
2959 Type *Ty = Sub->getType();
2960
2961
2962
2967 }
2968
2969
2970 const APInt *C2;
2971 APInt SubResult;
2973 bool HasNSW = Sub->hasNoSignedWrap();
2974 bool HasNUW = Sub->hasNoUnsignedWrap();
2976 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&
2978 return new ICmpInst(SwappedPred, Y, ConstantInt::get(Ty, SubResult));
2979
2980
2981
2982
2983
2984
2985
2986 if (Cmp.isEquality() && C.isZero() &&
2987 none_of((Sub->users()), [](const User *U) { return isa(U); }))
2989
2990
2991
2992
2993
2994
2995 if (->hasOneUse())
2996 return nullptr;
2997
2998 if (Sub->hasNoSignedWrap()) {
2999
3002
3003
3006
3007
3010
3011
3014 }
3015
3017 return nullptr;
3018
3019
3020
3022 (*C2 & (C - 1)) == (C - 1))
3024
3025
3026
3029
3030
3031
3032
3033 Value *Add = Builder.CreateAdd(Y, ConstantInt::get(Ty, ~(*C2)), "notsub",
3034 HasNUW, HasNSW);
3035 return new ICmpInst(SwappedPred, Add, ConstantInt::get(Ty, ~C));
3036}
3037
3040 bool HasOneUse) {
3041 auto FoldConstant = [&](bool Val) {
3042 Constant *Res = Val ? Builder.getTrue() : Builder.getFalse();
3046 return Res;
3047 };
3048
3049 switch (Table.to_ulong()) {
3050 case 0:
3051 return FoldConstant(false);
3052 case 1:
3053 return HasOneUse ? Builder.CreateNot(Builder.CreateOr(Op0, Op1)) : nullptr;
3054 case 2:
3055 return HasOneUse ? Builder.CreateAnd(Builder.CreateNot(Op0), Op1) : nullptr;
3056 case 3:
3057 return Builder.CreateNot(Op0);
3058 case 4:
3059 return HasOneUse ? Builder.CreateAnd(Op0, Builder.CreateNot(Op1)) : nullptr;
3060 case 5:
3061 return Builder.CreateNot(Op1);
3062 case 6:
3063 return Builder.CreateXor(Op0, Op1);
3064 case 7:
3065 return HasOneUse ? Builder.CreateNot(Builder.CreateAnd(Op0, Op1)) : nullptr;
3066 case 8:
3067 return Builder.CreateAnd(Op0, Op1);
3068 case 9:
3069 return HasOneUse ? Builder.CreateNot(Builder.CreateXor(Op0, Op1)) : nullptr;
3070 case 10:
3071 return Op1;
3072 case 11:
3073 return HasOneUse ? Builder.CreateOr(Builder.CreateNot(Op0), Op1) : nullptr;
3074 case 12:
3075 return Op0;
3076 case 13:
3077 return HasOneUse ? Builder.CreateOr(Op0, Builder.CreateNot(Op1)) : nullptr;
3078 case 14:
3079 return Builder.CreateOr(Op0, Op1);
3080 case 15:
3081 return FoldConstant(true);
3082 default:
3084 }
3085 return nullptr;
3086}
3087
3091 Constant *C1, *C2, *C3, *C4;
3096 Cmp.getType() != A->getType())
3097 return nullptr;
3098
3099 std::bitset<4> Table;
3100 auto ComputeTable = [&](bool First, bool Second) -> std::optional {
3102 Constant *R = Second ? C3 : C4;
3104 auto *Val = Res->getType()->isVectorTy() ? Res->getSplatValue() : Res;
3107 }
3108 return std::nullopt;
3109 };
3110
3111 for (unsigned I = 0; I < 4; ++I) {
3112 bool First = (I >> 1) & 1;
3113 bool Second = I & 1;
3114 if (auto Res = ComputeTable(First, Second))
3115 Table[I] = *Res;
3116 else
3117 return nullptr;
3118 }
3119
3120
3123 return nullptr;
3124}
3125
3126
3132
3133 Value *Op0, *Op1;
3135 const CmpPredicate Pred = Cmp.getCmpPredicate();
3142 unsigned BW = C.getBitWidth();
3143 std::bitset<4> Table;
3144 auto ComputeTable = [&](bool Op0Val, bool Op1Val) {
3145 APInt Res(BW, 0);
3146 if (Op0Val)
3148 if (Op1Val)
3151 };
3152
3153 Table[0] = ComputeTable(false, false);
3154 Table[1] = ComputeTable(false, true);
3155 Table[2] = ComputeTable(true, false);
3156 Table[3] = ComputeTable(true, true);
3157 if (auto *Cond =
3160 }
3161 const APInt *C2;
3163 return nullptr;
3164
3165
3166 Type *Ty = Add->getType();
3167
3168
3169
3170
3171 if (Add->hasNoUnsignedWrap() &&
3173 bool Overflow;
3174 APInt NewC = C.usub_ov(*C2, Overflow);
3175
3176 if (!Overflow)
3177
3178 return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC));
3179 }
3180
3182
3183 if (Add->hasNoSignedWrap() &&
3185 bool Overflow;
3186 APInt NewC = C.ssub_ov(*C2, Overflow);
3187 if (!Overflow)
3188
3189
3190 return new ICmpInst(ChosenPred, X, ConstantInt::get(Ty, NewC));
3191 }
3192
3194 C.isNonNegative() && (C - *C2).isNonNegative() &&
3197 ConstantInt::get(Ty, C - *C2));
3198
3202 if (Cmp.isSigned()) {
3203 if (Lower.isSignMask())
3205 if (Upper.isSignMask())
3207 } else {
3208 if (Lower.isMinValue())
3210 if (Upper.isMinValue())
3212 }
3213
3214
3215
3218
3219
3220
3223
3224
3227
3228
3231
3232
3235
3236
3241 }
3242
3243 if (->hasOneUse())
3244 return nullptr;
3245
3246
3247
3248
3252
3253
3254
3255
3258 ConstantInt::get(Ty, C * 2));
3259
3260
3261
3262
3266
3267
3268
3269
3272 Builder.CreateAdd(X, ConstantInt::get(Ty, *C2 - C - 1)),
3273 ConstantInt::get(Ty, ~C));
3274
3275
3278 Type *NewCmpTy = V->getType();
3280 if (shouldChangeType(Ty, NewCmpTy)) {
3284 APInt EquivOffset;
3285
3288 EquivPred,
3289 EquivOffset.isZero()
3290 ? V
3291 : Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),
3292 ConstantInt::get(NewCmpTy, EquivInt));
3293 }
3294 }
3295
3296 return nullptr;
3297}
3298
3303
3304
3305
3306
3307
3308
3309
3313 return false;
3314 Value *EqualVal = SI->getTrueValue();
3315 Value *UnequalVal = SI->getFalseValue();
3316
3318 std::swap(EqualVal, UnequalVal);
3320 return false;
3322 Value *LHS2, *RHS2;
3325 return false;
3326
3327
3328 if (LHS2 != LHS) {
3329
3332 }
3333 if (LHS2 != LHS)
3334 return false;
3335
3337
3338 auto FlippedStrictness =
3340 if (!FlippedStrictness)
3341 return false;
3343 "basic correctness failure");
3344 RHS2 = FlippedStrictness->second;
3345
3348 }
3350}
3351
3355
3356 assert(C && "Cmp RHS should be a constant int!");
3357
3358
3359
3360
3361
3362 Value *OrigLHS, *OrigRHS;
3363 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;
3364 if (Cmp.hasOneUse() &&
3366 C3GreaterThan)) {
3367 assert(C1LessThan && C2Equal && C3GreaterThan);
3368
3370 C1LessThan->getValue(), C->getValue(), Cmp.getPredicate());
3372 Cmp.getPredicate());
3374 C3GreaterThan->getValue(), C->getValue(), Cmp.getPredicate());
3375
3376
3377
3378
3379
3380
3381
3382
3383
3385 if (TrueWhenLessThan)
3388 if (TrueWhenEqual)
3391 if (TrueWhenGreaterThan)
3394
3396 }
3397 return nullptr;
3398}
3399
3402 if (!Bitcast)
3403 return nullptr;
3404
3406 Value *Op1 = Cmp.getOperand(1);
3407 Value *BCSrcOp = Bitcast->getOperand(0);
3408 Type *SrcType = Bitcast->getSrcTy();
3409 Type *DstType = Bitcast->getType();
3410
3411
3412
3413 if (SrcType->isVectorTy() == DstType->isVectorTy() &&
3414 SrcType->getScalarSizeInBits() == DstType->getScalarSizeInBits()) {
3415
3418
3419
3420
3421
3426
3427
3429 return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), 1));
3430
3431
3435 }
3436
3437
3438
3439
3441 if (Cmp.isEquality() && match(Op1, m_Zero()))
3443
3445 bool TrueIfSigned;
3446 if (match(Op1, m_APInt(C)) && Bitcast->hasOneUse()) {
3447
3448
3449
3450
3454
3455
3456 Type *XType = X->getType();
3457
3458
3459 if (!(XType->isPPC_FP128Ty() || SrcType->isPPC_FP128Ty())) {
3462 NewType = VectorType::get(NewType, XVTy->getElementCount());
3463 Value *NewBitcast = Builder.CreateBitCast(X, NewType);
3464 if (TrueIfSigned)
3467 else
3470 }
3471 }
3472
3473
3474 Type *FPType = SrcType->getScalarType();
3475 if (!Cmp.getParent()->getParent()->hasFnAttribute(
3476 Attribute::NoImplicitFloat) &&
3477 Cmp.isEquality() && FPType->isIEEELikeFPTy()) {
3481 Mask = ~Mask;
3483 Builder.createIsFPClass(BCSrcOp, Mask));
3484 }
3485 }
3486 }
3487 }
3488
3490 if ((Cmp.getOperand(1), m_APInt(C)) || !DstType->isIntegerTy() ||
3491 !SrcType->isIntOrIntVectorTy())
3492 return nullptr;
3493
3494
3495
3496
3497
3498
3499
3500
3501 if (Cmp.isEquality() && C->isAllOnes() && Bitcast->hasOneUse()) {
3502 if (Value *NotBCSrcOp =
3504 Value *Cast = Builder.CreateBitCast(NotBCSrcOp, DstType);
3506 }
3507 }
3508
3509
3510
3511
3513 if (Cmp.isEquality() && C->isZero() && Bitcast->hasOneUse() &&
3516 Type *NewType = Builder.getIntNTy(VecTy->getPrimitiveSizeInBits());
3517 Value *NewCast = Builder.CreateBitCast(X, NewType);
3519 }
3520 }
3521
3522
3523
3524
3525
3526
3527
3528
3532
3536 if (C->isSplat(EltTy->getBitWidth())) {
3537
3538
3539
3540
3541
3543 Value *Extract = Builder.CreateExtractElement(Vec, Elem);
3544 Value *NewC = ConstantInt::get(EltTy, C->trunc(EltTy->getBitWidth()));
3545 return new ICmpInst(Pred, Extract, NewC);
3546 }
3547 }
3548 }
3549 return nullptr;
3550}
3551
3552
3553
3556
3560 return I;
3561
3563
3564
3565
3568 return I;
3569
3572 return I;
3573
3576 return I;
3577
3578
3579
3580
3581 Value *Cmp0 = Cmp.getOperand(0);
3583 if (C->isZero() && Cmp.isEquality() && Cmp0->hasOneUse() &&
3590 return new ICmpInst(Cmp.getPredicate(), X, Y);
3591 }
3592
3595
3596 return nullptr;
3597}
3598
3599
3600
3603
3604
3605 if (!Cmp.isEquality())
3606 return nullptr;
3607
3612
3614 case Instruction::SRem:
3615
3616 if (C.isZero() && BO->hasOneUse()) {
3617 const APInt *BOC;
3620 return new ICmpInst(Pred, NewRem,
3622 }
3623 }
3624 break;
3625 case Instruction::Add: {
3626
3627
3628
3632 } else if (C.isZero()) {
3633
3634
3635 if (Value *NegVal = dyn_castNegVal(BOp1))
3636 return new ICmpInst(Pred, BOp0, NegVal);
3637 if (Value *NegVal = dyn_castNegVal(BOp0))
3638 return new ICmpInst(Pred, NegVal, BOp1);
3640
3644 }
3647 return new ICmpInst(Pred, BOp0, Neg);
3648 }
3649 }
3650 break;
3651 }
3652 case Instruction::Xor:
3654
3655
3657 } else if (C.isZero()) {
3658
3659 return new ICmpInst(Pred, BOp0, BOp1);
3660 }
3661 break;
3662 case Instruction::Or: {
3663 const APInt *BOC;
3665
3666
3667
3671 }
3672
3673
3674
3675
3677 if (C.isZero() &&
3683 Cond->getType() == Cmp.getType()) {
3685
3692 Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or, Cmp,
3694 }
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3715 Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or, Cmp,
3716 NotCond);
3717 }
3718 }
3719 break;
3720 }
3721 case Instruction::UDiv:
3722 case Instruction::SDiv:
3724
3725
3726
3727
3728
3729 if (C.isZero())
3731 else if (C.isOne())
3732 return new ICmpInst(Pred, BOp0, BOp1);
3735 Instruction::Mul, BO->getOpcode() == Instruction::SDiv, BOp1,
3736 Cmp.getOperand(1), BO);
3739 Builder.CreateMul(BOp1, ConstantInt::get(BO->getType(), C));
3740 return new ICmpInst(Pred, YC, BOp0);
3741 }
3742 }
3743 }
3744 if (BO->getOpcode() == Instruction::UDiv && C.isZero()) {
3745
3747 return new ICmpInst(NewPred, BOp1, BOp0);
3748 }
3749 break;
3750 default:
3751 break;
3752 }
3753 return nullptr;
3754}
3755
3757 const APInt &CRhs,
3761 "Non-ctpop intrin in ctpop fold");
3763 return nullptr;
3764
3765
3766
3767
3768
3769
3770
3771
3772
3778
3780 Value *And = Builder.CreateAnd(
3787 }
3788 }
3789
3790 return nullptr;
3791}
3792
3793
3796 Type *Ty = II->getType();
3797 unsigned BitWidth = C.getBitWidth();
3799
3800 switch (II->getIntrinsicID()) {
3801 case Intrinsic::abs:
3802
3803
3804 if (C.isZero() || C.isMinSignedValue())
3805 return new ICmpInst(Pred, II->getArgOperand(0), ConstantInt::get(Ty, C));
3806 break;
3807
3808 case Intrinsic::bswap:
3809
3810 return new ICmpInst(Pred, II->getArgOperand(0),
3811 ConstantInt::get(Ty, C.byteSwap()));
3812
3813 case Intrinsic::bitreverse:
3814
3815 return new ICmpInst(Pred, II->getArgOperand(0),
3816 ConstantInt::get(Ty, C.reverseBits()));
3817
3818 case Intrinsic::ctlz:
3819 case Intrinsic::cttz: {
3820
3822 return new ICmpInst(Pred, II->getArgOperand(0),
3824
3825
3826
3827
3828 unsigned Num = C.getLimitedValue(BitWidth);
3829 if (Num != BitWidth && II->hasOneUse()) {
3830 bool IsTrailing = II->getIntrinsicID() == Intrinsic::cttz;
3833 APInt Mask2 = IsTrailing
3836 return new ICmpInst(Pred, Builder.CreateAnd(II->getArgOperand(0), Mask1),
3837 ConstantInt::get(Ty, Mask2));
3838 }
3839 break;
3840 }
3841
3842 case Intrinsic::ctpop: {
3843
3844
3845 bool IsZero = C.isZero();
3847 return new ICmpInst(Pred, II->getArgOperand(0),
3850
3851 break;
3852 }
3853
3854 case Intrinsic::fshl:
3855 case Intrinsic::fshr:
3856 if (II->getArgOperand(0) == II->getArgOperand(1)) {
3857 const APInt *RotAmtC;
3858
3859
3861 return new ICmpInst(Pred, II->getArgOperand(0),
3862 II->getIntrinsicID() == Intrinsic::fshl
3863 ? ConstantInt::get(Ty, C.rotr(*RotAmtC))
3864 : ConstantInt::get(Ty, C.rotl(*RotAmtC)));
3865 }
3866 break;
3867
3868 case Intrinsic::umax:
3869 case Intrinsic::uadd_sat: {
3870
3871
3872 if (C.isZero() && II->hasOneUse()) {
3873 Value *Or = Builder.CreateOr(II->getArgOperand(0), II->getArgOperand(1));
3875 }
3876 break;
3877 }
3878
3879 case Intrinsic::ssub_sat:
3880
3881 if (C.isZero())
3882 return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1));
3883 break;
3884 case Intrinsic::usub_sat: {
3885
3886 if (C.isZero()) {
3889 return new ICmpInst(NewPred, II->getArgOperand(0), II->getArgOperand(1));
3890 }
3891 break;
3892 }
3893 default:
3894 break;
3895 }
3896
3897 return nullptr;
3898}
3899
3900
3904 assert(Cmp.isEquality());
3905
3907 Value *Op0 = Cmp.getOperand(0);
3908 Value *Op1 = Cmp.getOperand(1);
3911 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())
3912 return nullptr;
3913
3914 switch (IIOp0->getIntrinsicID()) {
3915 case Intrinsic::bswap:
3916 case Intrinsic::bitreverse:
3917
3918
3919 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3920 case Intrinsic::fshl:
3921 case Intrinsic::fshr: {
3922
3923
3924 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))
3925 break;
3926 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))
3927 break;
3928 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))
3929 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));
3930
3931
3932
3933
3934
3935 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();
3936 if (OneUses == 2 ||
3940 Builder.CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));
3941 Value *CombinedRotate = Builder.CreateIntrinsic(
3942 Op0->getType(), IIOp0->getIntrinsicID(),
3943 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});
3944 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);
3945 }
3946 } break;
3947 default:
3948 break;
3949 }
3950
3951 return nullptr;
3952}
3953
3954
3955
3956
3962 switch (II->getIntrinsicID()) {
3963 default:
3964 break;
3965 case Intrinsic::fshl:
3966 case Intrinsic::fshr:
3967 if (Cmp.isEquality() && II->getArgOperand(0) == II->getArgOperand(1)) {
3968
3969 if (C.isZero() || C.isAllOnes())
3970 return new ICmpInst(Pred, II->getArgOperand(0), Cmp.getOperand(1));
3971 }
3972 break;
3973 }
3974 }
3975
3976 return nullptr;
3977}
3978
3979
3984 case Instruction::Xor:
3986 return I;
3987 break;
3988 case Instruction::And:
3990 return I;
3991 break;
3992 case Instruction::Or:
3994 return I;
3995 break;
3996 case Instruction::Mul:
3998 return I;
3999 break;
4000 case Instruction::Shl:
4002 return I;
4003 break;
4004 case Instruction::LShr:
4005 case Instruction::AShr:
4007 return I;
4008 break;
4009 case Instruction::SRem:
4011 return I;
4012 break;
4013 case Instruction::UDiv:
4015 return I;
4016 [[fallthrough]];
4017 case Instruction::SDiv:
4019 return I;
4020 break;
4021 case Instruction::Sub:
4023 return I;
4024 break;
4025 case Instruction::Add:
4027 return I;
4028 break;
4029 default:
4030 break;
4031 }
4032
4033
4035 return I;
4036
4037
4038
4039
4041}
4042
4047
4048
4049 if (->hasOneUse())
4050 return nullptr;
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065 Value *Op0 = II->getOperand(0);
4066 Value *Op1 = II->getOperand(1);
4067
4068 const APInt *COp1;
4069
4070
4072 return nullptr;
4073
4075 switch (II->getIntrinsicID()) {
4076 default:
4078 "This function only works with usub_sat and uadd_sat for now!");
4079 case Intrinsic::uadd_sat:
4081 break;
4082 case Intrinsic::usub_sat:
4084 break;
4085 }
4086
4087
4089
4090
4092 II->getBinaryOp(), *COp1, II->getNoWrapKind());
4093
4094
4095 if (SatValCheck)
4097
4099 if (II->getBinaryOp() == Instruction::Add)
4100 C2 = C2.sub(*COp1);
4101 else
4102 C2 = C2.add(*COp1);
4103
4105 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;
4106
4107 std::optional Combination;
4108 if (CombiningOp == Instruction::BinaryOps::Or)
4110 else
4112
4113 if (!Combination)
4114 return nullptr;
4115
4118 APInt EquivOffset;
4119
4120 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);
4121
4123 EquivPred,
4124 Builder.CreateAdd(Op0, ConstantInt::get(Op1->getType(), EquivOffset)),
4125 ConstantInt::get(Op1->getType(), EquivInt));
4126}
4127
4132 std::optionalICmpInst::Predicate NewPredicate = std::nullopt;
4133 switch (Pred) {
4136 if (C.isZero())
4137 NewPredicate = Pred;
4138 else if (C.isOne())
4139 NewPredicate =
4141 else if (C.isAllOnes())
4142 NewPredicate =
4144 break;
4145
4147 if (C.isAllOnes())
4149 else if (C.isZero())
4151 break;
4152
4154 if (C.isZero())
4156 else if (C.isOne())
4158 break;
4159
4161 if (C.ugt(1))
4163 break;
4164
4166 if (.isZero() &&
.isAllOnes())
4168 break;
4169
4170 default:
4171 break;
4172 }
4173
4174 if (!NewPredicate)
4175 return nullptr;
4176
4177 if (I->getIntrinsicID() == Intrinsic::scmp)
4182}
4183
4184
4189
4190
4191 switch (II->getIntrinsicID()) {
4192 default:
4193 break;
4194 case Intrinsic::uadd_sat:
4195 case Intrinsic::usub_sat:
4198 return Folded;
4199 break;
4200 case Intrinsic::ctpop: {
4203 return R;
4204 } break;
4205 case Intrinsic::scmp:
4206 case Intrinsic::ucmp:
4208 return Folded;
4209 break;
4210 }
4211
4212 if (Cmp.isEquality())
4214
4215 Type *Ty = II->getType();
4216 unsigned BitWidth = C.getBitWidth();
4217 switch (II->getIntrinsicID()) {
4218 case Intrinsic::ctpop: {
4219
4220 Value *X = II->getArgOperand(0);
4224
4228 break;
4229 }
4230 case Intrinsic::ctlz: {
4231
4233 unsigned Num = C.getLimitedValue();
4236 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4237 }
4238
4239
4241 unsigned Num = C.getLimitedValue();
4244 II->getArgOperand(0), ConstantInt::get(Ty, Limit));
4245 }
4246 break;
4247 }
4248 case Intrinsic::cttz: {
4249
4250 if (->hasOneUse())
4251 return nullptr;
4252
4253
4257 Builder.CreateAnd(II->getArgOperand(0), Mask),
4259 }
4260
4261
4265 Builder.CreateAnd(II->getArgOperand(0), Mask),
4267 }
4268 break;
4269 }
4270 case Intrinsic::ssub_sat:
4271
4273 if (C.isZero())
4274 return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1));
4275
4278 II->getArgOperand(1));
4279
4282 II->getArgOperand(1));
4283 }
4284 break;
4285 default:
4286 break;
4287 }
4288
4289 return nullptr;
4290}
4291
4292
4294 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
4297 if (!RHSC || !LHSI)
4298 return nullptr;
4299
4301 case Instruction::IntToPtr:
4302
4308 break;
4309
4310 case Instruction::Load:
4311
4316 return Res;
4317 break;
4318 }
4319
4320 return nullptr;
4321}
4322
4325
4326
4327 auto SimplifyOp = [&](Value *Op, bool SelectCondIsTrue) -> Value * {
4329 return Res;
4331 SI->getCondition(), Pred, Op, RHS, DL, SelectCondIsTrue))
4332 return ConstantInt::get(I.getType(), *Impl);
4333 return nullptr;
4334 };
4335
4337 Value *Op1 = SimplifyOp(SI->getOperand(1), true);
4338 if (Op1)
4340
4341 Value *Op2 = SimplifyOp(SI->getOperand(2), false);
4342 if (Op2)
4344
4345 auto Simplifies = [&](Value *Op, unsigned Idx) {
4346
4347 const APInt *Dummy;
4348 return Op ||
4350 SI->getOperand(Idx)->hasOneUse() && match(RHS, m_APInt(Dummy)));
4351 };
4352
4353
4354
4355
4356
4357
4358
4359
4360 bool Transform = false;
4361 if (Op1 && Op2)
4362 Transform = true;
4363 else if (Simplifies(Op1, 1) || Simplifies(Op2, 2)) {
4364
4365 if (SI->hasOneUse())
4366 Transform = true;
4367
4368 else if (CI && !CI->isZero())
4369
4370
4371
4373 }
4374 if (Transform) {
4375 if (!Op1)
4376 Op1 = Builder.CreateICmp(Pred, SI->getOperand(1), RHS, I.getName());
4377 if (!Op2)
4378 Op2 = Builder.CreateICmp(Pred, SI->getOperand(2), RHS, I.getName());
4380 }
4381
4382 return nullptr;
4383}
4384
4385
4387 unsigned Depth = 0) {
4389 return true;
4390 if (V->getType()->getScalarSizeInBits() == 1)
4391 return true;
4393 return false;
4396 if ()
4397 return false;
4398 switch (I->getOpcode()) {
4399 case Instruction::ZExt:
4400
4402 case Instruction::SExt:
4403
4404
4406 case Instruction::And:
4407 case Instruction::Or:
4408
4409
4410
4411
4414 case Instruction::Xor:
4417
4418
4419 if (Not)
4421
4422 else
4424 case Instruction::Select:
4425
4428 case Instruction::Shl:
4429
4431 case Instruction::LShr:
4432
4434 case Instruction::AShr:
4435
4436
4438 case Instruction::Add:
4439
4443 break;
4444 case Instruction::Sub:
4445
4446 if (Not && match(I->getOperand(0), m_Zero()))
4449 break;
4450 case Instruction::Call: {
4452 switch (II->getIntrinsicID()) {
4453
4454
4455 case Intrinsic::umax:
4456 case Intrinsic::smax:
4457 case Intrinsic::umin:
4458 case Intrinsic::smin:
4461
4462
4463 case Intrinsic::bitreverse:
4465 default:
4466 break;
4467 }
4468 }
4469 break;
4470 }
4471 default:
4472 break;
4473 }
4474 return false;
4475}
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4496
4498 switch (Pred) {
4500
4501
4502
4503
4504
4505
4507 break;
4509
4510
4511
4512
4513
4514
4516 break;
4518
4519
4520
4521
4523 break;
4525
4526
4527
4528
4530 break;
4532
4533
4534
4535
4537 break;
4539
4540
4541
4542
4544 break;
4545 default:
4546
4547
4548 return nullptr;
4549 }
4550
4552
4553 auto IsLowBitMask = [&]() {
4555 X = Op1;
4556
4560 }
4561
4562
4565 }
4566 return false;
4567 }
4570
4571 auto Check = [&]() {
4572
4574 if (Value *NotX =
4576 X = NotX;
4577 return true;
4578 }
4579 }
4580 return false;
4581 };
4583 return true;
4586 }
4589 auto Check = [&]() {
4590
4592 if (Value *NotM =
4594 M = NotM;
4595 return true;
4596 }
4597 }
4598 return false;
4599 };
4601 return true;
4604 }
4605 return false;
4606 };
4607
4608 if (!IsLowBitMask())
4609 return nullptr;
4610
4612}
4613
4614
4615
4616
4617
4618
4619
4620
4621
4627 const APInt *C0, *C1;
4628
4633 return nullptr;
4634
4635
4636
4637
4638
4639
4640
4641
4642 if (*C0 != *C1)
4643 return nullptr;
4644 const APInt &MaskedBits = *C0;
4645 assert(MaskedBits != 0 && "shift by zero should be folded away already.");
4646
4648 switch (SrcPred) {
4650
4651
4652
4654 break;
4656
4657
4658
4660 break;
4661
4662 default:
4663 return nullptr;
4664 }
4665
4666 auto *XType = X->getType();
4667 const unsigned XBitWidth = XType->getScalarSizeInBits();
4669 assert(BitWidth.ugt(MaskedBits) && "shifts should leave some bits untouched");
4670
4671
4674
4675 const APInt ICmpCst = APInt(XBitWidth, 1).shl(KeptBits);
4677
4678 const APInt AddCst = ICmpCst.lshr(1);
4680
4681
4682 Value *T0 = Builder.CreateAdd(X, ConstantInt::get(XType, AddCst));
4683
4684 Value *T1 = Builder.CreateICmp(DstPred, T0, ConstantInt::get(XType, ICmpCst));
4685
4686 return T1;
4687}
4688
4689
4690
4691
4692
4693
4694
4695
4699 if (.isEquality() ||
(I.getOperand(1), m_Zero()) ||
4700 .getOperand(0)->hasOneUse())
4701 return nullptr;
4702
4704
4705
4706
4707 Instruction *XShift, *MaybeTruncation, *YShift;
4709 I.getOperand(0),
4714 return nullptr;
4715
4716
4717
4719
4720
4722
4723 Type *WidestTy = WidestShift->getType();
4724 Type *NarrowestTy = NarrowestShift->getType();
4725 assert(NarrowestTy == I.getOperand(0)->getType() &&
4726 "We did not look past any shifts while matching XShift though.");
4727 bool HadTrunc = WidestTy != I.getOperand(0)->getType();
4728
4729
4732
4733
4734 auto XShiftOpcode = XShift->getOpcode();
4735 if (XShiftOpcode == YShift->getOpcode())
4736 return nullptr;
4737
4738 Value *X, *XShAmt, *Y, *YShAmt;
4741
4742
4743
4744
4746
4747 if ((I.getOperand(0),
4749 return nullptr;
4750 if (HadTrunc) {
4751
4752
4753 if (!MaybeTruncation->hasOneUse() &&
4755 return nullptr;
4756 }
4757 }
4758
4759
4760
4762 return nullptr;
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773 unsigned MaximalPossibleTotalShiftAmount =
4776 APInt MaximalRepresentableShiftAmount =
4778 if (MaximalRepresentableShiftAmount.ult(MaximalPossibleTotalShiftAmount))
4779 return nullptr;
4780
4781
4785 if (!NewShAmt)
4786 return nullptr;
4787 if (NewShAmt->getType() != WidestTy) {
4788 NewShAmt =
4790 if (!NewShAmt)
4791 return nullptr;
4792 }
4794
4795
4796
4797 if ((NewShAmt,
4799 APInt(WidestBitWidth, WidestBitWidth))))
4800 return nullptr;
4801
4802
4804 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,
4805 WidestShift]() {
4806
4807
4808
4810 ? NewShAmt->getSplatValue()
4811 : NewShAmt;
4812
4813 if (NewShAmtSplat &&
4816 return true;
4817
4818
4822
4823 unsigned MaxActiveBits = Known.getBitWidth() - MinLeadZero;
4824 if (MaxActiveBits <= 1)
4825 return true;
4826
4827 if (NewShAmtSplat && NewShAmtSplat->getUniqueInteger().ule(MinLeadZero))
4828 return true;
4829 }
4833
4834 unsigned MaxActiveBits = Known.getBitWidth() - MinLeadZero;
4835 if (MaxActiveBits <= 1)
4836 return true;
4837
4838 if (NewShAmtSplat) {
4839 APInt AdjNewShAmt =
4841 if (AdjNewShAmt.ule(MinLeadZero))
4842 return true;
4843 }
4844 }
4845 return false;
4846 };
4847 if (!CanFold())
4848 return nullptr;
4849 }
4850
4851
4852 X = Builder.CreateZExt(X, WidestTy);
4853 Y = Builder.CreateZExt(Y, WidestTy);
4854
4855 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
4856 ? Builder.CreateLShr(X, NewShAmt)
4857 : Builder.CreateShl(X, NewShAmt);
4858 Value *T1 = Builder.CreateAnd(T0, Y);
4859 return Builder.CreateICmp(I.getPredicate(), T1,
4861}
4862
4863
4864
4865
4866
4867
4868
4869
4875 bool NeedNegation;
4876
4877 if (.isEquality() &&
4882 Mul = nullptr;
4883
4884
4885 switch (Pred) {
4887 NeedNegation = false;
4888 break;
4890 NeedNegation = true;
4891 break;
4892 default:
4893 return nullptr;
4894 }
4895 } else
4896 if (I.isEquality() &&
4905 } else
4906 return nullptr;
4907
4909
4910
4911 bool MulHadOtherUses = Mul && ->hasOneUse();
4912 if (MulHadOtherUses)
4914
4916 Div->getOpcode() == Instruction::UDiv ? Intrinsic::umul_with_overflow
4917 : Intrinsic::smul_with_overflow,
4918 X->getType(), {X, Y}, nullptr, "mul");
4919
4920
4921
4922
4923 if (MulHadOtherUses)
4925
4927 if (NeedNegation)
4928 Res = Builder.CreateNot(Res, "mul.not.ov");
4929
4930
4931
4932 if (MulHadOtherUses)
4934
4935 return Res;
4936}
4937
4943
4948
4949
4952 }
4953
4954
4955
4962 Value *And = Builder.CreateAnd(X, MaxSignedVal);
4965 }
4966
4967 return nullptr;
4968}
4969
4972 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A;
4973
4978 }
4979
4981 return nullptr;
4982
4983
4986
4987
4990
4992
4993
4994
4996 if (auto *NotOp1 =
5000
5004 }
5005
5007 return nullptr;
5008
5010
5013
5015 return nullptr;
5016
5018
5019
5022
5024
5025
5028
5029 return nullptr;
5030}
5031
5034 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A;
5035
5036
5042 return nullptr;
5043 }
5044
5045
5048
5049
5052
5054
5059
5063 }
5064 return nullptr;
5065}
5066
5069 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A;
5070
5075 }
5077 return nullptr;
5078
5079
5080
5081
5082
5085 return new ICmpInst(PredOut, Op0, Op1);
5086
5087
5088
5089
5093 default:
5094 return nullptr;
5098 break;
5102 break;
5103 }
5105 return new ICmpInst(NewPred, Op0, Const);
5106 }
5107
5108 return nullptr;
5109}
5110
5111
5112
5114 if (C.isOne())
5115 return true;
5116
5117 if (.isPowerOf2())
5118 return false;
5119
5121}
5122
5123
5124
5125
5126
5130 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
5131
5132
5135 if (!BO0 && !BO1)
5136 return nullptr;
5137
5139 return NewICmp;
5140
5143
5144
5145
5149
5153
5154 {
5155
5162 }
5163
5169 }
5170 }
5171
5172
5173
5177
5182 }
5183
5184 {
5185
5186
5187
5188
5189
5198 return new ICmpInst(NewPred, Op1, Zero);
5199 }
5200
5207 return new ICmpInst(NewPred, Op0, Zero);
5208 }
5209 }
5210
5211 bool NoOp0WrapProblem = false, NoOp1WrapProblem = false;
5212 bool Op0HasNUW = false, Op1HasNUW = false;
5213 bool Op0HasNSW = false, Op1HasNSW = false;
5214
5215
5217 bool &HasNSW, bool &HasNUW) -> bool {
5224 } else if (BO.getOpcode() == Instruction::Or) {
5225 HasNUW = true;
5226 HasNSW = true;
5227 return true;
5228 } else {
5229 return false;
5230 }
5231 };
5232 Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr;
5233
5234 if (BO0) {
5236 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);
5237 }
5238 if (BO1) {
5240 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);
5241 }
5242
5243
5244
5245 if ((A == Op1 || B == Op1) && NoOp0WrapProblem)
5246 return new ICmpInst(Pred, A == Op1 ? B : A,
5248
5249
5250
5251 if ((C == Op0 || D == Op0) && NoOp1WrapProblem)
5254
5255
5256 if (A && C && (A == C || A == D || B == C || B == D) && NoOp0WrapProblem &&
5257 NoOp1WrapProblem) {
5258
5261
5263 Z = D;
5265
5267 Z = C;
5269
5271 Z = D;
5272 } else {
5274
5276 Z = C;
5277 }
5278 return new ICmpInst(Pred, Y, Z);
5279 }
5280
5282
5283
5285 bool IsNegative) -> bool {
5286 const APInt *OffsetC;
5288 return false;
5289
5290
5291 if (IsNegative ? OffsetC->isAllOnes() : OffsetC->isOne())
5292 return true;
5293
5295 if (IsNegative)
5296 C.negate();
5297
5298 if (.isStrictlyPositive())
5299 return false;
5300
5302 };
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319 if (A && NoOp0WrapProblem &&
5320 ShareCommonDivisor(A, Op1, B,
5323 Op1);
5324
5325
5326
5327
5328
5329
5330
5331 if (C && NoOp1WrapProblem &&
5332 ShareCommonDivisor(Op0, C, D,
5335 C);
5336 }
5337
5338
5339
5340
5341
5342
5343
5344
5345 if (A && C && NoOp0WrapProblem && NoOp1WrapProblem &&
5347 const APInt *AP1, *AP2;
5348
5349
5355 if (AP1Abs.uge(AP2Abs)) {
5356 APInt Diff = *AP1 - *AP2;
5359 A, C3, "", Op0HasNUW && Diff.ule(*AP1), Op0HasNSW);
5360 return new ICmpInst(Pred, NewAdd, C);
5361 } else {
5362 APInt Diff = *AP2 - *AP1;
5365 C, C3, "", Op1HasNUW && Diff.ule(*AP2), Op1HasNSW);
5366 return new ICmpInst(Pred, A, NewAdd);
5367 }
5368 }
5374 return new ICmpInst(Pred, A, NewAdd);
5375 }
5376 }
5377
5378
5379
5380 A = nullptr;
5381 B = nullptr;
5382 C = nullptr;
5383 D = nullptr;
5384 if (BO0 && BO0->getOpcode() == Instruction::Sub) {
5387 }
5388 if (BO1 && BO1->getOpcode() == Instruction::Sub) {
5391 }
5392
5393
5394 if (A == Op1 && NoOp0WrapProblem)
5396
5397 if (C == Op0 && NoOp1WrapProblem)
5399
5400
5401
5404
5407
5411
5415
5416
5417 if (B && D && B == D && NoOp0WrapProblem && NoOp1WrapProblem)
5419
5420
5421 if (A && C && A == C && NoOp0WrapProblem && NoOp1WrapProblem)
5423
5424
5429 if (RHSC->isNotMinSignedValue())
5430 return new ICmpInst(I.getSwappedPredicate(), X,
5432 }
5433
5435 return R;
5437 return R;
5438
5439 {
5440
5441
5448 if (Op0HasNSW && Op1HasNSW) {
5455 SQ.getWithInstruction(&I));
5456 if (LessThan && match(LessThan, m_One()))
5460 SQ.getWithInstruction(&I));
5461 if (GreaterThan && match(GreaterThan, m_One()))
5463 }
5464 } else {
5465 bool NonZero;
5467
5468 if (((Op0HasNSW && Op1HasNSW) || (Op0HasNUW && Op1HasNUW)) &&
5471
5473
5474
5478
5479
5480 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)
5482 } else
5484
5485
5486
5487 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
5489 }
5490 }
5491 }
5492
5494
5495 if (BO0 && BO0->getOpcode() == Instruction::SRem && Op1 == BO0->getOperand(1))
5496 SRem = BO0;
5497
5498 else if (BO1 && BO1->getOpcode() == Instruction::SRem &&
5500 SRem = BO1;
5501 if (SRem) {
5502
5503
5505 default:
5506 break;
5519 }
5520 }
5521
5526 default:
5527 break;
5528 case Instruction::Add:
5529 case Instruction::Sub:
5530 case Instruction::Xor: {
5531 if (I.isEquality())
5533
5536
5537 if (C->isSignMask()) {
5540 }
5541
5542
5543 if (BO0->getOpcode() == Instruction::Xor && C->isMaxSignedValue()) {
5545 NewPred = I.getSwappedPredicate(NewPred);
5547 }
5548 }
5549 break;
5550 }
5551 case Instruction::Mul: {
5552 if (.isEquality())
5553 break;
5554
5557 ->isOne()) {
5558
5559
5560 if (unsigned TZs = C->countr_zero()) {
5561 Constant *Mask = ConstantInt::get(
5566 return new ICmpInst(Pred, And1, And2);
5567 }
5568 }
5569 break;
5570 }
5571 case Instruction::UDiv:
5572 case Instruction::LShr:
5574 break;
5576
5577 case Instruction::SDiv:
5580 break;
5582
5583 case Instruction::AShr:
5585 break;
5587
5588 case Instruction::Shl: {
5589 bool NUW = Op0HasNUW && Op1HasNUW;
5590 bool NSW = Op0HasNSW && Op1HasNSW;
5591 if (!NUW && !NSW)
5592 break;
5593 if (!NSW && I.isSigned())
5594 break;
5596 }
5597 }
5598 }
5599
5600 if (BO0) {
5601
5604
5608 }
5609 }
5610
5611
5612
5613
5621 }
5622
5625
5627 return R;
5628
5631
5634
5635 return nullptr;
5636}
5637
5638
5645 return nullptr;
5647
5648
5649
5653 } else
5654 return nullptr;
5655 }
5657 auto IsCondKnownTrue = [](Value *Val) -> std::optional {
5658 if (!Val)
5659 return std::nullopt;
5661 return true;
5663 return false;
5664 return std::nullopt;
5665 };
5666
5667
5668
5669
5670 Pred = Pred.dropSameSign();
5673 if (!CmpXZ.has_value() && !CmpYZ.has_value())
5674 return nullptr;
5675 if (!CmpXZ.has_value()) {
5678 }
5679
5680 auto FoldIntoCmpYZ = [&]() -> Instruction * {
5681 if (CmpYZ.has_value())
5684 };
5685
5686 switch (Pred) {
5689
5690
5691
5692
5693
5694
5701 }
5702
5704 auto MinMaxCmpXZ = IsCondKnownTrue(simplifyICmpInst(NewPred, X, Z, Q));
5705 if (!MinMaxCmpXZ.has_value()) {
5708
5709 if (!CmpXZ.has_value() || (Pred == ICmpInst::ICMP_EQ) == *CmpXZ)
5710 break;
5711 MinMaxCmpXZ = IsCondKnownTrue(simplifyICmpInst(NewPred, X, Z, Q));
5712 }
5713 if (!MinMaxCmpXZ.has_value())
5714 break;
5715 if (*MinMaxCmpXZ) {
5716
5717
5718
5719
5720
5723 } else {
5724
5725
5726
5727
5728
5729 return FoldIntoCmpYZ();
5730 }
5731 break;
5732 }
5742 if (*CmpXZ) {
5743 if (IsSame) {
5744
5745
5746
5747
5748
5750 } else {
5751
5752
5753
5754
5755
5756 return FoldIntoCmpYZ();
5757 }
5758 } else {
5759 if (IsSame) {
5760
5761
5762
5763
5764
5765 return FoldIntoCmpYZ();
5766 } else {
5767
5768
5769
5770
5771
5773 }
5774 }
5775 break;
5776 }
5777 default:
5778 break;
5779 }
5780
5781 return nullptr;
5782}
5783
5784
5785
5786
5787
5788
5789
5790
5791
5794 if (.isEquality() || !Min->hasOneUse() || !Min->isMin())
5795 return nullptr;
5796
5797 const APInt *Lo = nullptr, *Hi = nullptr;
5801 return nullptr;
5802 } else {
5805 return nullptr;
5806 }
5807
5813 else
5815
5816 if (.isZero())
5817 X = Builder.CreateAdd(X, ConstantInt::get(X->getType(), Offset));
5818
5820 I, Builder.CreateICmp(Pred, X, ConstantInt::get(X->getType(), C)));
5821}
5822
5823
5826 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
5829 bool CheckIs;
5830 if (I.isEquality()) {
5831
5832
5836 A = nullptr;
5837
5838
5839
5841 A = Op1;
5842 else if (match(Op1,
5844 A = Op0;
5845
5848
5849
5850
5854 A = Op1;
5859 A = Op0;
5861 }
5862 }
5863
5864 if (A) {
5866 CallInst *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop, A);
5868 ConstantInt::get(Ty, 2))
5870 ConstantInt::get(Ty, 1));
5871 }
5872
5873 return nullptr;
5874}
5875
5876
5877using OffsetOp = std::pair<Instruction::BinaryOps, Value *>;
5879 bool AllowRecursion) {
5881 if (!Inst || !Inst->hasOneUse())
5882 return;
5883
5885 case Instruction::Add:
5886 Offsets.emplace_back(Instruction::Sub, Inst->getOperand(1));
5887 Offsets.emplace_back(Instruction::Sub, Inst->getOperand(0));
5888 break;
5889 case Instruction::Sub:
5890 Offsets.emplace_back(Instruction::Add, Inst->getOperand(1));
5891 break;
5892 case Instruction::Xor:
5893 Offsets.emplace_back(Instruction::Xor, Inst->getOperand(1));
5894 Offsets.emplace_back(Instruction::Xor, Inst->getOperand(0));
5895 break;
5896 case Instruction::Shl:
5898 Offsets.emplace_back(Instruction::AShr, Inst->getOperand(1));
5900 Offsets.emplace_back(Instruction::LShr, Inst->getOperand(1));
5901 break;
5902 case Instruction::Select:
5903 if (AllowRecursion) {
5906 }
5907 break;
5908 default:
5909 break;
5910 }
5911}
5912
5914
5918
5930 switch (Kind) {
5934 return V0;
5936 return Builder.CreateSelect(V0, V1, V2);
5937 }
5939 }
5940};
5941
5942
5943
5944
5948 assert(I.isEquality() && "Expected an equality icmp");
5949 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
5951 return nullptr;
5952
5954 collectOffsetOp(Op0, OffsetOps, true);
5955 collectOffsetOp(Op1, OffsetOps, true);
5956
5957 auto ApplyOffsetImpl = [&](Value *V, unsigned BinOpc, Value *RHS) -> Value * {
5958 switch (BinOpc) {
5959
5960 case Instruction::AShr: {
5961 const APInt *CV, *CRHS;
5963 CV->ashr(*CRHS).shl(*CRHS) == *CV) &&
5965 return nullptr;
5966 break;
5967 }
5968
5969 case Instruction::LShr: {
5970 const APInt *CV, *CRHS;
5972 CV->lshr(*CRHS).shl(*CRHS) == *CV) &&
5974 return nullptr;
5975 break;
5976 }
5977 default:
5978 break;
5979 }
5980
5982 if (!Simplified)
5983 return nullptr;
5984
5986 return nullptr;
5987
5989 };
5990
5991 auto ApplyOffset = [&](Value *V, unsigned BinOpc,
5994 if (!Sel->hasOneUse())
5996 Value *TrueVal = ApplyOffsetImpl(Sel->getTrueValue(), BinOpc, RHS);
5997 if (!TrueVal)
5999 Value *FalseVal = ApplyOffsetImpl(Sel->getFalseValue(), BinOpc, RHS);
6000 if (!FalseVal)
6003 }
6004 if (Value *Simplified = ApplyOffsetImpl(V, BinOpc, RHS))
6007 };
6008
6009 for (auto [BinOp, RHS] : OffsetOps) {
6010 auto BinOpc = static_cast<unsigned>(BinOp);
6011
6012 auto Op0Result = ApplyOffset(Op0, BinOpc, RHS);
6013 if (!Op0Result.isValid())
6014 continue;
6015 auto Op1Result = ApplyOffset(Op1, BinOpc, RHS);
6016 if (!Op1Result.isValid())
6017 continue;
6018
6019 Value *NewLHS = Op0Result.materialize(Builder);
6020 Value *NewRHS = Op1Result.materialize(Builder);
6021 return new ICmpInst(I.getPredicate(), NewLHS, NewRHS);
6022 }
6023
6024 return nullptr;
6025}
6026
6028 if (.isEquality())
6029 return nullptr;
6030
6031 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
6035 if (A == Op1 || B == Op1) {
6036 Value *OtherVal = A == Op1 ? B : A;
6038 }
6039
6041
6044 Op1->hasOneUse()) {
6048 }
6049
6050
6059 }
6060 }
6061
6063
6064 Value *OtherVal = A == Op0 ? B : A;
6066 }
6067
6068
6071 Value *X = nullptr, *Y = nullptr, *Z = nullptr;
6072
6076 Z = A;
6080 Z = A;
6084 Z = B;
6088 Z = B;
6089 }
6090
6091 if (X) {
6092
6093
6094
6095 const APInt *C0, *C1;
6097 (*C0 ^ *C1).isNegatedPowerOf2();
6098
6099
6100
6101
6102 int UseCnt =
6103 int(Op0->hasOneUse()) + int(Op1->hasOneUse()) +
6105 if (XorIsNegP2 || UseCnt >= 2) {
6106
6108 Op1 = Builder.CreateAnd(Op1, Z);
6110 }
6111 }
6112 }
6113
6114 {
6115
6116
6124 }
6125 }
6126
6128 (Op0->hasOneUse() || Op1->hasOneUse())) {
6129
6130
6131 const APInt *MaskC;
6133 MaskC->countr_one() == A->getType()->getScalarSizeInBits())
6135 }
6136
6137
6138
6139 const APInt *AP1, *AP2;
6144 if (*AP1 != *AP2)
6145 return nullptr;
6148 if (ShAmt < TypeBits && ShAmt != 0) {
6153 return new ICmpInst(NewPred, Xor, ConstantInt::get(A->getType(), CmpVal));
6154 }
6155 }
6156
6157
6161 unsigned TypeBits = Cst1->getBitWidth();
6163 if (ShAmt < TypeBits && ShAmt != 0) {
6167 Builder.CreateAnd(Xor, Builder.getInt(AndVal), I.getName() + ".mask");
6169 }
6170 }
6171
6172
6173
6178
6179
6180 ->hasOneUse()) {
6181 unsigned ASize = cast(A->getType())->getPrimitiveSizeInBits();
6182
6183 if (ShAmt < ASize) {
6186 MaskV <<= ShAmt;
6187
6189 CmpV <<= ShAmt;
6190
6193 }
6194 }
6195
6197 return ICmp;
6198
6199
6200
6201
6202
6206 A->getType()->getScalarSizeInBits() == BitWidth * 2 &&
6207 (I.getOperand(0)->hasOneUse() || I.getOperand(1)->hasOneUse())) {
6209 Value *Add = Builder.CreateAdd(A, ConstantInt::get(A->getType(), C));
6212 Add, ConstantInt::get(A->getType(), C.shl(1)));
6213 }
6214
6215
6216
6217
6218
6223
6228
6229
6230
6231
6232
6233
6238 Pred, A,
6239 Builder.CreateIntrinsic(Op0->getType(), Intrinsic::fshl, {A, A, B}));
6240
6241
6242
6247
6248 {
6249
6250 auto m_Matcher =
6254 std::optional IsZero = std::nullopt;
6257 IsZero = false;
6258
6261 IsZero = true;
6262
6264
6265
6266
6267
6269 *IsZero ? A
6271 }
6272
6275 return Res;
6276
6277 return nullptr;
6278}
6279
6283
6284
6285
6289 return nullptr;
6290
6291
6292
6294 true)) {
6296 Constant *C = ConstantInt::get(Res->X->getType(), Res->C);
6298 }
6299
6300 unsigned SrcBits = X->getType()->getScalarSizeInBits();
6302 if (II->getIntrinsicID() == Intrinsic::cttz ||
6303 II->getIntrinsicID() == Intrinsic::ctlz) {
6304 unsigned MaxRet = SrcBits;
6305
6306
6307
6309 MaxRet--;
6310
6311
6312
6316 return I;
6317 }
6318 }
6319
6320 return nullptr;
6321}
6322
6328 return nullptr;
6329
6330 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;
6331 bool IsSignedCmp = ICmp.isSigned();
6332
6333
6338
6339 if (IsZext0 != IsZext1) {
6340
6341
6342
6343
6344 if (ICmp.isEquality() && X->getType()->isIntOrIntVectorTy(1) &&
6345 Y->getType()->isIntOrIntVectorTy(1))
6348
6349
6350
6351
6354
6355 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
6356 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
6357
6358 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))
6359 IsSignedExt = true;
6360 else
6361 return nullptr;
6362 }
6363
6364
6365 Type *XTy = X->getType(), *YTy = Y->getType();
6366 if (XTy != YTy) {
6367
6369 return nullptr;
6370
6372 IsSignedExt ? Instruction::SExt : Instruction::ZExt;
6374 X = Builder.CreateCast(CastOpcode, X, YTy);
6376 Y = Builder.CreateCast(CastOpcode, Y, XTy);
6377 else
6378 return nullptr;
6379 }
6380
6381
6382
6385
6386
6387
6388 if (IsSignedCmp && IsSignedExt)
6390
6391
6393 }
6394
6395
6397 if ()
6398 return nullptr;
6399
6400
6401 Type *SrcTy = CastOp0->getSrcTy();
6403 if (Res) {
6406
6407
6408
6409 if (IsSignedExt && IsSignedCmp)
6411
6412
6414 }
6415
6416
6417
6418
6419
6420
6422 return nullptr;
6423
6424
6425
6428
6429
6430
6433}
6434
6435
6437
6438
6439
6440 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.getOperand(0));
6441 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.getOperand(1));
6442 if (SimplifiedOp0 || SimplifiedOp1)
6444 SimplifiedOp0 ? SimplifiedOp0 : ICmp.getOperand(0),
6445 SimplifiedOp1 ? SimplifiedOp1 : ICmp.getOperand(1));
6446
6448 if (!CastOp0)
6449 return nullptr;
6451 return nullptr;
6452
6453 Value *Op0Src = CastOp0->getOperand(0);
6454 Type *SrcTy = CastOp0->getSrcTy();
6455 Type *DestTy = CastOp0->getDestTy();
6456
6457
6458
6459 auto CompatibleSizes = [&](Type *PtrTy, Type *IntTy) {
6463 }
6464 return DL.getPointerTypeSizeInBits(PtrTy) == IntTy->getIntegerBitWidth();
6465 };
6466 if (CastOp0->getOpcode() == Instruction::PtrToInt &&
6467 CompatibleSizes(SrcTy, DestTy)) {
6468 Value *NewOp1 = nullptr;
6470 Value *PtrSrc = PtrToIntOp1->getOperand(0);
6472 NewOp1 = PtrToIntOp1->getOperand(0);
6475 }
6476
6477 if (NewOp1)
6479 }
6480
6481
6482 if (CastOp0->getOpcode() == Instruction::IntToPtr &&
6483 CompatibleSizes(DestTy, SrcTy)) {
6484 Value *NewOp1 = nullptr;
6486 Value *IntSrc = IntToPtrOp1->getOperand(0);
6488 NewOp1 = IntToPtrOp1->getOperand(0);
6491 }
6492
6493 if (NewOp1)
6495 }
6496
6498 return R;
6499
6501}
6502
6504 bool IsSigned) {
6505 switch (BinaryOp) {
6506 default:
6508 case Instruction::Add:
6509 case Instruction::Sub:
6511 case Instruction::Mul:
6512 return !(RHS->getType()->isIntOrIntVectorTy(1) && IsSigned) &&
6514 }
6515}
6516
6519 bool IsSigned, Value *LHS, Value *RHS,
6521 switch (BinaryOp) {
6522 default:
6524 case Instruction::Add:
6525 if (IsSigned)
6527 else
6529 case Instruction::Sub:
6530 if (IsSigned)
6532 else
6534 case Instruction::Mul:
6535 if (IsSigned)
6537 else
6539 }
6540}
6541
6543 bool IsSigned, Value *LHS,
6549
6550
6551
6552
6553
6554 Builder.SetInsertPoint(&OrigI);
6555
6558 OverflowTy = VectorType::get(OverflowTy, LHSTy->getElementCount());
6559
6561 Result = LHS;
6563 return true;
6564 }
6565
6568 return false;
6571 Result = Builder.CreateBinOp(BinaryOp, LHS, RHS);
6572 Result->takeName(&OrigI);
6574 return true;
6576 Result = Builder.CreateBinOp(BinaryOp, LHS, RHS);
6577 Result->takeName(&OrigI);
6580 if (IsSigned)
6581 Inst->setHasNoSignedWrap();
6582 else
6583 Inst->setHasNoUnsignedWrap();
6584 }
6585 return true;
6586 }
6587
6589}
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6606 const APInt *OtherVal,
6608
6609
6611 return nullptr;
6612
6614 if (!MulInstr)
6615 return nullptr;
6616 assert(MulInstr->getOpcode() == Instruction::Mul);
6617
6620 assert(LHS->getOpcode() == Instruction::ZExt);
6621 assert(RHS->getOpcode() == Instruction::ZExt);
6622 Value *A = LHS->getOperand(0), *B = RHS->getOperand(0);
6623
6624
6625 Type *TyA = A->getType(), *TyB = B->getType();
6627 WidthB = TyB->getPrimitiveSizeInBits();
6628 unsigned MulWidth;
6629 Type *MulType;
6630 if (WidthB > WidthA) {
6631 MulWidth = WidthB;
6632 MulType = TyB;
6633 } else {
6634 MulWidth = WidthA;
6635 MulType = TyA;
6636 }
6637
6638
6639
6640
6642 for (User *U : MulVal->users()) {
6643 if (U == &I)
6644 continue;
6646
6647 unsigned TruncWidth = TI->getType()->getPrimitiveSizeInBits();
6648 if (TruncWidth > MulWidth)
6649 return nullptr;
6651
6652 if (BO->getOpcode() != Instruction::And)
6653 return nullptr;
6655 const APInt &CVal = CI->getValue();
6657 return nullptr;
6658 } else {
6659
6660
6661
6662 return nullptr;
6663 }
6664 } else {
6665
6666 return nullptr;
6667 }
6668 }
6669
6670
6671 switch (I.getPredicate()) {
6673
6674
6675
6678 if (MaxVal.eq(*OtherVal))
6679 break;
6680 return nullptr;
6681 }
6682
6684
6685
6686
6688 if (MaxVal.eq(*OtherVal))
6689 break;
6690 return nullptr;
6691 }
6692
6693 default:
6694 return nullptr;
6695 }
6696
6699
6700
6701 Value *MulA = A, *MulB = B;
6702 if (WidthA < MulWidth)
6703 MulA = Builder.CreateZExt(A, MulType);
6704 if (WidthB < MulWidth)
6705 MulB = Builder.CreateZExt(B, MulType);
6707 Builder.CreateIntrinsic(Intrinsic::umul_with_overflow, MulType,
6708 {MulA, MulB}, nullptr, "umul");
6710
6711
6712
6713
6715 Value *Mul = Builder.CreateExtractValue(Call, 0, "umul.value");
6717 if (U == &I)
6718 continue;
6720 if (TI->getType()->getPrimitiveSizeInBits() == MulWidth)
6722 else
6725 assert(BO->getOpcode() == Instruction::And);
6726
6729 Value *ShortAnd = Builder.CreateAnd(Mul, ShortMask);
6730 Value *Zext = Builder.CreateZExt(ShortAnd, BO->getType());
6732 } else {
6734 }
6736 }
6737 }
6738
6739
6740
6742 Value *Res = Builder.CreateExtractValue(Call, 1);
6744 }
6745
6747}
6748
6749
6750
6751
6756
6757
6758
6759 bool UnusedBit;
6762
6763 switch (I.getPredicate()) {
6764
6765
6766
6767
6770
6771
6772
6775
6776 default:
6778 }
6779}
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6794 assert(DI && UI && "Instruction not defined\n");
6795
6797 return false;
6798
6800 return false;
6801
6803 return false;
6804 for (const User *U : DI->users()) {
6806 if (Usr != UI && .dominates(DB, Usr->getParent()))
6807 return false;
6808 }
6809 return true;
6810}
6811
6812
6815 if (!BB)
6816 return false;
6818 if (!BI || BI->getNumSuccessors() != 2)
6819 return false;
6821 if (!IC || (IC->getOperand(0) != SI && IC->getOperand(1) != SI))
6822 return false;
6823 return true;
6824}
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6868 const unsigned SIOpd) {
6869 assert((SIOpd == 1 || SIOpd == 2) && "Invalid select operand!");
6871 BasicBlock *Succ = SI->getParent()->getTerminator()->getSuccessor(1);
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6884 NumSel++;
6885 SI->replaceUsesOutsideBlock(SI->getOperand(SIOpd), SI->getParent());
6886 return true;
6887 }
6888 }
6889 return false;
6890}
6891
6892
6893
6895 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
6898
6899
6900 unsigned BitWidth = Ty->isIntOrIntVectorTy()
6901 ? Ty->getScalarSizeInBits()
6902 : DL.getPointerTypeSizeInBits(Ty->getScalarType());
6903
6905 return nullptr;
6906
6909
6910 {
6911
6912
6913
6914 SimplifyQuery Q = SQ.getWithoutDomCondCache().getWithInstruction(&I);
6916 Op0Known, Q))
6917 return &I;
6918
6920 return &I;
6921 }
6922
6929
6930 if (std::optional Res = ICmpInst::compare(Op0Known, Op1Known, Pred))
6932
6933
6934
6935
6938 if (I.isSigned()) {
6943 } else {
6948 }
6949
6950
6951
6952
6953
6954 auto isMinMaxCmp = [&](Instruction &Cmp) {
6955 if (!Cmp.hasOneUse())
6956 return false;
6960 return false;
6963 };
6964 if (!isMinMaxCmp(I)) {
6965 switch (Pred) {
6966 default:
6967 break;
6969 if (Op1Min == Op0Max)
6971 const APInt *CmpC;
6973
6974 if (*CmpC == Op0Min + 1)
6976 ConstantInt::get(Op1->getType(), *CmpC - 1));
6977
6978
6982 }
6983 break;
6984 }
6986 if (Op1Max == Op0Min)
6988 const APInt *CmpC;
6990
6991 if (*CmpC == Op0Max - 1)
6993 ConstantInt::get(Op1->getType(), *CmpC + 1));
6994
6995
6999 }
7000 break;
7001 }
7003 if (Op1Min == Op0Max)
7005 const APInt *CmpC;
7007 if (*CmpC == Op0Min + 1)
7009 ConstantInt::get(Op1->getType(), *CmpC - 1));
7010 }
7011 break;
7012 }
7014 if (Op1Max == Op0Min)
7016 const APInt *CmpC;
7018 if (*CmpC == Op0Max - 1)
7020 ConstantInt::get(Op1->getType(), *CmpC + 1));
7021 }
7022 break;
7023 }
7024 }
7025 }
7026
7027
7028
7029 switch (Pred) {
7030 default:
7031 break;
7034
7035
7036
7037 APInt Op0KnownZeroInverted = ~Op0Known.Zero;
7038 if (Op1Known.isZero()) {
7039
7040 Value *LHS = nullptr;
7041 const APInt *LHSC;
7043 *LHSC != Op0KnownZeroInverted)
7044 LHS = Op0;
7045
7047 const APInt *C1;
7049 Type *XTy = X->getType();
7051 APInt C2 = Op0KnownZeroInverted;
7052 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;
7054
7055
7056
7058 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);
7059 auto NewPred =
7061 return new ICmpInst(NewPred, X, CmpC);
7062 }
7063 }
7064 }
7065
7066
7068 (Op0Known & Op1Known) == Op0Known)
7071 break;
7072 }
7074 if (Op1Min == Op0Max)
7076 break;
7078 if (Op1Max == Op0Min)
7080 break;
7082 if (Op1Min == Op0Max)
7084 break;
7086 if (Op1Max == Op0Min)
7088 break;
7089 }
7090
7091
7092
7093
7094 if ((I.isSigned() || (I.isUnsigned() && .hasSameSign())) &&
7097 I.setPredicate(I.getUnsignedPredicate());
7098 I.setSameSign();
7099 return &I;
7100 }
7101
7102 return nullptr;
7103}
7104
7105
7106
7110
7111
7112
7115 return BinaryOperator::CreateAnd(Builder.CreateIsNull(X), Y);
7116
7117
7118
7121 return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y);
7122
7123
7132 bool IsSExt = ExtI->getOpcode() == Instruction::SExt;
7134 auto CreateRangeCheck = [&] {
7140 Pred1 == ICmpInst::ICMP_EQ ? Instruction::Or : Instruction::And,
7141 CmpV1, CmpV2);
7142 };
7143 if (C->isZero()) {
7145
7146
7149 } else if (!IsSExt || HasOneUse) {
7150
7151
7152
7153
7154 return CreateRangeCheck();
7155 }
7156 } else if (IsSExt ? C->isAllOnes() : C->isOne()) {
7158
7159
7160
7161
7164 } else if (!IsSExt || HasOneUse) {
7165
7166
7167
7168
7169 return CreateRangeCheck();
7170 }
7171 } else {
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7183 Instruction::ICmp, Pred1, X,
7185 ? (IsSExt ? -1 : 1)
7186 : 0));
7187 }
7188 }
7189
7190 return nullptr;
7191}
7192
7193
7194
7195
7200 return nullptr;
7201
7202 Value *Op0 = I.getOperand(0);
7203 Value *Op1 = I.getOperand(1);
7205 if (!Op1C)
7206 return nullptr;
7207
7209 if (!FlippedStrictness)
7210 return nullptr;
7211
7212 return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
7213}
7214
7215
7216
7218
7221 return nullptr;
7222
7223
7225 return nullptr;
7226
7227
7228
7230 I.setName(I.getName() + ".not");
7231
7232
7234
7235 return &I;
7236}
7237
7238
7241 Value *A = I.getOperand(0), *B = I.getOperand(1);
7242 assert(A->getType()->isIntOrIntVectorTy(1) && "Bools only");
7243
7244
7245
7246
7248 switch (I.getPredicate()) {
7253 default:
7254 llvm_unreachable("ICmp i1 X, C not simplified as expected.");
7255 }
7257 switch (I.getPredicate()) {
7262 default:
7263 llvm_unreachable("ICmp i1 X, C not simplified as expected.");
7264 }
7265 }
7266
7267 switch (I.getPredicate()) {
7268 default:
7271
7273
7275
7276 return BinaryOperator::CreateXor(A, B);
7277
7279
7281 [[fallthrough]];
7283
7284 return BinaryOperator::CreateAnd(Builder.CreateNot(A), B);
7285
7287
7289 [[fallthrough]];
7291
7292 return BinaryOperator::CreateAnd(Builder.CreateNot(B), A);
7293
7295
7297 [[fallthrough]];
7299
7300 return BinaryOperator::CreateOr(Builder.CreateNot(A), B);
7301
7303
7305 [[fallthrough]];
7307
7308 return BinaryOperator::CreateOr(Builder.CreateNot(B), A);
7309 }
7310}
7311
7312
7313
7314
7315
7316
7317
7324 switch (Pred) {
7327 break;
7330 break;
7331 default:
7332 return nullptr;
7333 }
7340
7341
7342
7343 switch (Pred) {
7346 break;
7349 break;
7350 default:
7351 return nullptr;
7352 }
7353 } else
7354 return nullptr;
7355
7356 Value *NewX = Builder.CreateLShr(X, Y, X->getName() + ".highbits");
7358 return CmpInst::Create(Instruction::ICmp, NewPred, NewX, Zero);
7359}
7360
7364 Value *LHS = Cmp.getOperand(0), *RHS = Cmp.getOperand(1);
7366
7368 Value *V = Builder.CreateCmp(Pred, X, Y, Cmp.getName());
7370 I->copyIRFlags(&Cmp);
7371 Module *M = Cmp.getModule();
7373 M, Intrinsic::vector_reverse, V->getType());
7375 };
7376
7378
7380 (LHS->hasOneUse() || RHS->hasOneUse()))
7381 return createCmpReverse(Pred, V1, V2);
7382
7383
7385 return createCmpReverse(Pred, V1, RHS);
7386 }
7387
7389 return createCmpReverse(Pred, LHS, V2);
7390
7393 return nullptr;
7394
7395
7396
7397
7400 V1Ty == V2->getType() && (LHS->hasOneUse() || RHS->hasOneUse())) {
7401 Value *NewCmp = Builder.CreateCmp(Pred, V1, V2);
7403 }
7404
7405
7406
7407
7410 return nullptr;
7411
7412
7413
7414 Constant *ScalarC = C->getSplatValue( true);
7415 int MaskSplatIndex;
7417
7418
7420 ScalarC);
7422 Value *NewCmp = Builder.CreateCmp(Pred, V1, C);
7424 }
7425
7426 return nullptr;
7427}
7428
7429
7430
7433 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
7434
7439 if (match(Op0, UAddOvResultPat) &&
7445
7446
7447
7451
7453 else
7454 return nullptr;
7455
7457}
7458
7460 if (.getOperand(0)->getType()->isPointerTy() ||
7462 I.getParent()->getParent(),
7463 I.getOperand(0)->getType()->getPointerAddressSpace())) {
7464 return nullptr;
7465 }
7469 Op->isLaunderOrStripInvariantGroup()) {
7471 Op->getOperand(0), I.getOperand(1));
7472 }
7473 return nullptr;
7474}
7475
7476
7477
7478
7479
7483 if (I.getType()->isVectorTy())
7484 return nullptr;
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7504 return nullptr;
7506 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())
7507 return nullptr;
7508 unsigned NumBits =
7509 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();
7510
7511 if (.isLegalInteger(NumBits))
7512 return nullptr;
7513
7515 auto *ScalarTy = Builder.getIntNTy(NumBits);
7516 LHS = Builder.CreateBitCast(LHS, ScalarTy, LHS->getName() + ".scalar");
7517 RHS = Builder.CreateBitCast(RHS, ScalarTy, RHS->getName() + ".scalar");
7519 I.getName());
7520 }
7521
7522 return nullptr;
7523}
7524
7525
7529
7532 return NI;
7533
7536 return NI;
7537
7540 return Res;
7541
7543 return Res;
7544 }
7545
7546 {
7549
7552 }
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564 {
7573 bool IsIntMinPosion = C->isAllOnesValue();
7574 switch (Pred) {
7585 CxtI, IsIntMinPosion
7586 ? Builder.CreateICmpSGT(X, AllOnesValue)
7587 : Builder.CreateICmpULT(
7588 X, ConstantInt::get(X->getType(), SMin + 1)));
7589 }
7594 CxtI, IsIntMinPosion
7595 ? Builder.CreateICmpSLT(X, NullValue)
7596 : Builder.CreateICmpUGT(
7597 X, ConstantInt::get(X->getType(), SMin)));
7598 }
7599 default:
7601 }
7602 }
7603 }
7604
7608
7609
7610 auto CheckUGT1 = [](const APInt &Divisor) { return Divisor.ugt(1); };
7611 {
7615 }
7616
7621 }
7622 }
7623
7624
7625 auto CheckNE0 = [](const APInt &Shift) { return !Shift.isZero(); };
7626 {
7630 }
7631
7636 }
7637 }
7638
7639 return nullptr;
7640}
7641
7645 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
7648
7649
7650
7651
7652 if (Op0Cplxity < Op1Cplxity) {
7653 I.swapOperands();
7656 }
7657
7660
7661
7662
7664 Value *Cond, *SelectTrue, *SelectFalse;
7666 m_Value(SelectFalse)))) {
7667 if (Value *V = dyn_castNegVal(SelectTrue)) {
7668 if (V == SelectFalse)
7669 return CmpInst::Create(Instruction::ICmp, I.getPredicate(), V, Op1);
7670 } else if (Value *V = dyn_castNegVal(SelectFalse)) {
7671 if (V == SelectTrue)
7672 return CmpInst::Create(Instruction::ICmp, I.getPredicate(), V, Op1);
7673 }
7674 }
7675 }
7676
7678 return Res;
7679
7682 return Res;
7683
7685 return Res;
7686
7688 return Res;
7689
7691 return Res;
7692
7694 return Res;
7695
7697 return Res;
7698
7700 return Res;
7701
7703 return Res;
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714 if (I.hasOneUse())
7719 return nullptr;
7720 }
7721
7722
7724 return Res;
7725
7726
7727
7728
7729
7730
7734
7738 }
7739
7740
7744 }
7745 }
7746
7747
7748
7749
7750
7751
7752
7754 return Res;
7755
7757 return Res;
7758
7759
7760
7762 return New;
7763
7766 return NV;
7769 return NV;
7770
7772 return Res;
7773
7775 return Res;
7778 return Res;
7779
7780 if (I.isCommutative()) {
7781 if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) {
7784 return &I;
7785 }
7786 }
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801 {
7805 (Op0->hasOneUse() || Op1->hasOneUse())) {
7806
7810 }
7811
7815 }
7816 }
7817 }
7818
7819
7820
7821
7822 {
7829 bool I0NUW = I0->hasNoUnsignedWrap();
7830 bool I1NUW = I1->hasNoUnsignedWrap();
7831 bool I0NSW = I0->hasNoSignedWrap();
7832 bool I1NSW = I1->hasNoSignedWrap();
7836 ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {
7838 ConstantInt::get(Op0->getType(), 0));
7839 }
7840 }
7841 }
7842
7843
7845 assert(Op1->getType()->isPointerTy() &&
7846 "Comparing pointer with non-pointer?");
7849 return nullptr;
7852 return nullptr;
7853 }
7854
7856 return Res;
7857
7858
7860 return R;
7861
7862 {
7864
7865
7866
7869 I.isEquality())
7870 return new ICmpInst(I.getInversePredicate(), Builder.CreateAnd(X, Y),
7871 Op1);
7872
7873
7875 bool ConsumesOp0, ConsumesOp1;
7877 isFreeToInvert(Op1, Op1->hasOneUse(), ConsumesOp1) &&
7878 (ConsumesOp0 || ConsumesOp1)) {
7881 assert(InvOp0 && InvOp1 &&
7882 "Mismatch between isFreeToInvert and getFreelyInverted");
7883 return new ICmpInst(I.getSwappedPredicate(), InvOp0, InvOp1);
7884 }
7885 }
7886
7893
7894
7895 if (AddI->getOpcode() == Instruction::Add &&
7896 OptimizeOverflowCheck(Instruction::Add, false, X, Y, *AddI,
7897 Result, Overflow)) {
7901 }
7902 }
7903
7904
7908 return R;
7909 }
7910
7911
7912
7913
7915 if ((I.isUnsigned() || I.isEquality()) &&
7918 Y->getType()->getScalarSizeInBits() == 1 &&
7919 (Op0->hasOneUse() || Op1->hasOneUse())) {
7924 OpWidth - 1))))) {
7925 unsigned ExtOpc = ExtI->getOpcode();
7926 unsigned ShiftOpc = ShiftI->getOpcode();
7927 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||
7928 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {
7929 Value *SLTZero =
7931 Value *Cmp = Builder.CreateICmp(Pred, SLTZero, Y, I.getName());
7933 }
7934 }
7935 }
7936 }
7937
7939 return Res;
7940
7942 return Res;
7943
7945 return Res;
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7959 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&
7960 !ACXI->isWeak())
7962
7964 return Res;
7965
7966 if (I.getType()->isVectorTy())
7968 return Res;
7969
7971 return Res;
7972
7974 return Res;
7975
7976 {
7978 const APInt *C1, *C2;
7981
7982
7985 Type *InputTy = A->getType();
7987
7989 APInt TruncC1 = C1->trunc(InputBitWidth);
7990
7992 TruncC1.setBit(InputBitWidth - 1);
7995 Pred, AndInst,
7996 ConstantInt::get(InputTy, C2->trunc(InputBitWidth)));
7997 }
7998 }
7999 }
8000 }
8001
8002 return Changed ? &I : nullptr;
8003}
8004
8005
8011 return nullptr;
8012
8013
8014
8016 if (MantissaWidth == -1)
8017 return nullptr;
8018
8022
8023 if (I.isEquality()) {
8025 bool IsExact = false;
8026 APSInt RHSCvt(IntWidth, LHSUnsigned);
8028
8029
8030
8031 if (!IsExact) {
8032
8033 APFloat RHSRoundInt(*RHS);
8035 if (*RHS != RHSRoundInt) {
8038
8041 }
8042 }
8043
8044
8045
8046 }
8047
8048
8049
8050
8051
8052
8053
8054
8055 if ((int)IntWidth > MantissaWidth) {
8056
8057 int Exp = ilogb(*RHS);
8060 if (MaxExponent < (int)IntWidth - !LHSUnsigned)
8061
8062 return nullptr;
8063 } else {
8064
8065
8066 if (MantissaWidth <= Exp && Exp <= (int)IntWidth - !LHSUnsigned)
8067
8068 return nullptr;
8069 }
8070 }
8071
8072
8073
8074
8075 assert(!RHS->isNaN() && "NaN comparison not already folded!");
8076
8078 switch (I.getPredicate()) {
8079 default:
8084 break;
8088 break;
8092 break;
8096 break;
8100 break;
8104 break;
8109 }
8110
8111
8112
8113
8114
8115 if (!LHSUnsigned) {
8116
8117
8121 if (SMax < *RHS) {
8126 }
8127 } else {
8128
8129
8133 if (UMax < *RHS) {
8138 }
8139 }
8140
8141 if (!LHSUnsigned) {
8142
8146 if (SMin > *RHS) {
8151 }
8152 } else {
8153
8157 if (UMin > *RHS) {
8162 }
8163 }
8164
8165
8166
8167
8168
8169 APSInt RHSInt(IntWidth, LHSUnsigned);
8170 bool IsExact;
8172 if (!RHS->isZero()) {
8173 if (!IsExact) {
8174
8175
8176
8177 switch (Pred) {
8178 default:
8185
8186
8187 if (RHS->isNegative())
8189 break;
8191
8192
8193 if (RHS->isNegative())
8195 break;
8197
8198
8199 if (RHS->isNegative())
8202 break;
8204
8205
8206 if (!RHS->isNegative())
8208 break;
8210
8211
8212 if (RHS->isNegative())
8214 break;
8216
8217
8218 if (RHS->isNegative())
8220 break;
8222
8223
8224 if (RHS->isNegative())
8227 break;
8229
8230
8231 if (!RHS->isNegative())
8233 break;
8234 }
8235 }
8236 }
8237
8238
8239
8242}
8243
8244
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8261
8262
8265 return nullptr;
8266
8267
8269 return nullptr;
8270
8271
8272 if (!LHSI->hasNoInfs() || .hasNoInfs())
8273 return nullptr;
8274
8275
8276
8279 return nullptr;
8280
8281 if (C->isZero())
8282 return nullptr;
8283
8284
8285 if (C->isNegative())
8286 Pred = I.getSwappedPredicate();
8287
8289}
8290
8291
8292
8293
8294
8295
8296
8297
8298
8302 bool RoundDown = false;
8303
8306 RoundDown = true;
8309 RoundDown = false;
8310 else
8311 return nullptr;
8312
8315 return nullptr;
8316
8318 return nullptr;
8319
8320 auto ConvertFltSema = [](const APFloat &Src, const fltSemantics &Sema) {
8321 bool LosesInfo;
8324 return Dest;
8325 };
8326
8327 auto NextValue = [](const APFloat &Value, bool RoundDown) {
8329 NextValue.next(RoundDown);
8330 return NextValue;
8331 };
8332
8333 APFloat NextCValue = NextValue(*CValue, RoundDown);
8334
8338
8339 APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);
8340 APFloat ExtNextCValue = ConvertFltSema(NextCValue, DestFltSema);
8341
8342
8343
8344
8345
8347 APFloat PrevCValue = NextValue(*CValue, !RoundDown);
8348 APFloat Bias = ConvertFltSema(*CValue - PrevCValue, DestFltSema);
8349
8350 ExtNextCValue = ExtCValue + Bias;
8351 }
8352
8355
8357 C.getType()->getScalarType()->getFltSemantics();
8358
8359
8360 APFloat MidValue = ConvertFltSema(ExtMidValue, SrcFltSema);
8361 if (MidValue != *CValue)
8362 ExtMidValue.next(!RoundDown);
8363
8364
8365
8366
8367
8369
8370 if (ConvertFltSema(ExtMidValue, SrcFltSema).isInfinity())
8371 return nullptr;
8372
8373
8374 APFloat NextExtMidValue = NextValue(ExtMidValue, RoundDown);
8375 if (ConvertFltSema(NextExtMidValue, SrcFltSema).isFinite())
8376 return nullptr;
8377 }
8378
8380 ConstantFP::get(DestType, ExtMidValue), "", &I);
8381}
8382
8383
8387 return nullptr;
8388
8391 return nullptr;
8392
8393 if (->isPosZero()) {
8394 if (->isSmallestNormalized())
8395 return nullptr;
8396
8397 const Function *F = I.getFunction();
8401
8405 };
8406
8407 switch (I.getPredicate()) {
8409
8412
8415
8418
8420 default:
8421 break;
8422 }
8423 }
8424
8425 return nullptr;
8426 }
8427
8431 };
8432
8433 switch (I.getPredicate()) {
8436
8437
8439
8441
8443
8445
8447
8449
8451
8453
8455
8457
8458 assert(.hasNoNaNs() && "fcmp should have simplified");
8460
8462
8463 assert(.hasNoNaNs() && "fcmp should have simplified");
8465
8472
8473
8474
8475
8476
8477 return replacePredAndOp0(&I, I.getPredicate(), X);
8478
8479 default:
8480 return nullptr;
8481 }
8482}
8483
8484
8488 return nullptr;
8489
8491 return nullptr;
8492
8496 };
8497
8498
8500 I.setHasNoInfs(false);
8501
8502 switch (I.getPredicate()) {
8505
8506
8514
8515
8516
8517
8518
8519
8521
8523
8526
8529
8532
8535
8538
8540 default:
8542 }
8543}
8544
8547 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
8548
8549
8552 Pred = I.getSwappedPredicate();
8553 }
8554
8556 return nullptr;
8557
8558
8559
8561 return new FCmpInst(Pred, Op0, Zero, "", &I);
8562}
8563
8569 switch (Pred) {
8570 default:
8571 break;
8578
8579
8580
8581
8586 break;
8587
8588 [[fallthrough]];
8595
8597 I.getFunction()->getDenormalMode(
8604 I.setHasNoNaNs(true);
8605 return &I;
8606 }
8607 break;
8608 }
8609
8610 return nullptr;
8611}
8612
8615 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
8616 Type *OpType = LHS->getType();
8618
8621
8622 if (!FloorX && !CeilX) {
8626 Pred = I.getSwappedPredicate();
8627 }
8628 }
8629
8630 switch (Pred) {
8632
8633 if (FloorX)
8635 "", &I);
8636 break;
8638
8639 if (FloorX)
8641 break;
8643
8644 if (CeilX)
8646 "", &I);
8647 break;
8649
8650 if (CeilX)
8652 break;
8654
8655 if (FloorX)
8657 break;
8659
8660 if (FloorX)
8662 "", &I);
8663 break;
8665
8666 if (CeilX)
8668 break;
8670
8671 if (CeilX)
8673 "", &I);
8674 break;
8675 default:
8676 break;
8677 }
8678
8679 return nullptr;
8680}
8681
8684
8685
8686
8687
8689 I.swapOperands();
8691 }
8692
8694 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
8696 SQ.getWithInstruction(&I)))
8698
8699
8701 assert(OpType == Op1->getType() && "fcmp with different-typed operands?");
8702 if (Op0 == Op1) {
8703 switch (Pred) {
8704 default:
8705 break;
8710
8713 return &I;
8714
8717 case FCmpInst::FCMP_OGE:
8719
8722 return &I;
8723 }
8724 }
8725
8726 if (I.isCommutative()) {
8727 if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) {
8730 return &I;
8731 }
8732 }
8733
8734
8735
8740
8744 }
8745
8746
8749 return new FCmpInst(I.getSwappedPredicate(), X, Y, "", &I);
8750
8752 return R;
8753
8754
8755
8756
8757
8758
8759
8760
8761 if (I.hasOneUse())
8766 return nullptr;
8767 }
8768
8769
8770
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8794 default:
8795 break;
8807 "", &I);
8814 "", &I);
8817 }
8818 }
8819
8820
8821
8829
8831 Type *IntTy = X->getType();
8832 const APInt &SignMask = ~APInt::getSignMask(IntTy->getScalarSizeInBits());
8833 Value *MaskX = Builder.CreateAnd(X, ConstantInt::get(IntTy, SignMask));
8835 }
8836 }
8837
8838
8843 case Instruction::Select:
8844
8849 return NV;
8850 break;
8851 case Instruction::FSub:
8854 return NV;
8855 break;
8856 case Instruction::PHI:
8858 return NV;
8859 break;
8860 case Instruction::SIToFP:
8861 case Instruction::UIToFP:
8863 return NV;
8864 break;
8865 case Instruction::FDiv:
8867 return NV;
8868 break;
8869 case Instruction::Load:
8873 return Res;
8874 break;
8875 case Instruction::FPTrunc:
8877 return NV;
8878 break;
8879 }
8880 }
8881
8883 return R;
8884
8886 return R;
8887
8889 return R;
8890
8892
8896 return new FCmpInst(I.getSwappedPredicate(), X, NegC, "", &I);
8897 }
8898
8899
8901 return new FCmpInst(Pred, X, Op1, "", &I);
8902
8903
8905 return new FCmpInst(Pred, Op0, Y, "", &I);
8906
8908
8910 return new FCmpInst(Pred, X, Y, "", &I);
8911
8915 X->getType()->getScalarType()->getFltSemantics();
8916 bool Lossy;
8919
8920 if (Lossy) {
8921
8922
8923
8924 switch (Pred) {
8926
8929
8933
8937
8939 default:
8940 break;
8941 }
8942 }
8943
8944
8945
8946
8949 if (!Lossy &&
8951 Constant *NewC = ConstantFP::get(X->getType(), TruncC);
8952 return new FCmpInst(Pred, X, NewC, "", &I);
8953 }
8954 }
8955 }
8956
8957
8958
8959
8960
8964 Type *IntType = Builder.getIntNTy(X->getType()->getScalarSizeInBits());
8966 IntType = VectorType::get(IntType, VecTy->getElementCount());
8967
8968
8970 Value *IntX = Builder.CreateBitCast(X, IntType);
8973 }
8974 }
8975
8976 {
8977 Value *CanonLHS = nullptr;
8979
8980 if (CanonLHS == Op1)
8981 return new FCmpInst(Pred, Op1, Op1, "", &I);
8982
8983 Value *CanonRHS = nullptr;
8985
8986 if (CanonRHS == Op0)
8987 return new FCmpInst(Pred, Op0, Op0, "", &I);
8988
8989
8990 if (CanonLHS && CanonRHS)
8991 return new FCmpInst(Pred, CanonLHS, CanonRHS, "", &I);
8992 }
8993
8994 if (I.getType()->isVectorTy())
8996 return Res;
8997
8998 return Changed ? &I : nullptr;
8999}
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 the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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...
static Instruction * foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI, Constant *RHSC)
Fold (C / X) < 0.0 --> X < 0.0 if possible. Swap predicate if necessary.
Definition InstCombineCompares.cpp:8245
static Instruction * foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)
Optimize fabs(X) compared with zero.
Definition InstCombineCompares.cpp:8384
static void collectOffsetOp(Value *V, SmallVectorImpl< OffsetOp > &Offsets, bool AllowRecursion)
Definition InstCombineCompares.cpp:5878
static Value * rewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags NW, const DataLayout &DL, SetVector< Value * > &Explored, InstCombiner &IC)
Returns a re-written value of Start as an indexed GEP using Base as a pointer.
Definition InstCombineCompares.cpp:507
static Instruction * foldICmpEqualityWithOffset(ICmpInst &I, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
Offset both sides of an equality icmp to see if we can save some instructions: icmp eq/ne X,...
Definition InstCombineCompares.cpp:5945
static bool addWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)
Compute Result = In1+In2, returning true if the result overflowed for this type.
Definition InstCombineCompares.cpp:46
static Instruction * foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
Definition InstCombineCompares.cpp:4970
static Instruction * foldVectorCmp(CmpInst &Cmp, InstCombiner::BuilderTy &Builder)
Definition InstCombineCompares.cpp:7361
static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q, unsigned Depth=0)
Definition InstCombineCompares.cpp:4386
static Value * createLogicFromTable(const std::bitset< 4 > &Table, Value *Op0, Value *Op1, IRBuilderBase &Builder, bool HasOneUse)
Definition InstCombineCompares.cpp:3038
static Instruction * foldICmpOfUAddOv(ICmpInst &I)
Definition InstCombineCompares.cpp:7431
static bool isChainSelectCmpBranch(const SelectInst *SI)
Return true when the instruction sequence within a block is select-cmp-br.
Definition InstCombineCompares.cpp:6813
static Instruction * foldICmpInvariantGroup(ICmpInst &I)
Definition InstCombineCompares.cpp:7459
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
Definition InstCombineCompares.cpp:5877
static Instruction * foldReductionIdiom(ICmpInst &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
This function folds patterns produced by lowering of reduce idioms, such as llvm.vector....
Definition InstCombineCompares.cpp:7480
static Instruction * canonicalizeICmpBool(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Integer compare with boolean values can always be turned into bitwise ops.
Definition InstCombineCompares.cpp:7239
OffsetKind
Definition InstCombineCompares.cpp:5913
@ Invalid
Definition InstCombineCompares.cpp:5913
@ Value
Definition InstCombineCompares.cpp:5913
@ Select
Definition InstCombineCompares.cpp:5913
static Instruction * foldFCmpFSubIntoFCmp(FCmpInst &I, Instruction *LHSI, Constant *RHSC, InstCombinerImpl &CI)
Definition InstCombineCompares.cpp:8564
static Value * foldICmpOrXorSubChain(ICmpInst &Cmp, BinaryOperator *Or, InstCombiner::BuilderTy &Builder)
Fold icmp eq/ne (or (xor/sub (X1, X2), xor/sub (X3, X4))), 0.
Definition InstCombineCompares.cpp:2022
static bool hasBranchUse(ICmpInst &I)
Given an icmp instruction, return true if any use of this comparison is a branch on sign bit comparis...
Definition InstCombineCompares.cpp:72
static Value * foldICmpWithLowBitMaskedVal(CmpPredicate Pred, Value *Op0, Value *Op1, const SimplifyQuery &Q, InstCombiner &IC)
Some comparisons can be simplified.
Definition InstCombineCompares.cpp:4493
static APInt getDemandedBitsLHSMask(ICmpInst &I, unsigned BitWidth)
When performing a comparison against a constant, it is possible that not all the bits in the LHS are ...
Definition InstCombineCompares.cpp:6752
static Instruction * foldICmpShlLHSC(ICmpInst &Cmp, Instruction *Shl, const APInt &C)
Fold icmp (shl nuw C2, Y), C.
Definition InstCombineCompares.cpp:2273
static Instruction * foldFCmpWithFloorAndCeil(FCmpInst &I, InstCombinerImpl &IC)
Definition InstCombineCompares.cpp:8613
static Instruction * foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
Definition InstCombineCompares.cpp:5067
static Instruction * foldICmpOfCmpIntrinsicWithConstant(CmpPredicate Pred, IntrinsicInst *I, const APInt &C, InstCombiner::BuilderTy &Builder)
Definition InstCombineCompares.cpp:4129
static Instruction * processUMulZExtIdiom(ICmpInst &I, Value *MulVal, const APInt *OtherVal, InstCombinerImpl &IC)
Recognize and process idiom involving test for multiplication overflow.
Definition InstCombineCompares.cpp:6605
static Instruction * foldSqrtWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)
Optimize sqrt(X) compared with zero.
Definition InstCombineCompares.cpp:8485
static Instruction * foldFCmpFNegCommonOp(FCmpInst &I)
Definition InstCombineCompares.cpp:8545
static Instruction * foldICmpWithHighBitMask(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)
Definition InstCombineCompares.cpp:7318
static ICmpInst * canonicalizeCmpWithConstant(ICmpInst &I)
If we have an icmp le or icmp ge instruction with a constant operand, turn it into the appropriate ic...
Definition InstCombineCompares.cpp:7196
static Instruction * foldICmpIntrinsicWithIntrinsic(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)
Fold an icmp with LLVM intrinsics.
Definition InstCombineCompares.cpp:3902
static Instruction * foldICmpUSubSatOrUAddSatWithConstant(CmpPredicate Pred, SaturatingInst *II, const APInt &C, InstCombiner::BuilderTy &Builder)
Definition InstCombineCompares.cpp:4044
static Instruction * foldICmpPow2Test(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Definition InstCombineCompares.cpp:5824
static bool subWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)
Compute Result = In1-In2, returning true if the result overflowed for this type.
Definition InstCombineCompares.cpp:59
static bool canRewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags &NW, const DataLayout &DL, SetVector< Value * > &Explored)
Returns true if we can rewrite Start as a GEP with pointer Base and some integer offset.
Definition InstCombineCompares.cpp:393
static Instruction * foldFCmpFpTrunc(FCmpInst &I, const Instruction &FPTrunc, const Constant &C)
Definition InstCombineCompares.cpp:8299
static Instruction * foldICmpXNegX(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Definition InstCombineCompares.cpp:4938
static Instruction * processUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B, ConstantInt *CI2, ConstantInt *CI1, InstCombinerImpl &IC)
The caller has matched a pattern of the form: I = icmp ugt (add (add A, B), CI2), CI1 If this is of t...
Definition InstCombineCompares.cpp:1060
static Value * foldShiftIntoShiftInAnotherHandOfAndInICmp(ICmpInst &I, const SimplifyQuery SQ, InstCombiner::BuilderTy &Builder)
Definition InstCombineCompares.cpp:4697
static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C)
Returns true if the exploded icmp can be expressed as a signed comparison to zero and updates the pre...
Definition InstCombineCompares.cpp:83
static Instruction * transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, const DataLayout &DL, InstCombiner &IC)
Converts (CMP GEPLHS, RHS) if this change would make RHS a constant.
Definition InstCombineCompares.cpp:601
static Instruction * foldCtpopPow2Test(ICmpInst &I, IntrinsicInst *CtpopLhs, const APInt &CRhs, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
Definition InstCombineCompares.cpp:3756
static void setInsertionPoint(IRBuilder<> &Builder, Value *V, bool Before=true)
Definition InstCombineCompares.cpp:481
static bool isNeutralValue(Instruction::BinaryOps BinaryOp, Value *RHS, bool IsSigned)
Definition InstCombineCompares.cpp:6503
static bool isMultipleOf(Value *X, const APInt &C, const SimplifyQuery &Q)
Return true if X is a multiple of C.
Definition InstCombineCompares.cpp:5113
static Value * foldICmpWithTruncSignExtendedVal(ICmpInst &I, InstCombiner::BuilderTy &Builder)
Some comparisons can be simplified.
Definition InstCombineCompares.cpp:4623
static Instruction * foldICmpOrXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)
Definition InstCombineCompares.cpp:5032
This file provides internal interfaces used to implement the InstCombine.
This file provides the interface for the instcombine pass implementation.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
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)
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
APInt bitcastToAPInt() const
static APFloat getLargest(const fltSemantics &Sem, bool Negative=false)
Returns the largest finite number in the given semantics.
opStatus next(bool nextDown)
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
LLVM_ABI FPClassTest classify() const
Return the FPClassTest which will return true for the value.
opStatus roundToIntegral(roundingMode RM)
Class for arbitrary precision integers.
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
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 isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getActiveBits() const
Compute the number of active bits in the value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
unsigned ceilLogBase2() const
bool sgt(const APInt &RHS) const
Signed greater than comparison.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
LLVM_ABI APInt usub_ov(const APInt &RHS, bool &Overflow) const
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
static APInt getMinValue(unsigned numBits)
Gets minimum unsigned value of APInt for a specific bit width.
bool isNegative() const
Determine sign of this APInt.
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
bool eq(const APInt &RHS) const
Equality comparison.
LLVM_ABI APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
LLVM_ABI APInt uadd_ov(const APInt &RHS, bool &Overflow) const
void negate()
Negate this APInt in place.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
bool isStrictlyPositive() const
Determine if this APInt Value is positive.
void flipAllBits()
Toggle every bit to its opposite value.
unsigned countl_one() const
Count the number of leading one bits.
unsigned logBase2() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
bool isMaxSignedValue() const
Determine if this is the largest signed value.
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt shl(unsigned shiftAmt) const
Left-shift function.
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.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const
bool isOne() const
Determine if this is a value of 1.
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
unsigned countr_one() const
Count the number of trailing one bits.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
An arbitrary precision integer that knows its signedness.
an instruction to allocate memory on the stack
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
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 const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
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...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
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.
Conditional or Unconditional Branch instruction.
Value * getArgOperand(unsigned i) const
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)
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate getStrictPredicate() const
For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.
static LLVM_ABI Predicate getFlippedStrictnessPredicate(Predicate pred)
This is a static version that you can use without an instruction available.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
bool isTrueWhenEqual() const
This is just a convenience.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getNonStrictPredicate() const
For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
static LLVM_ABI bool isStrictPredicate(Predicate predicate)
This is a static version that you can use without an instruction available.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
static bool isIntPredicate(Predicate P)
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI CmpPredicate getSwapped(CmpPredicate P)
Get the swapped predicate of a CmpPredicate.
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
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 * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getXor(Constant *C1, Constant *C2)
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
static LLVM_ABI Constant * getZero(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This class represents a range of values.
LLVM_ABI ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
LLVM_ABI std::optional< ConstantRange > exactUnionWith(const ConstantRange &CR) const
Union the two ranges and return the result if it can be represented exactly, otherwise return std::nu...
LLVM_ABI bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const
Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.
LLVM_ABI ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
LLVM_ABI ConstantRange difference(const ConstantRange &CR) const
Subtract the specified range from this range (aka relative complement of the sets).
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
LLVM_ABI ConstantRange truncate(uint32_t BitWidth, unsigned NoWrapKind=0) const
Return a new range in the specified integer type, which must be strictly smaller than the current typ...
static LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
LLVM_ABI ConstantRange inverse() const
Return a new range that is the logical not of the current set.
LLVM_ABI std::optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const
Intersect the two ranges and return the result if it can be represented exactly, otherwise return std...
LLVM_ABI ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
LLVM_ABI ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
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.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
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 * getAllOnesValue(Type *Ty)
LLVM_ABI const APInt & getUniqueInteger() const
If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
This instruction compares its operands according to the predicate given to the constructor.
static bool isEquality(Predicate Pred)
Represents flags for the getelementptr instruction/expression.
bool hasNoUnsignedSignedWrap() const
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()
bool isInBounds() const
Test whether this is an inbounds GEP, as defined by LangRef.html.
LLVM_ABI Type * getSourceElementType() const
Value * getPointerOperand()
GEPNoWrapFlags getNoWrapFlags() const
bool hasAllConstantIndices() const
Return true if all of the indices of this GEP are constant integers.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
This instruction compares its operands according to the predicate given to the constructor.
static bool isGE(Predicate P)
Return true if the predicate is SGE or UGE.
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
static bool isGT(Predicate P)
Return true if the predicate is SGT or UGT.
Predicate getFlippedSignednessPredicate() const
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
bool isEquality() const
Return true if this predicate is either EQ or NE.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Predicate getUnsignedPredicate() const
For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
static bool isLE(Predicate P)
Return true if the predicate is SLE or ULE.
Common base class shared among various IRBuilders.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Instruction * foldICmpShrConstant(ICmpInst &Cmp, BinaryOperator *Shr, const APInt &C)
Fold icmp ({al}shr X, Y), C.
Definition InstCombineCompares.cpp:2503
Instruction * foldICmpWithZextOrSext(ICmpInst &ICmp)
Definition InstCombineCompares.cpp:6323
Instruction * foldICmpSelectConstant(ICmpInst &Cmp, SelectInst *Select, ConstantInt *C)
Definition InstCombineCompares.cpp:3352
Instruction * foldICmpSRemConstant(ICmpInst &Cmp, BinaryOperator *UDiv, const APInt &C)
Definition InstCombineCompares.cpp:2657
Instruction * foldICmpBinOpWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Fold an icmp with BinaryOp and constant operand: icmp Pred BO, C.
Definition InstCombineCompares.cpp:3980
Instruction * foldICmpOrConstant(ICmpInst &Cmp, BinaryOperator *Or, const APInt &C)
Fold icmp (or X, Y), C.
Definition InstCombineCompares.cpp:2081
Instruction * foldICmpTruncWithTruncOrExt(ICmpInst &Cmp, const SimplifyQuery &Q)
Fold icmp (trunc nuw/nsw X), (trunc nuw/nsw Y).
Definition InstCombineCompares.cpp:1533
Instruction * foldSignBitTest(ICmpInst &I)
Fold equality-comparison between zero and any (maybe truncated) right-shift by one-less-than-bitwidth...
Definition InstCombineCompares.cpp:1166
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,...
Value * insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi, bool isSigned, bool Inside)
Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise (V < Lo || V >= Hi).
Instruction * foldICmpBinOp(ICmpInst &Cmp, const SimplifyQuery &SQ)
Try to fold icmp (binop), X or icmp X, (binop).
Definition InstCombineCompares.cpp:5127
Instruction * foldCmpLoadFromIndexedGlobal(LoadInst *LI, GetElementPtrInst *GEP, CmpInst &ICI, ConstantInt *AndCst=nullptr)
This is called when we see this pattern: cmp pred (load (gep GV, ...)), cmpcst where GV is a global v...
Definition InstCombineCompares.cpp:113
Instruction * foldICmpSubConstant(ICmpInst &Cmp, BinaryOperator *Sub, const APInt &C)
Fold icmp (sub X, Y), C.
Definition InstCombineCompares.cpp:2954
Instruction * foldICmpWithClamp(ICmpInst &Cmp, Value *X, MinMaxIntrinsic *Min)
Match and fold patterns like: icmp eq/ne X, min(max(X, Lo), Hi) which represents a range check and ca...
Definition InstCombineCompares.cpp:5792
Instruction * foldICmpInstWithConstantNotInt(ICmpInst &Cmp)
Handle icmp with constant (but not simple integer constant) RHS.
Definition InstCombineCompares.cpp:4293
bool SimplifyDemandedBits(Instruction *I, unsigned Op, const APInt &DemandedMask, KnownBits &Known, const SimplifyQuery &Q, unsigned Depth=0) override
This form of SimplifyDemandedBits simplifies the specified instruction operand if possible,...
Instruction * foldICmpShlConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)
Handle "(icmp eq/ne (shl AP2, A), AP1)" -> (icmp eq/ne A, TrailingZeros(AP1) - TrailingZeros(AP2)).
Definition InstCombineCompares.cpp:1016
Value * reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0, const SimplifyQuery &SQ, bool AnalyzeForSignBitExtraction=false)
Instruction * foldICmpEqIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)
Fold an equality icmp with LLVM intrinsic and constant operand.
Definition InstCombineCompares.cpp:3794
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,...
Value * foldMultiplicationOverflowCheck(ICmpInst &Cmp)
Fold (-1 u/ x) u< y ((x * y) ?
Definition InstCombineCompares.cpp:4870
Instruction * foldICmpWithConstant(ICmpInst &Cmp)
Fold icmp Pred X, C.
Definition InstCombineCompares.cpp:1316
CmpInst * canonicalizeICmpPredicate(CmpInst &I)
If we have a comparison with a non-canonical predicate, if we can update all the users,...
Definition InstCombineCompares.cpp:7217
Instruction * eraseInstFromFunction(Instruction &I) override
Combiner aware instruction erasure.
Instruction * foldICmpWithZero(ICmpInst &Cmp)
Definition InstCombineCompares.cpp:1197
Instruction * foldICmpCommutative(CmpPredicate Pred, Value *Op0, Value *Op1, ICmpInst &CxtI)
Definition InstCombineCompares.cpp:7526
Instruction * foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Fold an icmp equality instruction with binary operator LHS and constant RHS: icmp eq/ne BO,...
Definition InstCombineCompares.cpp:3601
Instruction * foldICmpUsingBoolRange(ICmpInst &I)
If one operand of an icmp is effectively a bool (value range of {0,1}), then try to reduce patterns b...
Definition InstCombineCompares.cpp:7107
Instruction * foldICmpWithTrunc(ICmpInst &Cmp)
Definition InstCombineCompares.cpp:6280
Instruction * foldICmpIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)
Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C.
Definition InstCombineCompares.cpp:4185
bool matchThreeWayIntCompare(SelectInst *SI, Value *&LHS, Value *&RHS, ConstantInt *&Less, ConstantInt *&Equal, ConstantInt *&Greater)
Match a select chain which produces one of three values based on whether the LHS is less than,...
Definition InstCombineCompares.cpp:3299
Instruction * visitFCmpInst(FCmpInst &I)
Definition InstCombineCompares.cpp:8682
Instruction * foldICmpUsingKnownBits(ICmpInst &Cmp)
Try to fold the comparison based on range information we can get by checking whether bits are known t...
Definition InstCombineCompares.cpp:6894
Instruction * foldICmpDivConstant(ICmpInst &Cmp, BinaryOperator *Div, const APInt &C)
Fold icmp ({su}div X, Y), C.
Definition InstCombineCompares.cpp:2772
Instruction * foldIRemByPowerOfTwoToBitTest(ICmpInst &I)
If we have: icmp eq/ne (urem/srem x, y), 0 iff y is a power-of-two, we can replace this with a bit te...
Definition InstCombineCompares.cpp:1147
Instruction * foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI, Constant *RHSC)
Fold fcmp ([us]itofp x, cst) if possible.
Definition InstCombineCompares.cpp:8006
Instruction * foldICmpUDivConstant(ICmpInst &Cmp, BinaryOperator *UDiv, const APInt &C)
Fold icmp (udiv X, Y), C.
Definition InstCombineCompares.cpp:2739
Instruction * foldICmpAddOpConst(Value *X, const APInt &C, CmpPredicate Pred)
Fold "icmp pred (X+C), X".
Definition InstCombineCompares.cpp:907
Instruction * foldICmpWithCastOp(ICmpInst &ICmp)
Handle icmp (cast x), (cast or constant).
Definition InstCombineCompares.cpp:6436
Instruction * foldICmpTruncConstant(ICmpInst &Cmp, TruncInst *Trunc, const APInt &C)
Fold icmp (trunc X), C.
Definition InstCombineCompares.cpp:1442
Instruction * foldICmpAddConstant(ICmpInst &Cmp, BinaryOperator *Add, const APInt &C)
Fold icmp (add X, Y), C.
Definition InstCombineCompares.cpp:3127
Instruction * foldICmpMulConstant(ICmpInst &Cmp, BinaryOperator *Mul, const APInt &C)
Fold icmp (mul X, Y), C.
Definition InstCombineCompares.cpp:2182
Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)
Instruction * foldICmpXorConstant(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)
Fold icmp (xor X, Y), C.
Definition InstCombineCompares.cpp:1592
Instruction * foldSelectICmp(CmpPredicate Pred, SelectInst *SI, Value *RHS, const ICmpInst &I)
Definition InstCombineCompares.cpp:4323
Instruction * foldICmpInstWithConstantAllowPoison(ICmpInst &Cmp, const APInt &C)
Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...
Definition InstCombineCompares.cpp:3958
Instruction * foldIsMultipleOfAPowerOfTwo(ICmpInst &Cmp)
Fold icmp eq (num + mask) & ~mask, num to icmp eq (and num, mask), 0 Where mask is a low bit mask.
Definition InstCombineCompares.cpp:1286
Instruction * foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1, const APInt &C2)
Fold icmp (and (sh X, Y), C2), C1.
Definition InstCombineCompares.cpp:1693
Instruction * foldICmpBinOpWithConstantViaTruthTable(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)
Definition InstCombineCompares.cpp:3088
Instruction * foldICmpInstWithConstant(ICmpInst &Cmp)
Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...
Definition InstCombineCompares.cpp:3554
Instruction * foldICmpXorShiftConst(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)
For power-of-2 C: ((X s>> ShiftC) ^ X) u< C --> (X + C) u< (C << 1) ((X s>> ShiftC) ^ X) u> (C - 1) -...
Definition InstCombineCompares.cpp:1664
Instruction * foldICmpShlConstant(ICmpInst &Cmp, BinaryOperator *Shl, const APInt &C)
Fold icmp (shl X, Y), C.
Definition InstCombineCompares.cpp:2323
Instruction * foldICmpAndConstant(ICmpInst &Cmp, BinaryOperator *And, const APInt &C)
Fold icmp (and X, Y), C.
Definition InstCombineCompares.cpp:1927
Instruction * foldICmpEquality(ICmpInst &Cmp)
Definition InstCombineCompares.cpp:6027
Instruction * foldICmpWithMinMax(Instruction &I, MinMaxIntrinsic *MinMax, Value *Z, CmpPredicate Pred)
Fold icmp Pred min|max(X, Y), Z.
Definition InstCombineCompares.cpp:5639
bool dominatesAllUses(const Instruction *DI, const Instruction *UI, const BasicBlock *DB) const
True when DB dominates all uses of DI except UI.
Definition InstCombineCompares.cpp:6791
bool foldAllocaCmp(AllocaInst *Alloca)
Definition InstCombineCompares.cpp:829
Instruction * visitICmpInst(ICmpInst &I)
Definition InstCombineCompares.cpp:7642
OverflowResult computeOverflow(Instruction::BinaryOps BinaryOp, bool IsSigned, Value *LHS, Value *RHS, Instruction *CxtI) const
Definition InstCombineCompares.cpp:6518
Instruction * foldICmpWithDominatingICmp(ICmpInst &Cmp)
Canonicalize icmp instructions based on dominating conditions.
Definition InstCombineCompares.cpp:1366
bool replacedSelectWithOperand(SelectInst *SI, const ICmpInst *Icmp, const unsigned SIOpd)
Try to replace select with select operand SIOpd in SI-ICmp sequence.
Definition InstCombineCompares.cpp:6866
Instruction * foldICmpShrConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)
Handle "(icmp eq/ne (ashr/lshr AP2, A), AP1)" -> (icmp eq/ne A, Log2(AP2/AP1)) -> (icmp eq/ne A,...
Definition InstCombineCompares.cpp:957
void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)
Freely adapt every user of V as-if V was changed to !V.
Instruction * foldICmpAndConstConst(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1)
Fold icmp (and X, C2), C1.
Definition InstCombineCompares.cpp:1780
Instruction * foldICmpBitCast(ICmpInst &Cmp)
Definition InstCombineCompares.cpp:3400
Instruction * foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, Instruction &I)
Fold comparisons between a GEP instruction and something else.
Definition InstCombineCompares.cpp:645
The core instruction combiner logic.
OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
unsigned ComputeMaxSignificantBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) 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).
OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS, const Instruction *CxtI, bool IsNSW=false) const
static unsigned getComplexity(Value *V)
Assign a complexity or rank value to LLVM Values.
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
uint64_t MaxArraySizeForCombine
Maximum size of array considered when transforming.
OverflowResult computeOverflowForSignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CxtI) const
static Constant * SubOne(Constant *C)
Subtract one from a Constant.
OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
static bool isCanonicalPredicate(CmpPredicate Pred)
Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...
void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const
bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)
Given i1 V, can every user of V be freely adapted if V is changed to !V ?
void addToWorklist(Instruction *I)
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS, const Instruction *CxtI) const
OverflowResult computeOverflowForUnsignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CxtI) const
Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)
const SimplifyQuery & getSimplifyQuery() const
bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)
LLVM_ABI bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
bool isArithmeticShift() const
Return true if this is an arithmetic shift right.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
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.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
An instruction for reading from memory.
bool isVolatile() const
Return true if this is a load from a volatile memory location.
This class represents min/max intrinsics.
static bool isMin(Intrinsic::ID ID)
Whether the intrinsic is a smin or umin.
static bool isSigned(Intrinsic::ID ID)
Whether the intrinsic is signed or unsigned.
A Module instance is used to store all the information related to an LLVM module.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
Represents a saturating add/sub intrinsic.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
reverse_iterator rbegin()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class represents a truncation of integer types.
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.
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.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
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)
LLVM_ABI int getFPMantissaWidth() const
Return the width of the mantissa of this type.
LLVM_ABI const fltSemantics & getFltSemantics() const
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
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.
iterator_range< use_iterator > uses()
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.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
LLVM_ABI APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A sign-divided by B, rounded by the given rounding mode.
@ 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.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
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.
cst_pred_ty< is_lowbit_mask > m_LowBitMask()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
cst_pred_ty< is_negative > m_Negative()
Match an integer or vector of negative values.
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.
cst_pred_ty< is_sign_mask > m_SignMask()
Match an integer or vector with only the sign bit(s) set.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
cst_pred_ty< is_power2 > m_Power2()
Match an integer or vector power-of-2.
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
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.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)
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.
cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()
Match a floating-point negative zero or positive zero.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
Matches an ICmp with a predicate over LHS and RHS in either order.
OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)
Matches a 'Neg' as 'sub nsw 0, V'.
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.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
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.
BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)
Matches logical shift operations.
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
m_Intrinsic_Ty< Opnd0 >::Ty m_Sqrt(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)
Matches an Xor with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)
Matches trunc nsw.
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)
CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
cst_pred_ty< is_negated_power2_or_zero > m_NegatedPower2OrZero()
Match a integer or vector negated power-of-2.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
cst_pred_ty< custom_checkfn< APInt > > m_CheckedInt(function_ref< bool(const APInt &)> CheckFn)
Match an integer or vector where CheckFn(ele) for each element is true.
cst_pred_ty< is_lowbit_mask_or_zero > m_LowBitMaskOrZero()
Match an integer or vector with only the low bit(s) set.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
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.
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Signum_match< Val_t > m_Signum(const Val_t &V)
Matches a signum pattern.
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)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()
Match a floating-point positive zero.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)
Match an icmp instruction checking for unsigned overflow on addition.
m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)
BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)
Matches integer remainder operations.
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)
CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)
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.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_unless< Ty > m_Unless(const Ty &M)
Match if the inner matcher does NOT match.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)
Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
@ NeverOverflows
Never overflows.
@ AlwaysOverflowsHigh
Always overflows in the direction of signed/unsigned max value.
@ AlwaysOverflowsLow
Always overflows in the direction of signed/unsigned min value.
@ MayOverflow
May or may not overflow.
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 bool isKnownNeverInfinity(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...
LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)
Given an exploded icmp instruction, return true if the comparison only checks the sign bit.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI Value * stripNullTest(Value *V)
Returns the inner value X if the expression has the form f(X) where f(X) == 0 if and only if X == 0,...
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...
LLVM_ABI Value * simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for an FCmpInst, fold the result or return null.
int ilogb(const APFloat &Arg)
Returns the exponent of the internal representation of the APFloat.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, bool UseInstrInfo=true, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
LLVM_ABI bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if 'V & Mask' is known to be zero.
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)
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...
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
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
LLVM_ABI Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
LLVM_ABI bool isKnownNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be negative (i.e.
SelectPatternFlavor
Specific patterns of select instructions we can match.
LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
LLVM_ABI LinearExpression decomposeLinearExpression(const DataLayout &DL, Value *Ptr)
Decompose a pointer into a linear expression.
LLVM_ABI bool isFinite(const Loop *L)
Return true if this loop can be assumed to run for a finite number of iterations.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
Returns: X * 2^Exp for integral exponents.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for an ICmpInst, fold the result or return null.
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 Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
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 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 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 T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ Sub
Subtraction of integers.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
LLVM_ABI bool isKnownNonEqual(const Value *V1, const Value *V2, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the given values are known to be non-equal when defined.
DWARFExpression::Operation Op
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
constexpr unsigned BitWidth
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.
LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
LLVM_ABI std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)
Convert an integer comparison with a constant RHS into an equivalent form with the strictness flipped...
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
LLVM_ABI bool isKnownPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the given value is known be positive (i.e.
LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)
Returns true if the give value is known to be non-negative.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
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.
std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)
Decompose an icmp into the form ((X & Mask) pred C) if possible.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
OffsetKind Kind
Definition InstCombineCompares.cpp:5916
Value * V2
Definition InstCombineCompares.cpp:5917
Value * V1
Definition InstCombineCompares.cpp:5917
Value * materialize(InstCombiner::BuilderTy &Builder) const
Definition InstCombineCompares.cpp:5929
bool isValid() const
Definition InstCombineCompares.cpp:5928
static OffsetResult value(Value *V)
Definition InstCombineCompares.cpp:5922
static OffsetResult select(Value *Cond, Value *TrueV, Value *FalseV)
Definition InstCombineCompares.cpp:5925
Value * V0
Definition InstCombineCompares.cpp:5917
static OffsetResult invalid()
Definition InstCombineCompares.cpp:5919
This callback is used in conjunction with PointerMayBeCaptured.
static CommonPointerBase compute(Value *LHS, Value *RHS)
Represent subnormal handling kind for floating point instruction inputs and outputs.
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
@ PositiveZero
Denormals are flushed to positive zero.
static constexpr DenormalMode getIEEE()
bool isNonNegative() const
Returns true if this value is known to be non-negative.
bool isZero() const
Returns true if value is all zero.
unsigned countMinTrailingZeros() const
Returns the minimum number of trailing zero bits.
unsigned countMaxTrailingZeros() const
Returns the maximum number of trailing zero bits possible.
APInt getSignedMaxValue() const
Return the maximal signed value possible given these KnownBits.
unsigned countMaxPopulation() const
Returns the maximum number of bits that could be one.
unsigned getBitWidth() const
Get the bit width of this value.
bool isConstant() const
Returns true if we know the value of all bits.
unsigned countMinLeadingZeros() const
Returns the minimum number of leading zero bits.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
APInt getMinValue() const
Return the minimal unsigned value possible given these KnownBits.
bool isStrictlyPositive() const
Returns true if this value is known to be positive.
bool isNegative() const
Returns true if this value is known to be negative.
unsigned countMinPopulation() const
Returns the number of bits known to be one.
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
Linear expression BasePtr + Index * Scale + Offset.
SelectPatternFlavor Flavor
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?
SimplifyQuery getWithInstruction(const Instruction *I) const
A MapVector that performs no allocations if smaller than a certain size.
Capture information for a specific Use.