LLVM: lib/IR/ConstantRange.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
25#include "llvm/Config/llvm-config.h"
38#include
39#include
40#include
41#include
42
43using namespace llvm;
44
48
51
55 "ConstantRange with unequal bit widths");
57 "Lower == Upper, but they aren't min or max value!");
58}
59
61 bool IsSigned) {
66
67
68
71
72
73
75 Lower.setSignBit();
78}
79
81
82
85
86
90 if (std::optional DifferentBit =
94 }
95 return Known;
96}
97
101 return CR;
102
104 switch (Pred) {
105 default:
106 llvm_unreachable("Invalid ICmp predicate to makeAllowedICmpRegion()");
108 return CR;
112 return getFull(W);
115 if (UMax.isMinValue())
116 return getEmpty(W);
118 }
121 if (SMax.isMinSignedValue())
122 return getEmpty(W);
124 }
131 if (UMin.isMaxValue())
132 return getEmpty(W);
134 }
137 if (SMin.isMaxSignedValue())
138 return getEmpty(W);
140 }
145 }
146}
147
150
151
152
153
156}
157
160
161
162
163
164
165
168}
169
173 return true;
174
177}
178
182 return true;
183
186}
187
192 "Only for relational integer predicates!");
193
196
198 return FlippedSignednessPred;
199
202
204}
205
214 RHS = *OnlyElt;
217 RHS = *OnlyMissingElt;
218 } else if (getLower().isMinSignedValue() || getLower().isMinValue()) {
219 Pred =
222 } else if (getUpper().isMinSignedValue() || getUpper().isMinValue()) {
223 Pred =
226 } else {
230 }
231
233 "Bad result!");
234}
235
237 APInt &RHS) const {
240 return Offset.isZero();
241}
242
246 return true;
247
248 switch (Pred) {
251 if (const APInt *R = Other.getSingleElement())
252 return *L == *R;
253 return false;
272 default:
274 }
275}
276
277
279 unsigned BitWidth = V.getBitWidth();
280 if (V == 0)
281 return ConstantRange::getFull(V.getBitWidth());
282
288}
289
290
292
293 unsigned BitWidth = V.getBitWidth();
294 if (V == 0)
295 return ConstantRange::getFull(BitWidth);
296
299
300 if (V.isAllOnes())
302
304 if (V.isNegative()) {
307 } else {
310 }
312}
313
317 unsigned NoWrapKind) {
319
321
322 assert((NoWrapKind == OBO::NoSignedWrap ||
323 NoWrapKind == OBO::NoUnsignedWrap) &&
324 "NoWrapKind invalid!");
325
326 bool Unsigned = NoWrapKind == OBO::NoUnsignedWrap;
328
329 switch (BinOp) {
330 default:
332
333 case Instruction::Add: {
336
340 SMin.isNegative() ? SignedMinVal - SMin : SignedMinVal,
341 SMax.isStrictlyPositive() ? SignedMinVal - SMax : SignedMinVal);
342 }
343
344 case Instruction::Sub: {
347
351 SMax.isStrictlyPositive() ? SignedMinVal + SMax : SignedMinVal,
352 SMin.isNegative() ? SignedMinVal + SMin : SignedMinVal);
353 }
354
355 case Instruction::Mul:
358
359
360 if (const APInt *C = Other.getSingleElement())
362
365
366 case Instruction::Shl: {
367
368
372
373
375 }
376
377
378
385 }
386 }
387}
388
391 unsigned NoWrapKind) {
392
393
395}
396
399 unsigned BitWidth = Mask.getBitWidth();
400
403
404 if (Mask.isZero())
406
407
408
409
412}
413
415 return Lower == Upper && Lower.isMaxValue();
416}
417
419 return Lower == Upper && Lower.isMinValue();
420}
421
423 return Lower.ugt(Upper) && !Upper.isZero();
424}
425
427 return Lower.ugt(Upper);
428}
429
432}
433
435 return Lower.sgt(Upper);
436}
437
438bool
442 return false;
443 if (Other.isFullSet())
444 return true;
445 return (Upper - Lower).ult(Other.Upper - Other.Lower);
446}
447
448bool
450
451
454
455 return (Upper - Lower).ugt(MaxSize);
456}
457
459
461 return true;
463 return false;
464
466}
467
469
471}
472
474
476 return true;
478 return false;
479
481}
482
487}
488
493}
494
499}
500
505}
506
508 if (Lower == Upper)
510
512 return Lower.ule(V) && V.ult(Upper);
513 return Lower.ule(V) || V.ult(Upper);
514}
515
519
521 if (Other.isUpperWrapped())
522 return false;
523
524 return Lower.ule(Other.getLower()) && Other.getUpper().ule(Upper);
525 }
526
527 if (.isUpperWrapped())
528 return Other.getUpper().ule(Upper) ||
530
531 return Other.getUpper().ule(Upper) && Lower.ule(Other.getLower());
532}
533
536 return 0;
537
539}
540
543 return 0;
544
545 return std::max(getSignedMin().getSignificantBits(),
547}
548
551
552 if (Lower == Upper)
553 return *this;
555}
556
559}
560
566 return CR1;
568 return CR2;
571 return CR1;
573 return CR2;
574 }
575
577 return CR1;
578 return CR2;
579}
580
584 "ConstantRange types don't agree!");
585
586
589
592
594 if (Lower.ult(CR.Lower)) {
595
596
597 if (Upper.ule(CR.Lower))
598 return getEmpty();
599
600
601
602 if (Upper.ult(CR.Upper))
604
605
606
607 return CR;
608 }
609
610
611 if (Upper.ult(CR.Upper))
612 return *this;
613
614
615
616 if (Lower.ult(CR.Upper))
618
619
620
621 return getEmpty();
622 }
623
625 if (CR.Lower.ult(Upper)) {
626
627
628 if (CR.Upper.ult(Upper))
629 return CR;
630
631
632
633 if (CR.Upper.ule(Lower))
635
636
637
639 }
640 if (CR.Lower.ult(Lower)) {
641
642
643 if (CR.Upper.ule(Lower))
644 return getEmpty();
645
646
647
649 }
650
651
652
653 return CR;
654 }
655
656 if (CR.Upper.ult(Upper)) {
657
658
659 if (CR.Lower.ult(Upper))
661
662
663
664 if (CR.Lower.ult(Lower))
666
667
668
669 return CR;
670 }
671 if (CR.Upper.ule(Lower)) {
672
673
674 if (CR.Lower.ult(Lower))
675 return *this;
676
677
678
680 }
681
682
683
685}
686
690 "ConstantRange types don't agree!");
691
694
697
699
700
701
702
703
704 if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower))
707
708 APInt L = CR.Lower.ult(Lower) ? CR.Lower : Lower;
709 APInt U = (CR.Upper - 1).ugt(Upper - 1) ? CR.Upper : Upper;
710
711 if (L.isZero() && U.isZero())
712 return getFull();
713
714 return ConstantRange(std::move(L), std::move(U));
715 }
716
718
719
720 if (CR.Upper.ule(Upper) || CR.Lower.uge(Lower))
721 return *this;
722
723
724
725 if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper))
726 return getFull();
727
728
729
730
731
732
733 if (Upper.ult(CR.Lower) && CR.Upper.ult(Lower))
736
737
738
739 if (Upper.ult(CR.Lower) && Lower.ule(CR.Upper))
741
742
743
744 assert(CR.Lower.ule(Upper) && CR.Upper.ult(Lower) &&
745 "ConstantRange::unionWith missed a case with one range wrapped");
747 }
748
749
750
751 if (CR.Lower.ule(Upper) || Lower.ule(CR.Upper))
752 return getFull();
753
754 APInt L = CR.Lower.ult(Lower) ? CR.Lower : Lower;
755 APInt U = CR.Upper.ugt(Upper) ? CR.Upper : Upper;
756
757 return ConstantRange(std::move(L), std::move(U));
758}
759
760std::optional
762
765 return Result;
766 return std::nullopt;
767}
768
769std::optional
771
774 return Result;
775 return std::nullopt;
776}
777
779 uint32_t ResultBitWidth) const {
780 switch (CastOp) {
781 default:
783 case Instruction::Trunc:
784 return truncate(ResultBitWidth);
785 case Instruction::SExt:
787 case Instruction::ZExt:
789 case Instruction::BitCast:
790 return *this;
791 case Instruction::FPToUI:
792 case Instruction::FPToSI:
794 return *this;
795 else
796 return getFull(ResultBitWidth);
797 case Instruction::UIToFP: {
798
802 if (ResultBitWidth > BW) {
803 Min = Min.zext(ResultBitWidth);
804 Max = Max.zext(ResultBitWidth);
805 }
806 return getNonEmpty(std::move(Min), std::move(Max) + 1);
807 }
808 case Instruction::SIToFP: {
809
813 if (ResultBitWidth > BW) {
814 SMin = SMin.sext(ResultBitWidth);
815 SMax = SMax.sext(ResultBitWidth);
816 }
818 }
819 case Instruction::FPTrunc:
820 case Instruction::FPExt:
821 case Instruction::IntToPtr:
822 case Instruction::PtrToInt:
823 case Instruction::AddrSpaceCast:
824
825 return getFull(ResultBitWidth);
826 };
827}
828
830 if (isEmptySet()) return getEmpty(DstTySize);
831
833 assert(SrcTySize < DstTySize && "Not a value extension");
835
836 APInt LowerExt(DstTySize, 0);
837 if (!Upper)
838 LowerExt = Lower.zext(DstTySize);
841 }
842
844}
845
847 if (isEmptySet()) return getEmpty(DstTySize);
848
850 assert(SrcTySize < DstTySize && "Not a value extension");
851
852
855
859 }
860
862}
863
867 return getEmpty(DstTySize);
869 return getFull(DstTySize);
870
871 APInt LowerDiv(Lower), UpperDiv(Upper);
872 ConstantRange Union(DstTySize, false);
873
874
875
876
878
879
881 return getFull(DstTySize);
882
885
886
887
888 if (LowerDiv == UpperDiv)
889 return Union;
890 }
891
892
893 if (LowerDiv.getActiveBits() > DstTySize) {
894
896 LowerDiv -= Adjust;
897 UpperDiv -= Adjust;
898 }
899
900 unsigned UpperDivWidth = UpperDiv.getActiveBits();
901 if (UpperDivWidth <= DstTySize)
904
905
906 if (UpperDivWidth == DstTySize + 1) {
907
908 UpperDiv.clearBit(DstTySize);
909 if (UpperDiv.ult(LowerDiv))
912 }
913
914 return getFull(DstTySize);
915}
916
919 if (SrcTySize > DstTySize)
921 if (SrcTySize < DstTySize)
923 return *this;
924}
925
928 if (SrcTySize > DstTySize)
930 if (SrcTySize < DstTySize)
932 return *this;
933}
934
938
939 switch (BinOp) {
940 case Instruction::Add:
942 case Instruction::Sub:
944 case Instruction::Mul:
946 case Instruction::UDiv:
948 case Instruction::SDiv:
950 case Instruction::URem:
952 case Instruction::SRem:
954 case Instruction::Shl:
956 case Instruction::LShr:
958 case Instruction::AShr:
960 case Instruction::And:
962 case Instruction::Or:
964 case Instruction::Xor:
966
967
968 case Instruction::FAdd:
970 case Instruction::FSub:
972 case Instruction::FMul:
974 default:
975
976 return getFull();
977 }
978}
979
982 unsigned NoWrapKind) const {
984
985 switch (BinOp) {
986 case Instruction::Add:
988 case Instruction::Sub:
990 case Instruction::Mul:
992 case Instruction::Shl:
994 default:
995
996
998 }
999}
1000
1002 switch (IntrinsicID) {
1003 case Intrinsic::uadd_sat:
1004 case Intrinsic::usub_sat:
1005 case Intrinsic::sadd_sat:
1006 case Intrinsic::ssub_sat:
1007 case Intrinsic::umin:
1008 case Intrinsic::umax:
1009 case Intrinsic::smin:
1010 case Intrinsic::smax:
1011 case Intrinsic::abs:
1012 case Intrinsic::ctlz:
1013 case Intrinsic::cttz:
1014 case Intrinsic::ctpop:
1015 return true;
1016 default:
1017 return false;
1018 }
1019}
1020
1023 switch (IntrinsicID) {
1024 case Intrinsic::uadd_sat:
1025 return Ops[0].uadd_sat(Ops[1]);
1026 case Intrinsic::usub_sat:
1027 return Ops[0].usub_sat(Ops[1]);
1028 case Intrinsic::sadd_sat:
1029 return Ops[0].sadd_sat(Ops[1]);
1030 case Intrinsic::ssub_sat:
1031 return Ops[0].ssub_sat(Ops[1]);
1032 case Intrinsic::umin:
1033 return Ops[0].umin(Ops[1]);
1034 case Intrinsic::umax:
1035 return Ops[0].umax(Ops[1]);
1036 case Intrinsic::smin:
1037 return Ops[0].smin(Ops[1]);
1038 case Intrinsic::smax:
1039 return Ops[0].smax(Ops[1]);
1040 case Intrinsic::abs: {
1041 const APInt *IntMinIsPoison = Ops[1].getSingleElement();
1042 assert(IntMinIsPoison && "Must be known (immarg)");
1043 assert(IntMinIsPoison->getBitWidth() == 1 && "Must be boolean");
1044 return Ops[0].abs(IntMinIsPoison->getBoolValue());
1045 }
1046 case Intrinsic::ctlz: {
1047 const APInt *ZeroIsPoison = Ops[1].getSingleElement();
1048 assert(ZeroIsPoison && "Must be known (immarg)");
1050 return Ops[0].ctlz(ZeroIsPoison->getBoolValue());
1051 }
1052 case Intrinsic::cttz: {
1053 const APInt *ZeroIsPoison = Ops[1].getSingleElement();
1054 assert(ZeroIsPoison && "Must be known (immarg)");
1056 return Ops[0].cttz(ZeroIsPoison->getBoolValue());
1057 }
1058 case Intrinsic::ctpop:
1059 return Ops[0].ctpop();
1060 default:
1063 }
1064}
1065
1069 return getEmpty();
1071 return getFull();
1072
1075 if (NewLower == NewUpper)
1076 return getFull();
1077
1079 if (X.isSizeStrictlySmallerThan(*this) ||
1080 X.isSizeStrictlySmallerThan(Other))
1081
1082 return getFull();
1083 return X;
1084}
1085
1087 unsigned NoWrapKind,
1089
1090
1092 return getEmpty();
1094 return getFull();
1095
1098
1099
1100
1101
1102
1103
1104 if (NoWrapKind & OBO::NoSignedWrap)
1105 Result = Result.intersectWith(sadd_sat(Other), RangeType);
1106
1107 if (NoWrapKind & OBO::NoUnsignedWrap)
1108 Result = Result.intersectWith(uadd_sat(Other), RangeType);
1109
1110 return Result;
1111}
1112
1116 return getEmpty();
1118 return getFull();
1119
1122 if (NewLower == NewUpper)
1123 return getFull();
1124
1126 if (X.isSizeStrictlySmallerThan(*this) ||
1127 X.isSizeStrictlySmallerThan(Other))
1128
1129 return getFull();
1130 return X;
1131}
1132
1134 unsigned NoWrapKind,
1136
1137
1139 return getEmpty();
1141 return getFull();
1142
1145
1146
1147
1148
1149
1150
1151 if (NoWrapKind & OBO::NoSignedWrap)
1152 Result = Result.intersectWith(ssub_sat(Other), RangeType);
1153
1154 if (NoWrapKind & OBO::NoUnsignedWrap) {
1156 return getEmpty();
1157 Result = Result.intersectWith(usub_sat(Other), RangeType);
1158 }
1159
1160 return Result;
1161}
1162
1165
1166
1167
1168
1169
1171 return getEmpty();
1172
1174 if (C->isOne())
1176 if (C->isAllOnes())
1178 }
1179
1180 if (const APInt *C = Other.getSingleElement()) {
1181 if (C->isOne())
1182 return *this;
1183 if (C->isAllOnes())
1185 }
1186
1187
1188
1189
1190
1191
1192
1193
1198
1200 this_max * Other_max + 1);
1202
1203
1204
1205
1206
1209 return UR;
1210
1211
1212
1213
1214
1215
1216
1221
1222 auto L = {this_min * Other_min, this_min * Other_max,
1223 this_max * Other_min, this_max * Other_max};
1224 auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); };
1225 ConstantRange Result_sext(std::min(L, Compare), std::max(L, Compare) + 1);
1227
1229}
1230
1233 unsigned NoWrapKind,
1236 return getEmpty();
1238 return getFull();
1239
1241
1243 Result = Result.intersectWith(smul_sat(Other), RangeType);
1244
1246 Result = Result.intersectWith(umul_sat(Other), RangeType);
1247
1248
1251 !Result.isAllNonNegative()) {
1253 Result = Result.intersectWith(
1256 RangeType);
1257 }
1258
1259 return Result;
1260}
1261
1264 return getEmpty();
1265
1268 APInt OtherMin = Other.getSignedMin();
1269 APInt OtherMax = Other.getSignedMax();
1270
1271 bool O1, O2, O3, O4;
1272 auto Muls = {Min.smul_ov(OtherMin, O1), Min.smul_ov(OtherMax, O2),
1273 Max.smul_ov(OtherMin, O3), Max.smul_ov(OtherMax, O4)};
1274 if (O1 || O2 || O3 || O4)
1275 return getFull();
1276
1277 auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); };
1278 return getNonEmpty(std::min(Muls, Compare), std::max(Muls, Compare) + 1);
1279}
1280
1283
1284
1286 return getEmpty();
1292 return Res;
1293}
1294
1297
1298
1300 return getEmpty();
1306 return Res;
1307}
1308
1311
1312
1314 return getEmpty();
1320 return Res;
1321}
1322
1325
1326
1328 return getEmpty();
1334 return Res;
1335}
1336
1339 if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isZero())
1340 return getEmpty();
1341
1343
1344 APInt RHS_umin = RHS.getUnsignedMin();
1345 if (RHS_umin.isZero()) {
1346
1347
1348 if (RHS.getUpper() == 1)
1349 RHS_umin = RHS.getLower();
1350 else
1351 RHS_umin = 1;
1352 }
1353
1356}
1357
1359
1360
1361
1364
1373
1376
1378 (PosL.Upper - 1).sdiv(PosR.Lower) + 1);
1379
1381
1382
1383
1384
1385
1386
1387 APInt Lo = (NegL.Upper - 1).sdiv(NegR.Lower);
1389
1390
1392 APInt AdjNegRUpper;
1393 if (RHS.Lower.isAllOnes())
1394
1395 AdjNegRUpper = RHS.Upper;
1396 else
1397
1398 AdjNegRUpper = NegR.Upper - 1;
1399
1402 }
1403
1404
1405
1406 if (NegL.Upper != SignedMin + 1) {
1407 APInt AdjNegLLower;
1408 if (Upper == SignedMin + 1)
1409
1410 AdjNegLLower = Lower;
1411 else
1412
1413 AdjNegLLower = NegL.Lower + 1;
1414
1417 AdjNegLLower.sdiv(NegR.Upper - 1) + 1));
1418 }
1419 } else {
1422 }
1423 }
1424
1427
1428 NegRes = ConstantRange((PosL.Upper - 1).sdiv(NegR.Upper - 1),
1429 PosL.Lower.sdiv(NegR.Lower) + 1);
1430
1432
1435 (NegL.Upper - 1).sdiv(PosR.Upper - 1) + 1));
1436
1437
1439
1440
1443 return Res;
1444}
1445
1447 if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isZero())
1448 return getEmpty();
1449
1450 if (const APInt *RHSInt = RHS.getSingleElement()) {
1451
1452 if (RHSInt->isZero())
1453 return getEmpty();
1454
1456 return {LHSInt->urem(*RHSInt)};
1457 }
1458
1459
1461 return *this;
1462
1463
1466}
1467
1470 return getEmpty();
1471
1472 if (const APInt *RHSInt = RHS.getSingleElement()) {
1473
1474 if (RHSInt->isZero())
1475 return getEmpty();
1476
1478 return {LHSInt->srem(*RHSInt)};
1479 }
1480
1484
1485
1486 if (MaxAbsRHS.isZero())
1487 return getEmpty();
1488
1489 if (MinAbsRHS.isZero())
1490 ++MinAbsRHS;
1491
1493
1495
1496 if (MaxLHS.ult(MinAbsRHS))
1497 return *this;
1498
1499
1502 }
1503
1504
1505 if (MaxLHS.isNegative()) {
1506 if (MinLHS.ugt(-MinAbsRHS))
1507 return *this;
1508
1511 }
1512
1513
1517}
1518
1521}
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1550
1551
1552 if ((LHS.isFullSet() || RHS.isFullSet()) ||
1553 (LHS.isWrappedSet() || RHS.isWrappedSet()))
1555
1556 auto LLo = LHS.getLower();
1557 auto LHi = LHS.getUpper() - 1;
1558 auto RLo = RHS.getLower();
1559 auto RHi = RHS.getUpper() - 1;
1560
1561
1562 auto Mask = ~((LLo ^ LHi) | (RLo ^ RHi) | (LLo ^ RLo));
1563 unsigned LeadingOnes = Mask.countLeadingOnes();
1564 Mask.clearLowBits(BitWidth - LeadingOnes);
1565
1567 const APInt &BHi) {
1568 unsigned LeadingOnes = ((BLo & BHi) | Mask).countLeadingOnes();
1569 unsigned StartBit = BitWidth - LeadingOnes;
1570 ALo.clearLowBits(StartBit);
1571 return ALo;
1572 };
1573
1574 auto LowerBoundByLHS = estimateBound(LLo, RLo, RHi);
1575 auto LowerBoundByRHS = estimateBound(RLo, LLo, LHi);
1576
1577 return APIntOps::umax(LowerBoundByLHS, LowerBoundByRHS);
1578}
1579
1582 return getEmpty();
1583
1589 return KnownBitsRange.intersectWith(UMinUMaxRange);
1590}
1591
1594 return getEmpty();
1595
1598
1599
1600
1601
1602
1603
1604 auto UpperBound =
1606
1609 return KnownBitsRange.intersectWith(UMaxUMinRange);
1610}
1611
1614 return getEmpty();
1615
1616
1619
1620
1621 if (Other.isSingleElement() && Other.getSingleElement()->isAllOnes())
1624 return Other.binaryNot();
1625
1628 KnownBits Known = LHSKnown ^ RHSKnown;
1630
1632 return CR;
1633
1634
1635
1636
1637 if ((~LHSKnown.Zero).isSubsetOf(RHSKnown.One))
1639 else if ((~RHSKnown.Zero).isSubsetOf(LHSKnown.One))
1641 return CR;
1642}
1643
1647 return getEmpty();
1648
1651 if (const APInt *RHS = Other.getSingleElement()) {
1653 if (RHS->uge(BW))
1654 return getEmpty();
1655
1656 unsigned EqualLeadingBits = (Min ^ Max).countl_zero();
1657 if (RHS->ule(EqualLeadingBits))
1659
1662 }
1663
1664 APInt OtherMax = Other.getUnsignedMax();
1666
1667
1668 Max <<= Other.getUnsignedMin();
1669 Min <<= OtherMax;
1671 }
1672
1673
1674 if (OtherMax.ugt(Max.countl_zero()))
1675 return getFull();
1676
1677
1678
1679 Min <<= Other.getUnsignedMin();
1680 Max <<= OtherMax;
1681
1683}
1684
1688 bool Overflow;
1689 APInt LHSMin = LHS.getUnsignedMin();
1690 unsigned RHSMin = RHS.getUnsignedMin().getLimitedValue(BitWidth);
1691 APInt MinShl = LHSMin.ushl_ov(RHSMin, Overflow);
1692 if (Overflow)
1693 return ConstantRange::getEmpty(BitWidth);
1694 APInt LHSMax = LHS.getUnsignedMax();
1695 unsigned RHSMax = RHS.getUnsignedMax().getLimitedValue(BitWidth);
1696 APInt MaxShl = MinShl;
1698 if (RHSMin <= MaxShAmt)
1699 MaxShl = LHSMax << std::min(RHSMax, MaxShAmt);
1700 RHSMin = std::max(RHSMin, MaxShAmt + 1);
1702 if (RHSMin <= RHSMax)
1706}
1707
1709 const APInt &LHSMax,
1710 unsigned RHSMin,
1711 unsigned RHSMax) {
1713 bool Overflow;
1714 APInt MinShl = LHSMin.sshl_ov(RHSMin, Overflow);
1715 if (Overflow)
1716 return ConstantRange::getEmpty(BitWidth);
1717 APInt MaxShl = MinShl;
1719 if (RHSMin <= MaxShAmt)
1720 MaxShl = LHSMax << std::min(RHSMax, MaxShAmt);
1721 RHSMin = std::max(RHSMin, MaxShAmt + 1);
1723 if (RHSMin <= RHSMax)
1727}
1728
1730 const APInt &LHSMax,
1731 unsigned RHSMin, unsigned RHSMax) {
1733 bool Overflow;
1734 APInt MaxShl = LHSMax.sshl_ov(RHSMin, Overflow);
1735 if (Overflow)
1736 return ConstantRange::getEmpty(BitWidth);
1737 APInt MinShl = MaxShl;
1739 if (RHSMin <= MaxShAmt)
1740 MinShl = LHSMin.shl(std::min(RHSMax, MaxShAmt));
1741 RHSMin = std::max(RHSMin, MaxShAmt + 1);
1743 if (RHSMin <= RHSMax)
1746}
1747
1751 unsigned RHSMin = RHS.getUnsignedMin().getLimitedValue(BitWidth);
1752 unsigned RHSMax = RHS.getUnsignedMax().getLimitedValue(BitWidth);
1753 APInt LHSMin = LHS.getSignedMin();
1754 APInt LHSMax = LHS.getSignedMax();
1760 RHSMax)
1762 RHSMin, RHSMax),
1764}
1765
1767 unsigned NoWrapKind,
1770 return getEmpty();
1771
1772 switch (NoWrapKind) {
1773 case 0:
1783 default:
1785 }
1786}
1787
1791 return getEmpty();
1792
1796}
1797
1801 return getEmpty();
1802
1803
1804
1805
1806
1807
1808
1810
1811
1812
1813
1814
1815
1817
1818
1819
1820
1821
1822
1824
1825
1826
1827
1828
1829
1831
1834
1835 min = PosMin;
1836 max = PosMax;
1838
1839 min = NegMin;
1840 max = NegMax;
1841 } else {
1842
1843 min = NegMin;
1844 max = PosMax;
1845 }
1847}
1848
1851 return getEmpty();
1852
1855 return getNonEmpty(std::move(NewL), std::move(NewU));
1856}
1857
1860 return getEmpty();
1861
1864 return getNonEmpty(std::move(NewL), std::move(NewU));
1865}
1866
1869 return getEmpty();
1870
1873 return getNonEmpty(std::move(NewL), std::move(NewU));
1874}
1875
1878 return getEmpty();
1879
1882 return getNonEmpty(std::move(NewL), std::move(NewU));
1883}
1884
1887 return getEmpty();
1888
1891 return getNonEmpty(std::move(NewL), std::move(NewU));
1892}
1893
1896 return getEmpty();
1897
1898
1899
1900
1901
1902
1903
1906 APInt OtherMin = Other.getSignedMin();
1907 APInt OtherMax = Other.getSignedMax();
1908
1910 Max.smul_sat(OtherMin), Max.smul_sat(OtherMax)};
1911 auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); };
1912 return getNonEmpty(std::min(L, Compare), std::max(L, Compare) + 1);
1913}
1914
1917 return getEmpty();
1918
1921 return getNonEmpty(std::move(NewL), std::move(NewU));
1922}
1923
1926 return getEmpty();
1927
1929 APInt ShAmtMin = Other.getUnsignedMin(), ShAmtMax = Other.getUnsignedMax();
1931 APInt NewU = Max.sshl_sat(Max.isNegative() ? ShAmtMin : ShAmtMax) + 1;
1932 return getNonEmpty(std::move(NewL), std::move(NewU));
1933}
1934
1937 return getEmpty();
1939 return getFull();
1941}
1942
1945 return getEmpty();
1946
1949
1952 else
1954
1955
1956 if (IntMinIsPoison)
1958 else
1960 }
1961
1963
1964
1965 if (IntMinIsPoison && SMin.isMinSignedValue()) {
1966
1967 if (SMax.isMinSignedValue())
1968 return getEmpty();
1970 }
1971
1972
1973 if (SMin.isNonNegative())
1975
1976
1977 if (SMax.isNegative())
1979
1980
1983}
1984
1987 return getEmpty();
1988
1990 if (ZeroIsPoison && contains(Zero)) {
1991
1992
1993
1994
1995
1996
1999
2000
2001 return getEmpty();
2002 }
2003
2004
2009
2012 } else {
2014 }
2015 }
2016
2017
2018
2021}
2022
2026 "Unexpected wrapped set.");
2031 if (Lower.isZero())
2034
2035
2036 unsigned LCPLength = (Lower ^ (Upper - 1)).countl_zero();
2037
2038
2042 std::max(BitWidth - LCPLength - 1, Lower.countr_zero()) + 1));
2043}
2044
2047 return getEmpty();
2048
2051 if (ZeroIsPoison && contains(Zero)) {
2052
2053
2054
2055
2056
2057
2058 if (Lower.isZero()) {
2059 if (Upper == 1) {
2060
2061
2062 return getEmpty();
2063 }
2064
2065
2067 } else if (Upper == 1) {
2068
2070 } else {
2075 }
2076 }
2077
2082
2083
2084
2086
2089}
2090
2094 "Unexpected wrapped set.");
2099
2101
2103 unsigned LCPPopCount = Lower.getHiBits(LCPLength).popcount();
2104
2105
2106 unsigned MinBits =
2107 LCPPopCount + (Lower.countr_zero() < BitWidth - LCPLength ? 1 : 0);
2108
2109
2110
2111
2112 unsigned MaxBits = LCPPopCount + (BitWidth - LCPLength) -
2113 (Max.countr_one() < BitWidth - LCPLength ? 1 : 0);
2115}
2116
2119 return getEmpty();
2120
2127
2128
2129
2132
2135}
2136
2141
2143 APInt OtherMin = Other.getUnsignedMin(), OtherMax = Other.getUnsignedMax();
2144
2145
2146 if (Min.ugt(~OtherMin))
2148 if (Max.ugt(~OtherMax))
2151}
2152
2157
2159 APInt OtherMin = Other.getSignedMin(), OtherMax = Other.getSignedMax();
2160
2163
2164
2165
2167 Min.sgt(SignedMax - OtherMin))
2169 if (Max.isNegative() && OtherMax.isNegative() &&
2170 Max.slt(SignedMin - OtherMax))
2172
2173 if (Max.isNonNegative() && OtherMax.isNonNegative() &&
2174 Max.sgt(SignedMax - OtherMax))
2177 Min.slt(SignedMin - OtherMin))
2179
2181}
2182
2187
2189 APInt OtherMin = Other.getUnsignedMin(), OtherMax = Other.getUnsignedMax();
2190
2191
2192 if (Max.ult(OtherMin))
2194 if (Min.ult(OtherMax))
2197}
2198
2203
2205 APInt OtherMin = Other.getSignedMin(), OtherMax = Other.getSignedMax();
2206
2209
2210
2211
2212 if (Min.isNonNegative() && OtherMax.isNegative() &&
2213 Min.sgt(SignedMax + OtherMax))
2215 if (Max.isNegative() && OtherMin.isNonNegative() &&
2216 Max.slt(SignedMin + OtherMin))
2218
2219 if (Max.isNonNegative() && OtherMin.isNegative() &&
2220 Max.sgt(SignedMax + OtherMin))
2222 if (Min.isNegative() && OtherMax.isNonNegative() &&
2223 Min.slt(SignedMin + OtherMax))
2225
2227}
2228
2233
2235 APInt OtherMin = Other.getUnsignedMin(), OtherMax = Other.getUnsignedMax();
2236 bool Overflow;
2237
2238 (void) Min.umul_ov(OtherMin, Overflow);
2239 if (Overflow)
2241
2242 (void) Max.umul_ov(OtherMax, Overflow);
2243 if (Overflow)
2245
2247}
2248
2251 OS << "full-set";
2253 OS << "empty-set";
2254 else
2255 OS << "[" << Lower << "," << Upper << ")";
2256}
2257
2258#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2261}
2262#endif
2263
2265 const unsigned NumRanges = Ranges.getNumOperands() / 2;
2266 assert(NumRanges >= 1 && "Must have at least one range!");
2267 assert(Ranges.getNumOperands() % 2 == 0 && "Must be a sequence of pairs");
2268
2269 auto *FirstLow = mdconst::extract(Ranges.getOperand(0));
2270 auto *FirstHigh = mdconst::extract(Ranges.getOperand(1));
2271
2272 ConstantRange CR(FirstLow->getValue(), FirstHigh->getValue());
2273
2274 for (unsigned i = 1; i < NumRanges; ++i) {
2275 auto *Low = mdconst::extract(Ranges.getOperand(2 * i + 0));
2276 auto *High = mdconst::extract(Ranges.getOperand(2 * i + 1));
2277
2278
2279
2281 }
2282
2283 return CR;
2284}
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static APInt estimateBitMaskedAndLowerBound(const ConstantRange &LHS, const ConstantRange &RHS)
Estimate the 'bit-masked AND' operation's lower bound.
static ConstantRange computeShlNUW(const ConstantRange &LHS, const ConstantRange &RHS)
static ConstantRange getUnsignedPopCountRange(const APInt &Lower, const APInt &Upper)
static ConstantRange computeShlNSW(const ConstantRange &LHS, const ConstantRange &RHS)
static ConstantRange makeExactMulNUWRegion(const APInt &V)
Exact mul nuw region for single element RHS.
static ConstantRange computeShlNSWWithNNegLHS(const APInt &LHSMin, const APInt &LHSMax, unsigned RHSMin, unsigned RHSMax)
static ConstantRange makeExactMulNSWRegion(const APInt &V)
Exact mul nsw region for single element RHS.
static ConstantRange getPreferredRange(const ConstantRange &CR1, const ConstantRange &CR2, ConstantRange::PreferredRangeType Type)
static ConstantRange getUnsignedCountTrailingZerosRange(const APInt &Lower, const APInt &Upper)
static ConstantRange computeShlNSWWithNegLHS(const APInt &LHSMin, const APInt &LHSMax, unsigned RHSMin, unsigned RHSMax)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
APInt umul_ov(const APInt &RHS, bool &Overflow) const
APInt usub_sat(const APInt &RHS) const
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.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
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.
unsigned getActiveBits() const
Compute the number of active bits in the value.
APInt trunc(unsigned width) const
Truncate to new width.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
APInt sshl_ov(const APInt &Amt, bool &Overflow) const
APInt smul_sat(const APInt &RHS) const
unsigned countLeadingOnes() const
APInt sadd_sat(const APInt &RHS) 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.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
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.
bool isMinValue() const
Determine if this is the smallest unsigned value.
static APInt getMinValue(unsigned numBits)
Gets minimum unsigned value of APInt for a specific bit width.
bool isNegative() const
Determine sign of this APInt.
APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
bool sle(const APInt &RHS) const
Signed less or equal comparison.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
APInt sshl_sat(const APInt &RHS) const
APInt ushl_sat(const APInt &RHS) const
APInt ushl_ov(const APInt &Amt, bool &Overflow) const
unsigned countLeadingZeros() const
bool isStrictlyPositive() const
Determine if this APInt Value is positive.
unsigned countl_one() const
Count the number of leading one bits.
void clearLowBits(unsigned loBits)
Set bottom loBits bits to 0.
APInt uadd_sat(const APInt &RHS) const
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
void setAllBits()
Set every bit to 1.
bool getBoolValue() const
Convert APInt to a boolean value.
APInt smul_ov(const APInt &RHS, bool &Overflow) const
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
APInt sext(unsigned width) const
Sign extend to a new width.
APInt shl(unsigned shiftAmt) const
Left-shift function.
APInt umul_sat(const APInt &RHS) const
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
bool slt(const APInt &RHS) const
Signed less than comparison.
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.
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.
void clearSignBit()
Set the sign bit to 0.
APInt ssub_sat(const APInt &RHS) const
bool isMaxValue() const
Determine if this is the largest unsigned value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
bool isIntPredicate() const
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
This class represents a range of values.
ConstantRange multiply(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a multiplication of a value in thi...
ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
bool isUpperSignWrapped() const
Return true if the (exclusive) upper bound wraps around the signed domain.
unsigned getActiveBits() const
Compute the maximal number of active bits needed to represent every value in this range.
ConstantRange zextOrTrunc(uint32_t BitWidth) const
Make this range have the bit width given by BitWidth.
PreferredRangeType
If represented precisely, the result of some range operations may consist of multiple disjoint ranges...
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...
bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const
Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.
ConstantRange umul_sat(const ConstantRange &Other) const
Perform an unsigned saturating multiplication of two constant ranges.
static CmpInst::Predicate getEquivalentPredWithFlippedSignedness(CmpInst::Predicate Pred, const ConstantRange &CR1, const ConstantRange &CR2)
If the comparison between constant ranges this and Other is insensitive to the signedness of the comp...
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.
ConstantRange binaryXor(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
const APInt * getSingleMissingElement() const
If this set contains all but a single element, return it, otherwise return null.
static ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned)
Initialize a range based on a known bits constraint.
const APInt & getLower() const
Return the lower value for this range.
OverflowResult unsignedSubMayOverflow(const ConstantRange &Other) const
Return whether unsigned sub of the two ranges always/never overflows.
bool isAllNegative() const
Return true if all values in this range are negative.
ConstantRange truncate(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly smaller than the current typ...
OverflowResult unsignedAddMayOverflow(const ConstantRange &Other) const
Return whether unsigned add of the two ranges always/never overflows.
ConstantRange urem(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned remainder operation of...
ConstantRange sshl_sat(const ConstantRange &Other) const
Perform a signed saturating left shift of this constant range by a value in Other.
ConstantRange smul_fast(const ConstantRange &Other) const
Return range of possible values for a signed multiplication of this and Other.
ConstantRange lshr(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a logical right shift of a value i...
KnownBits toKnownBits() const
Return known bits for values in this range.
ConstantRange castOp(Instruction::CastOps CastOp, uint32_t BitWidth) const
Return a new range representing the possible values resulting from an application of the specified ca...
ConstantRange umin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned minimum of a value in ...
APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
ConstantRange difference(const ConstantRange &CR) const
Subtract the specified range from this range (aka relative complement of the sets).
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
ConstantRange srem(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed remainder operation of a ...
bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other? NOTE: false does not mean that inverse pr...
ConstantRange sadd_sat(const ConstantRange &Other) const
Perform a signed saturating addition of two constant ranges.
ConstantRange ushl_sat(const ConstantRange &Other) const
Perform an unsigned saturating left shift of this constant range by a value in Other.
static ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
void dump() const
Allow printing from a debugger easily.
bool isEmptySet() const
Return true if this set contains no members.
ConstantRange smul_sat(const ConstantRange &Other) const
Perform a signed saturating multiplication of two constant ranges.
bool isAllPositive() const
Return true if all values in this range are positive.
ConstantRange shl(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a left shift of a value in this ra...
ConstantRange zeroExtend(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly larger than the current type...
bool isSignWrappedSet() const
Return true if this set wraps around the signed domain.
bool isSizeLargerThan(uint64_t MaxSize) const
Compare set size of this range with Value.
APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
ConstantRange abs(bool IntMinIsPoison=false) const
Calculate absolute value range.
static bool isIntrinsicSupported(Intrinsic::ID IntrinsicID)
Returns true if ConstantRange calculations are supported for intrinsic with IntrinsicID.
static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the largest range such that all values in the returned range satisfy the given predicate with...
bool isWrappedSet() const
Return true if this set wraps around the unsigned domain.
ConstantRange usub_sat(const ConstantRange &Other) const
Perform an unsigned saturating subtraction of two constant ranges.
ConstantRange uadd_sat(const ConstantRange &Other) const
Perform an unsigned saturating addition of two constant ranges.
ConstantRange overflowingBinaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind) const
Return a new range representing the possible values resulting from an application of the specified ov...
void print(raw_ostream &OS) const
Print out the bounds to a stream.
ConstantRange(uint32_t BitWidth, bool isFullSet)
Initialize a full or empty set for the specified bit width.
OverflowResult unsignedMulMayOverflow(const ConstantRange &Other) const
Return whether unsigned mul of the two ranges always/never overflows.
ConstantRange subWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, PreferredRangeType RangeType=Smallest) const
Return a new range representing the possible values resulting from an subtraction with wrap type NoWr...
bool isSingleElement() const
Return true if this set contains exactly one member.
ConstantRange ssub_sat(const ConstantRange &Other) const
Perform a signed saturating subtraction of two constant ranges.
bool isAllNonNegative() const
Return true if all values in this range are non-negative.
ConstantRange umax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned maximum of a value in ...
ConstantRange signExtend(uint32_t BitWidth) const
Return a new range in the specified integer type, which must be strictly larger than the current type...
static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
ConstantRange sdiv(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed division of a value in th...
const APInt & getUpper() const
Return the upper value for this range.
bool isUpperWrapped() const
Return true if the exclusive upper bound wraps around the unsigned domain.
ConstantRange shlWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, PreferredRangeType RangeType=Smallest) const
Return a new range representing the possible values resulting from a left shift with wrap type NoWrap...
ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
static 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...
ConstantRange inverse() const
Return a new range that is the logical not of the current set.
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...
ConstantRange ashr(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a arithmetic right shift of a valu...
ConstantRange binaryAnd(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a binary-and of a value in this ra...
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static bool areInsensitiveToSignednessOfInvertedICmpPredicate(const ConstantRange &CR1, const ConstantRange &CR2)
Return true iff CR1 ult CR2 is equivalent to CR1 sge CR2.
OverflowResult signedAddMayOverflow(const ConstantRange &Other) const
Return whether signed add of the two ranges always/never overflows.
APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
ConstantRange addWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, PreferredRangeType RangeType=Smallest) const
Return a new range representing the possible values resulting from an addition with wrap type NoWrapK...
ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
OverflowResult
Represents whether an operation on the given constant range is known to always or never overflow.
@ 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.
static ConstantRange makeMaskNotEqualRange(const APInt &Mask, const APInt &C)
Initialize a range containing all values X that satisfy (X & Mask) != C.
static bool areInsensitiveToSignednessOfICmpPredicate(const ConstantRange &CR1, const ConstantRange &CR2)
Return true iff CR1 ult CR2 is equivalent to CR1 slt CR2.
ConstantRange cttz(bool ZeroIsPoison=false) const
Calculate cttz range.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
ConstantRange ctpop() const
Calculate ctpop range.
static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind)
Produce the largest range containing all X such that "X BinOp Y" is guaranteed not to wrap (overflow)...
ConstantRange smin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed minimum of a value in thi...
ConstantRange udiv(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned division of a value in...
unsigned getMinSignedBits() const
Compute the maximal number of bits needed to represent every value in this signed range.
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
ConstantRange binaryNot() const
Return a new range representing the possible values resulting from a binary-xor of a value in this ra...
ConstantRange smax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed maximum of a value in thi...
ConstantRange binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const
Return a new range representing the possible values resulting from an application of the specified bi...
ConstantRange binaryOr(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a binary-or of a value in this ran...
OverflowResult signedSubMayOverflow(const ConstantRange &Other) const
Return whether signed sub of the two ranges always/never overflows.
ConstantRange ctlz(bool ZeroIsPoison=false) const
Calculate ctlz range.
ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
ConstantRange sextOrTrunc(uint32_t BitWidth) const
Make this range have the bit width given by BitWidth.
static 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.
bool isSizeStrictlySmallerThan(const ConstantRange &CR) const
Compare set size of this range with the range CR.
ConstantRange multiplyWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, PreferredRangeType RangeType=Smallest) const
Return a new range representing the possible values resulting from a multiplication with wrap type No...
Predicate getFlippedSignednessPredicate() const
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
Utility class for integer operators which may exhibit overflow - Add, Sub, Mul, and Shl.
The instances of the Type class are immutable: once they are created, they are never changed.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::optional< unsigned > GetMostSignificantDifferentBit(const APInt &A, const APInt &B)
Compare two values, and if they are different, return the position of the most significant bit that i...
APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A sign-divided by B, rounded by the given rounding mode.
const APInt & smin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be signed.
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
const APInt & umax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be unsigned.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
constexpr unsigned BitWidth
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
bool isUnknown() const
Returns true if we don't know any bits.
bool hasConflict() const
Returns true if there is conflicting information.
unsigned getBitWidth() const
Get the bit width of this value.
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 isNegative() const
Returns true if this value is known to be negative.