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

401 if ((Mask & C) != C)

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 (Other.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.