LLVM: lib/Transforms/InstCombine/InstCombineCompares.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

34#include

35

36using namespace llvm;

38

39#define DEBUG_TYPE "instcombine"

40

41

42STATISTIC(NumSel, "Number of select opts");

43

44

45

47 bool IsSigned = false) {

48 bool Overflow;

49 if (IsSigned)

50 Result = In1.sadd_ov(In2, Overflow);

51 else

52 Result = In1.uadd_ov(In2, Overflow);

53

54 return Overflow;

55}

56

57

58

60 bool IsSigned = false) {

61 bool Overflow;

62 if (IsSigned)

63 Result = In1.ssub_ov(In2, Overflow);

64 else

65 Result = In1.usub_ov(In2, Overflow);

66

67 return Overflow;

68}

69

70

71

73 for (auto *U : I.users())

75 return true;

76 return false;

77}

78

79

80

81

82

85 return false;

86

87 if (C.isZero())

89

90 if (C.isOne()) {

93 return true;

94 }

95 } else if (C.isAllOnes()) {

98 return true;

99 }

100 }

101

102 return false;

103}

104

105

106

107

108

109

110

111

112

116 if (LI->isVolatile() || !GV || !GV->isConstant() ||

117 !GV->hasDefinitiveInitializer())

118 return nullptr;

119

121 TypeSize EltSize = DL.getTypeStoreSize(EltTy);

123 return nullptr;

124

127 return nullptr;

128

130 TypeSize GlobalSize = DL.getTypeAllocSize(Init->getType());

131

135

136

137 if (!ConstOffset.ult(Stride))

138 return nullptr;

139

140

142 return nullptr;

143

144

149 return nullptr;

150

151 enum { Overdefined = -3, Undefined = -2 };

152

153

154

155

156

157

158

159

160 int FirstTrueElement = Undefined, SecondTrueElement = Undefined;

161

162

163

164 int FirstFalseElement = Undefined, SecondFalseElement = Undefined;

165

166

167

168

169

170

171

172 int TrueRangeEnd = Undefined, FalseRangeEnd = Undefined;

173

174

175

176

178

179

182 for (unsigned i = 0, e = ArrayElementCount; i != e; ++i, Offset += Stride) {

184 if (!Elt)

185 return nullptr;

186

187

188 if (AndCst) {

190 if (!Elt)

191 return nullptr;

192 }

193

194

196 CompareRHS, DL, &TLI);

197 if (C)

198 return nullptr;

199

200

202

203

204 if (TrueRangeEnd == (int)i - 1)

205 TrueRangeEnd = i;

206 if (FalseRangeEnd == (int)i - 1)

207 FalseRangeEnd = i;

208 continue;

209 }

210

211

212

214 return nullptr;

215

216

217

219

220

221 if (IsTrueForElt) {

222

223 if (FirstTrueElement == Undefined)

224 FirstTrueElement = TrueRangeEnd = i;

225 else {

226

227 if (SecondTrueElement == Undefined)

228 SecondTrueElement = i;

229 else

230 SecondTrueElement = Overdefined;

231

232

233 if (TrueRangeEnd == (int)i - 1)

234 TrueRangeEnd = i;

235 else

236 TrueRangeEnd = Overdefined;

237 }

238 } else {

239

240 if (FirstFalseElement == Undefined)

241 FirstFalseElement = FalseRangeEnd = i;

242 else {

243

244 if (SecondFalseElement == Undefined)

245 SecondFalseElement = i;

246 else

247 SecondFalseElement = Overdefined;

248

249

250 if (FalseRangeEnd == (int)i - 1)

251 FalseRangeEnd = i;

252 else

253 FalseRangeEnd = Overdefined;

254 }

255 }

256

257

258 if (i < 64 && IsTrueForElt)

259 MagicBitvector |= 1ULL << i;

260

261

262

263

264 if ((i & 8) == 0 && i >= 64 && SecondTrueElement == Overdefined &&

265 SecondFalseElement == Overdefined && TrueRangeEnd == Overdefined &&

266 FalseRangeEnd == Overdefined)

267 return nullptr;

268 }

269

270

271

272

273

274

275

276

277

278

279

280 auto MaskIdx = [&](Value *Idx) {

284 Idx = Builder.CreateAnd(Idx, Mask);

285 }

286 return Idx;

287 };

288

289

290

291 if (SecondTrueElement != Overdefined) {

292 Idx = MaskIdx(Idx);

293

294 if (FirstTrueElement == Undefined)

296

297 Value *FirstTrueIdx = ConstantInt::get(Idx->getType(), FirstTrueElement);

298

299

300 if (SecondTrueElement == Undefined)

302

303

304 Value *C1 = Builder.CreateICmpEQ(Idx, FirstTrueIdx);

305 Value *SecondTrueIdx = ConstantInt::get(Idx->getType(), SecondTrueElement);

306 Value *C2 = Builder.CreateICmpEQ(Idx, SecondTrueIdx);

307 return BinaryOperator::CreateOr(C1, C2);

308 }

309

310

311

312 if (SecondFalseElement != Overdefined) {

313 Idx = MaskIdx(Idx);

314

315 if (FirstFalseElement == Undefined)

317

318 Value *FirstFalseIdx = ConstantInt::get(Idx->getType(), FirstFalseElement);

319

320

321 if (SecondFalseElement == Undefined)

323

324

325 Value *C1 = Builder.CreateICmpNE(Idx, FirstFalseIdx);

326 Value *SecondFalseIdx =

327 ConstantInt::get(Idx->getType(), SecondFalseElement);

328 Value *C2 = Builder.CreateICmpNE(Idx, SecondFalseIdx);

329 return BinaryOperator::CreateAnd(C1, C2);

330 }

331

332

333

334 if (TrueRangeEnd != Overdefined) {

335 assert(TrueRangeEnd != FirstTrueElement && "Should emit single compare");

336 Idx = MaskIdx(Idx);

337

338

339 if (FirstTrueElement) {

340 Value *Offs = ConstantInt::get(Idx->getType(), -FirstTrueElement);

341 Idx = Builder.CreateAdd(Idx, Offs);

342 }

343

345 ConstantInt::get(Idx->getType(), TrueRangeEnd - FirstTrueElement + 1);

347 }

348

349

350 if (FalseRangeEnd != Overdefined) {

351 assert(FalseRangeEnd != FirstFalseElement && "Should emit single compare");

352 Idx = MaskIdx(Idx);

353

354 if (FirstFalseElement) {

355 Value *Offs = ConstantInt::get(Idx->getType(), -FirstFalseElement);

356 Idx = Builder.CreateAdd(Idx, Offs);

357 }

358

360 ConstantInt::get(Idx->getType(), FalseRangeEnd - FirstFalseElement);

362 }

363

364

365

366

367 {

368 Type *Ty = nullptr;

369

370

371

372

373 if (ArrayElementCount <= Idx->getType()->getIntegerBitWidth())

375 else

376 Ty = DL.getSmallestLegalIntType(Init->getContext(), ArrayElementCount);

377

378 if (Ty) {

379 Idx = MaskIdx(Idx);

380 Value *V = Builder.CreateIntCast(Idx, Ty, false);

381 V = Builder.CreateLShr(ConstantInt::get(Ty, MagicBitvector), V);

382 V = Builder.CreateAnd(ConstantInt::get(Ty, 1), V);

384 }

385 }

386

387 return nullptr;

388}

389

390

391

392

398

399

400

401

402

403

404

405

406

407 while (!WorkList.empty()) {

409

410 while (!WorkList.empty()) {

411 if (Explored.size() >= 100)

412 return false;

413

415

418 continue;

419 }

420

422

423

424 return false;

425

427

429 if (GEP->isInBounds() || count_if(GEP->indices(), IsNonConst) > 1)

430 return false;

431

433 if (!Explored.contains(GEP->getOperand(0)))

435 }

436

437 if (WorkList.back() == V) {

439

441 }

442

444

446 return false;

449 }

450 }

451

452

453 for (auto *PN : PHIs)

454 for (Value *Op : PN->incoming_values())

457 }

458

459

460

461

462 for (Value *Val : Explored) {

464

467

468 if (Inst == Base || Inst == PHI || !Inst || PHI ||

470 continue;

471

472 if (PHI->getParent() == Inst->getParent())

473 return false;

474 }

475 }

476 return true;

477}

478

479

480

482 bool Before = true) {

486 return;

487 }

489 if (!Before)

490 I = &*std::next(I->getIterator());

491 Builder.SetInsertPoint(I);

492 return;

493 }

495

496 BasicBlock &Entry = A->getParent()->getEntryBlock();

497 Builder.SetInsertPoint(&Entry, Entry.getFirstInsertionPt());

498 return;

499 }

500

501

502 assert(isa(V) && "Setting insertion point for unknown value!");

503}

504

505

506

511

512

513

514

515

516

517

519 Base->getContext(), DL.getIndexTypeSizeInBits(Start->getType()));

520

523

524

525 for (Value *Val : Explored) {

526 if (Val == Base)

527 continue;

528

529

531 NewInsts[PHI] =

533 PHI->getName() + ".idx", PHI->getIterator());

534 }

536

537

538 for (Value *Val : Explored) {

540 continue;

541

544 Value *Op = NewInsts[GEP->getOperand(0)];

547 NewInsts[GEP] = OffsetV;

548 else

549 NewInsts[GEP] = Builder.CreateAdd(

550 Op, OffsetV, GEP->getOperand(0)->getName() + ".add",

553 continue;

554 }

556 continue;

557

559 }

560

561

562 for (Value *Val : Explored) {

563 if (Val == Base)

564 continue;

565

566

569 for (unsigned I = 0, E = PHI->getNumIncomingValues(); I < E; ++I) {

570 Value *NewIncoming = PHI->getIncomingValue(I);

571

572 auto It = NewInsts.find(NewIncoming);

573 if (It != NewInsts.end())

574 NewIncoming = It->second;

575

576 NewPhi->addIncoming(NewIncoming, PHI->getIncomingBlock(I));

577 }

578 }

579 }

580

581 for (Value *Val : Explored) {

582 if (Val == Base)

583 continue;

584

586

587 Value *NewVal = Builder.CreateGEP(Builder.getInt8Ty(), Base, NewInsts[Val],

588 Val->getName() + ".ptr", NW);

590

591

593 }

594

595 return NewInsts[Start];

596}

597

598

599

600

605

607 return nullptr;

608

610 return nullptr;

611

615 false);

616

617

619 return nullptr;

620

621

625 return nullptr;

626

627

628

629

630

631

632

634

635

636

637

638

641}

642

643

644

647

648

649

650

651

653 return nullptr;

654

655

656

659

662 return true;

663

664

667 };

668

671

673 }

674

677 return I;

678 };

679

681 if (Base.Ptr == RHS && CanFold(Base.LHSNW) && Base.isExpensive()) {

682

683 Type *IdxTy = DL.getIndexType(GEPLHS->getType());

685 EmitGEPOffsets(Base.LHSGEPs, Base.LHSNW, IdxTy, true);

688 }

689

693 RHS->getType()->getPointerAddressSpace())) {

694

695

696

697

698

699

700

701

702

703

704

705

706

707

708

709

710

715 }

721

722

723

724 if (GEPLHS->getOperand(0) != GEPRHS->getOperand(0)) {

725 bool IndicesTheSame =

726 GEPLHS->getNumOperands() == GEPRHS->getNumOperands() &&

728 GEPRHS->getPointerOperand()->getType() &&

730 if (IndicesTheSame)

731 for (unsigned i = 1, e = GEPLHS->getNumOperands(); i != e; ++i)

732 if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) {

733 IndicesTheSame = false;

734 break;

735 }

736

737

739 if (IndicesTheSame &&

742

743

744

745

746

747 if (GEPLHS->isInBounds() && GEPRHS->isInBounds() &&

749 (GEPRHS->hasAllConstantIndices() || GEPRHS->hasOneUse()) &&

753 Value *LOffset = EmitGEPOffset(GEPLHS);

754 Value *ROffset = EmitGEPOffset(GEPRHS);

755

756

757

758

761 if (LHSIndexTy != RHSIndexTy) {

764 ROffset = Builder.CreateTrunc(ROffset, LHSIndexTy);

765 } else

766 LOffset = Builder.CreateTrunc(LOffset, RHSIndexTy);

767 }

768

770 LOffset, ROffset);

772 }

773 }

774

775 if (GEPLHS->getOperand(0) == GEPRHS->getOperand(0) &&

776 GEPLHS->getNumOperands() == GEPRHS->getNumOperands() &&

778

779 unsigned NumDifferences = 0;

780 unsigned DiffOperand = 0;

781 for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)

782 if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) {

784 Type *RHSType = GEPRHS->getOperand(i)->getType();

785

790

791 NumDifferences = 2;

792 break;

793 }

794

795 if (NumDifferences++)

796 break;

797 DiffOperand = i;

798 }

799

800 if (NumDifferences == 0)

802 I,

804

805

808 Value *RHSV = GEPRHS->getOperand(DiffOperand);

809 return NewICmp(NW, LHSV, RHSV);

810 }

811 }

812

813 if (Base.Ptr && CanFold(Base.LHSNW & Base.RHSNW) && Base.isExpensive()) {

814

815 Type *IdxTy = DL.getIndexType(GEPLHS->getType());

817 EmitGEPOffsets(Base.LHSGEPs, Base.LHSNW, IdxTy, true);

819 EmitGEPOffsets(Base.RHSGEPs, Base.RHSNW, IdxTy, true);

820 return NewICmp(Base.LHSNW & Base.RHSNW, L, R);

821 }

822 }

823

824

825

827}

828

830

831

832

833

834

835

836

837

838

839

840

841

842

843

846 bool Captured = false;

847

848

850

851 CmpCaptureTracker(AllocaInst *Alloca) : Alloca(Alloca) {}

852

853 void tooManyUses() override { Captured = true; }

854

856

858

859

860

861

863

864

865 ICmps[ICmp] |= 1u << U->getOperandNo();

867 }

868

869 Captured = true;

870 return Stop;

871 }

872 };

873

874 CmpCaptureTracker Tracker(Alloca);

876 if (Tracker.Captured)

877 return false;

878

880 for (auto [ICmp, Operands] : Tracker.ICmps) {

881 switch (Operands) {

882 case 1:

883 case 2: {

884

885

886 auto *Res = ConstantInt::get(ICmp->getType(),

891 break;

892 }

893 case 3:

894

895

896

897 break;

898 default:

900 }

901 }

902

904}

905

906

909

910

911

912 assert(!C && "C should not be zero!");

913

914

915

916

921 }

922

923

924

925

928 ConstantInt::get(X->getType(), -C));

929

931

932

933

934

935

936

937

940 ConstantInt::get(X->getType(), SMax - C));

941

942

943

944

945

946

947

948

951 ConstantInt::get(X->getType(), SMax - (C - 1)));

952}

953

954

955

956

958 const APInt &AP1,

959 const APInt &AP2) {

960 assert(I.isEquality() && "Cannot fold icmp gt/lt");

961

963 if (I.getPredicate() == I.ICMP_NE)

965 return new ICmpInst(Pred, LHS, RHS);

966 };

967

968

970 return nullptr;

971

973 if (IsAShr) {

975 return nullptr;

977 return nullptr;

978 if (AP2.sgt(AP1))

979 return nullptr;

980 }

981

982 if (!AP1)

983

984 return getICmp(I.ICMP_UGT, A,

985 ConstantInt::get(A->getType(), AP2.logBase2()));

986

987 if (AP1 == AP2)

989

990 int Shift;

993 else

995

996 if (Shift > 0) {

997 if (IsAShr && AP1 == AP2.ashr(Shift)) {

998

999

1001 return getICmp(I.ICMP_UGE, A, ConstantInt::get(A->getType(), Shift));

1002 return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));

1003 } else if (AP1 == AP2.lshr(Shift)) {

1004 return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));

1005 }

1006 }

1007

1008

1009

1010 auto *TorF = ConstantInt::get(I.getType(), I.getPredicate() == I.ICMP_NE);

1012}

1013

1014

1015

1017 const APInt &AP1,

1018 const APInt &AP2) {

1019 assert(I.isEquality() && "Cannot fold icmp gt/lt");

1020

1022 if (I.getPredicate() == I.ICMP_NE)

1024 return new ICmpInst(Pred, LHS, RHS);

1025 };

1026

1027

1029 return nullptr;

1030

1031 unsigned AP2TrailingZeros = AP2.countr_zero();

1032

1033 if (!AP1 && AP2TrailingZeros != 0)

1034 return getICmp(

1035 I.ICMP_UGE, A,

1036 ConstantInt::get(A->getType(), AP2.getBitWidth() - AP2TrailingZeros));

1037

1038 if (AP1 == AP2)

1040

1041

1042 int Shift = AP1.countr_zero() - AP2TrailingZeros;

1043

1044 if (Shift > 0 && AP2.shl(Shift) == AP1)

1045 return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));

1046

1047

1048

1049 auto *TorF = ConstantInt::get(I.getType(), I.getPredicate() == I.ICMP_NE);

1051}

1052

1053

1054

1055

1056

1057

1058

1059

1063

1064

1065

1066

1067

1068

1069

1072 return nullptr;

1073

1074

1076 return nullptr;

1078 if (NewWidth != 7 && NewWidth != 15 && NewWidth != 31)

1079 return nullptr;

1080

1081

1082 ++NewWidth;

1083

1084

1087 return nullptr;

1088

1089

1090

1091

1094 return nullptr;

1095

1096

1097

1098

1099

1101 for (User *U : OrigAdd->users()) {

1102 if (U == AddWithCst)

1103 continue;

1104

1105

1106

1107

1108

1109

1112 return nullptr;

1113 }

1114

1115

1116

1117

1120 I.getModule(), Intrinsic::sadd_with_overflow, NewType);

1121

1123

1124

1125

1127

1128 Value *TruncA = Builder.CreateTrunc(A, NewType, A->getName() + ".trunc");

1129 Value *TruncB = Builder.CreateTrunc(B, NewType, B->getName() + ".trunc");

1130 CallInst *Call = Builder.CreateCall(F, {TruncA, TruncB}, "sadd");

1131 Value *Add = Builder.CreateExtractValue(Call, 0, "sadd.result");

1132 Value *ZExt = Builder.CreateZExt(Add, OrigAdd->getType());

1133

1134

1135

1138

1139

1141}

1142

1143

1144

1145

1146

1148

1149 if (I.isEquality())

1150 return nullptr;

1155 return nullptr;

1157 return nullptr;

1158

1162}

1163

1164

1165

1170 return nullptr;

1171

1174

1177 XTy = X->getType();

1180 APInt(XBitWidth, XBitWidth - 1))))

1181 return nullptr;

1185 true))) {

1186 XTy = X->getType();

1187 } else

1188 return nullptr;

1189

1194}

1195

1196

1199 if (match(Cmp.getOperand(1), m_Zero()))

1200 return nullptr;

1201

1202

1207 return new ICmpInst(Pred, B, Cmp.getOperand(1));

1209 return new ICmpInst(Pred, A, Cmp.getOperand(1));

1210 }

1211 }

1212

1214 return New;

1215

1216

1217

1218

1219

1226 return new ICmpInst(Pred, X, Cmp.getOperand(1));

1227 }

1228

1229

1230

1233

1235

1236

1238 return new ICmpInst(Pred, Y, Cmp.getOperand(1));

1239

1241

1242

1244 return new ICmpInst(Pred, X, Cmp.getOperand(1));

1245

1247 if (BO0->hasNoUnsignedWrap() || BO0->hasNoSignedWrap()) {

1249

1250

1251

1252

1253

1255 return new ICmpInst(Pred, Y, Cmp.getOperand(1));

1256

1257

1258

1260 return new ICmpInst(Pred, X, Cmp.getOperand(1));

1261 }

1262

1263

1264

1265

1266

1267

1268

1269

1270 }

1271

1272

1273

1276 return new ICmpInst(Pred, Stripped,

1278

1279 return nullptr;

1280}

1281

1282

1283

1284

1285

1289 const APInt *Mask, *Neg;

1290

1291 if (match(&Cmp,

1296 return nullptr;

1297

1298 if (*Neg != ~*Mask)

1299 return nullptr;

1300

1302 return nullptr;

1303

1304

1305 auto *NewAnd = Builder.CreateAnd(Num, *Mask);

1307

1308 return new ICmpInst(Pred, NewAnd, Zero);

1309}

1310

1311

1312

1313

1314

1315

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326

1327

1329 Value *Op0 = Cmp.getOperand(0), *Op1 = Cmp.getOperand(1);

1331 ConstantInt *CI, *CI2;

1335 return Res;

1336

1337

1339 if (C)

1340 return nullptr;

1341

1345 for (Value *V : Phi->incoming_values()) {

1348 if (!Res)

1349 return nullptr;

1350 Ops.push_back(Res);

1351 }

1352 Builder.SetInsertPoint(Phi);

1353 PHINode *NewPhi = Builder.CreatePHI(Cmp.getType(), Phi->getNumOperands());

1354 for (auto [V, Pred] : zip(Ops, Phi->blocks()))

1357 }

1358

1360 return R;

1361

1362 return nullptr;

1363}

1364

1365

1367

1368

1369 Value *X = Cmp.getOperand(0), *Y = Cmp.getOperand(1);

1372 return nullptr;

1373

1376

1379

1380

1381

1382

1383

1384

1385

1394

1395

1396

1397

1398

1399

1400 bool UnusedBit;

1402 if (Cmp.isEquality() || (IsSignBit && hasBranchUse(Cmp)))

1403 return nullptr;

1404

1405

1406

1407 if (Cmp.hasOneUse() &&

1409 return nullptr;

1410

1415 return nullptr;

1416 };

1417

1420 const APInt *DomC;

1421 if (match(BI->getCondition(),

1423 continue;

1424

1425 BasicBlockEdge Edge0(BI->getParent(), BI->getSuccessor(0));

1426 if (DT.dominates(Edge0, Cmp.getParent())) {

1427 if (auto *V = handleDomCond(DomPred, DomC))

1428 return V;

1429 } else {

1430 BasicBlockEdge Edge1(BI->getParent(), BI->getSuccessor(1));

1431 if (DT.dominates(Edge1, Cmp.getParent()))

1432 if (auto *V =

1434 return V;

1435 }

1436 }

1437

1438 return nullptr;

1439}

1440

1441

1447 Type *SrcTy = X->getType();

1449 SrcBits = SrcTy->getScalarSizeInBits();

1450

1451

1452

1453 if (shouldChangeType(Trunc->getType(), SrcTy)) {

1455 return new ICmpInst(Pred, X, ConstantInt::get(SrcTy, C.sext(SrcBits)));

1457 return new ICmpInst(Pred, X, ConstantInt::get(SrcTy, C.zext(SrcBits)));

1458 }

1459

1460 if (C.isOne() && C.getBitWidth() > 1) {

1461

1462 Value *V = nullptr;

1465 ConstantInt::get(V->getType(), 1));

1466 }

1467

1468

1470 const APInt *Pow2;

1472 DstBits > Pow2->logBase2()) {

1473

1474

1475

1476 if (C.isZero()) {

1477 auto NewPred = (Pred == Cmp.ICMP_EQ) ? Cmp.ICMP_UGE : Cmp.ICMP_ULT;

1479 ConstantInt::get(SrcTy, DstBits - Pow2->logBase2()));

1480 }

1481

1482

1483 if (C.isPowerOf2())

1485 Pred, Y, ConstantInt::get(SrcTy, C.logBase2() - Pow2->logBase2()));

1486 }

1487

1489

1490

1491 if (!SrcTy->isVectorTy() && shouldChangeType(DstBits, SrcBits)) {

1495 Constant *WideC = ConstantInt::get(SrcTy, C.zext(SrcBits));

1497 }

1498

1499

1500

1502

1503

1504 if ((Known.Zero | Known.One).countl_one() >= SrcBits - DstBits) {

1505

1506 APInt NewRHS = C.zext(SrcBits);

1508 return new ICmpInst(Pred, X, ConstantInt::get(SrcTy, NewRHS));

1509 }

1510 }

1511

1512

1513

1514

1517 bool TrueIfSigned;

1520 DstBits == SrcBits - ShAmt) {

1525 }

1526

1527 return nullptr;

1528}

1529

1530

1531

1537 bool YIsSExt = false;

1538

1540 unsigned NoWrapFlags = cast(Cmp.getOperand(0))->getNoWrapKind() &

1542 if (Cmp.isSigned()) {

1543

1545 return nullptr;

1546 } else {

1547

1548

1549 if (!NoWrapFlags)

1550 return nullptr;

1551 }

1552

1553 if (X->getType() != Y->getType() &&

1554 (!Cmp.getOperand(0)->hasOneUse() || !Cmp.getOperand(1)->hasOneUse()))

1555 return nullptr;

1556 if (!isDesirableIntType(X->getType()->getScalarSizeInBits()) &&

1557 isDesirableIntType(Y->getType()->getScalarSizeInBits())) {

1559 Pred = Cmp.getSwappedPredicate(Pred);

1560 }

1562 }

1563

1564 else if (!Cmp.isSigned() &&

1567

1568 }

1569

1572

1573 YIsSExt =

1575 } else

1576 return nullptr;

1577

1578 Type *TruncTy = Cmp.getOperand(0)->getType();

1580

1581

1582

1583 if (isDesirableIntType(TruncBits) &&

1584 !isDesirableIntType(X->getType()->getScalarSizeInBits()))

1585 return nullptr;

1586

1587 Value *NewY = Builder.CreateIntCast(Y, X->getType(), YIsSExt);

1588 return new ICmpInst(Pred, X, NewY);

1589}

1590

1591

1596 return I;

1597

1600 const APInt *XorC;

1602 return nullptr;

1603

1604

1605

1607 bool TrueIfSigned = false;

1608 if (isSignBitCheck(Cmp.getPredicate(), C, TrueIfSigned)) {

1609

1610

1611

1614

1615

1616 if (TrueIfSigned)

1619 else

1622 }

1623

1624 if (Xor->hasOneUse()) {

1625

1626 if (!Cmp.isEquality() && XorC->isSignMask()) {

1627 Pred = Cmp.getFlippedSignednessPredicate();

1628 return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), C ^ *XorC));

1629 }

1630

1631

1633 Pred = Cmp.getFlippedSignednessPredicate();

1634 Pred = Cmp.getSwappedPredicate(Pred);

1635 return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), C ^ *XorC));

1636 }

1637 }

1638

1639

1641

1642 if (*XorC == ~C && (C + 1).isPowerOf2())

1644

1645 if (*XorC == C && (C + 1).isPowerOf2())

1647 }

1649

1650 if (*XorC == -C && C.isPowerOf2())

1652 ConstantInt::get(X->getType(), ~C));

1653

1654 if (*XorC == C && (-C).isPowerOf2())

1656 ConstantInt::get(X->getType(), ~C));

1657 }

1658 return nullptr;

1659}

1660

1661

1662

1663

1670 PowerOf2 = C;

1672 PowerOf2 = C + 1;

1673 else

1674 return nullptr;

1676 return nullptr;

1678 const APInt *ShiftC;

1681 return nullptr;

1683 Type *XType = X->getType();

1685 return nullptr;

1686 Value *Add = Builder.CreateAdd(X, ConstantInt::get(XType, PowerOf2));

1689 return new ICmpInst(Pred, Add, ConstantInt::get(XType, Bound));

1690}

1691

1692

1695 const APInt &C1,

1696 const APInt &C2) {

1698 if (!Shift || !Shift->isShift())

1699 return nullptr;

1700

1701

1702

1703

1704

1705

1706 unsigned ShiftOpcode = Shift->getOpcode();

1707 bool IsShl = ShiftOpcode == Instruction::Shl;

1708 const APInt *C3;

1710 APInt NewAndCst, NewCmpCst;

1711 bool AnyCmpCstBitsShiftedOut;

1712 if (ShiftOpcode == Instruction::Shl) {

1713

1714

1715

1716

1718 return nullptr;

1719

1720 NewCmpCst = C1.lshr(*C3);

1721 NewAndCst = C2.lshr(*C3);

1722 AnyCmpCstBitsShiftedOut = NewCmpCst.shl(*C3) != C1;

1723 } else if (ShiftOpcode == Instruction::LShr) {

1724

1725

1726

1727

1728 NewCmpCst = C1.shl(*C3);

1729 NewAndCst = C2.shl(*C3);

1730 AnyCmpCstBitsShiftedOut = NewCmpCst.lshr(*C3) != C1;

1732 return nullptr;

1733 } else {

1734

1735

1736 assert(ShiftOpcode == Instruction::AShr && "Unknown shift opcode");

1737 NewCmpCst = C1.shl(*C3);

1738 NewAndCst = C2.shl(*C3);

1739 AnyCmpCstBitsShiftedOut = NewCmpCst.ashr(*C3) != C1;

1740 if (NewAndCst.ashr(*C3) != C2)

1741 return nullptr;

1742 }

1743

1744 if (AnyCmpCstBitsShiftedOut) {

1745

1746

1747

1752 } else {

1754 Shift->getOperand(0), ConstantInt::get(And->getType(), NewAndCst));

1755 return new ICmpInst(Cmp.getPredicate(), NewAnd,

1756 ConstantInt::get(And->getType(), NewCmpCst));

1757 }

1758 }

1759

1760

1761

1762

1763 if (Shift->hasOneUse() && C1.isZero() && Cmp.isEquality() &&

1766

1767 Value *NewShift =

1770

1771

1773 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));

1774 }

1775

1776 return nullptr;

1777}

1778

1779

1782 const APInt &C1) {

1784

1785

1786

1787

1788 if (isICMP_NE && Cmp.getType()->isVectorTy() && C1.isZero() &&

1790 return new TruncInst(And->getOperand(0), Cmp.getType());

1791

1792 const APInt *C2;

1795 return nullptr;

1796

1797

1801 ConstantInt::get(X->getType(), ~*C2));

1802

1806 ConstantInt::get(X->getType(), -*C2));

1807

1808

1809 if (And->hasOneUse())

1810 return nullptr;

1811

1812 if (Cmp.isEquality() && C1.isZero()) {

1813

1814

1818 return new ICmpInst(NewPred, X, Zero);

1819 }

1820

1821 APInt NewC2 = *C2;

1823

1826

1827

1828

1830 Constant *NegBOC = ConstantInt::get(And->getType(), -NewC2);

1832 return new ICmpInst(NewPred, X, NegBOC);

1833 }

1834 }

1835

1836

1837

1838

1839

1840

1841

1842

1843

1847

1848

1849

1850 if (!Cmp.getType()->isVectorTy()) {

1851 Type *WideType = W->getType();

1853 Constant *ZextC1 = ConstantInt::get(WideType, C1.zext(WideScalarBits));

1854 Constant *ZextC2 = ConstantInt::get(WideType, C2->zext(WideScalarBits));

1855 Value *NewAnd = Builder.CreateAnd(W, ZextC2, And->getName());

1856 return new ICmpInst(Cmp.getPredicate(), NewAnd, ZextC1);

1857 }

1858 }

1859

1861 return I;

1862

1863

1864

1865

1866

1867 if (!Cmp.isSigned() && C1.isZero() && And->getOperand(0)->hasOneUse() &&

1874 unsigned UsesRemoved = 0;

1875 if (And->hasOneUse())

1876 ++UsesRemoved;

1877 if (Or->hasOneUse())

1878 ++UsesRemoved;

1880 ++UsesRemoved;

1881

1882

1884 if (UsesRemoved >= RequireUsesRemoved) {

1887 true),

1888 One, Or->getName());

1889 Value *NewAnd = Builder.CreateAnd(A, NewOr, And->getName());

1890 return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));

1891 }

1892 }

1893 }

1894

1895

1896

1897

1898

1899

1900

1901

1902

1904 if (!Cmp.getParent()->getParent()->hasFnAttribute(

1905 Attribute::NoImplicitFloat) &&

1906 Cmp.isEquality() &&

1908 Type *FPType = V->getType()->getScalarType();

1909 if (FPType->isIEEELikeFPTy() && (C1.isZero() || C1 == *C2)) {

1910 APInt ExponentMask =

1912 if (*C2 == ExponentMask) {

1913 unsigned Mask = C1.isZero()

1916 if (isICMP_NE)

1919 }

1920 }

1921 }

1922

1923 return nullptr;

1924}

1925

1926

1931 return I;

1932

1934 bool TrueIfNeg;

1936

1937

1943 }

1944

1945

1947 Constant *MinSignedC = ConstantInt::get(

1948 X->getType(),

1951 return new ICmpInst(NewPred, X, MinSignedC);

1952 }

1953 }

1954

1955

1956

1957

1964 return Res;

1965

1966 if (!Cmp.isEquality())

1967 return nullptr;

1968

1969

1970

1971

1972 if (Cmp.getOperand(1) == Y && C.isNegatedPowerOf2()) {

1973 auto NewPred =

1976 }

1977

1978

1979

1980

1981

1983 X->getType()->isIntOrIntVectorTy(1) && (C.isZero() || C.isOne())) {

1984 Value *TruncY = Builder.CreateTrunc(Y, X->getType());

1988 }

1989 return BinaryOperator::CreateAnd(TruncY, X);

1990 }

1991

1992

1993

1994

1995

1996 if (C.isZero() &&

2001 }

2002

2003

2004

2005 {

2007 const APInt *Addend, *Msk;

2010 C.ule(*Msk)) {

2011 APInt NewComperand = (C - *Addend) & *Msk;

2012 Value *MaskA = Builder.CreateAnd(A, ConstantInt::get(A->getType(), *Msk));

2013 return new ICmpInst(Pred, MaskA,

2014 ConstantInt::get(MaskA->getType(), NewComperand));

2015 }

2016 }

2017

2018 return nullptr;

2019}

2020

2021

2024

2025

2026

2027

2028

2029

2030

2031

2032

2035

2036 while (!WorkList.empty()) {

2037 auto MatchOrOperatorArgument = [&](Value *OrOperatorArgument) {

2038 Value *Lhs, *Rhs;

2039

2040 if (match(OrOperatorArgument,

2043 return;

2044 }

2045

2046 if (match(OrOperatorArgument,

2049 return;

2050 }

2051

2052 WorkList.push_back(OrOperatorArgument);

2053 };

2054

2056 Value *OrOperatorLhs, *OrOperatorRhs;

2057

2058 if (match(CurrentValue,

2060 return nullptr;

2061 }

2062

2063 MatchOrOperatorArgument(OrOperatorRhs);

2064 MatchOrOperatorArgument(OrOperatorLhs);

2065 }

2066

2068 auto BOpc = Pred == CmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;

2069 Value *LhsCmp = Builder.CreateICmp(Pred, CmpValues.rbegin()->first,

2070 CmpValues.rbegin()->second);

2071

2072 for (auto It = CmpValues.rbegin() + 1; It != CmpValues.rend(); ++It) {

2073 Value *RhsCmp = Builder.CreateICmp(Pred, It->first, It->second);

2074 LhsCmp = Builder.CreateBinOp(BOpc, LhsCmp, RhsCmp);

2075 }

2076

2077 return LhsCmp;

2078}

2079

2080

2085 if (C.isOne()) {

2086

2087 Value *V = nullptr;

2090 ConstantInt::get(V->getType(), 1));

2091 }

2092

2093 Value *OrOp0 = Or->getOperand(0), *OrOp1 = Or->getOperand(1);

2094

2095

2096

2100 Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(), C));

2101 return new ICmpInst(Pred, OrOp0, NewC);

2102 }

2103

2104 const APInt *MaskC;

2105 if (match(OrOp1, m_APInt(MaskC)) && Cmp.isEquality()) {

2106 if (*MaskC == C && (C + 1).isPowerOf2()) {

2107

2108

2109

2111 return new ICmpInst(Pred, OrOp0, OrOp1);

2112 }

2113

2114

2115

2116

2117

2118 if (Or->hasOneUse()) {

2120 Constant *NewC = ConstantInt::get(Or->getType(), C ^ (*MaskC));

2122 }

2123 }

2124

2125

2126

2128 bool TrueIfSigned;

2132 Constant *NewC = ConstantInt::get(X->getType(), TrueIfSigned ? 1 : 0);

2133 return new ICmpInst(NewPred, X, NewC);

2134 }

2135

2136 const APInt *OrC;

2137

2139 switch (Pred) {

2140

2142

2144 if (OrC->sge(C))

2146 break;

2147

2149

2151 if (OrC->sgt(C))

2154 break;

2155 default:

2156 break;

2157 }

2158 }

2159

2160 if (!Cmp.isEquality() || C.isZero() || Or->hasOneUse())

2161 return nullptr;

2162

2165

2166

2171 auto BOpc = Pred == CmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;

2173 }

2174

2177

2178 return nullptr;

2179}

2180

2181

2186 Type *MulTy = Mul->getType();

2188

2189

2190

2191

2192 if (Cmp.isEquality() && C.isZero() && X == Mul->getOperand(1) &&

2193 (Mul->hasNoUnsignedWrap() || Mul->hasNoSignedWrap()))

2195

2196 const APInt *MulC;

2198 return nullptr;

2199

2200

2201

2202

2203

2204 if (isSignTest(Pred, C) && Mul->hasNoSignedWrap()) {

2208 }

2209

2211 return nullptr;

2212

2213

2214

2215 if (Cmp.isEquality()) {

2216

2217 if (Mul->hasNoSignedWrap() && C.srem(*MulC).isZero()) {

2218 Constant *NewC = ConstantInt::get(MulTy, C.sdiv(*MulC));

2219 return new ICmpInst(Pred, X, NewC);

2220 }

2221

2222

2223

2224

2225

2226 if (C.urem(*MulC).isZero()) {

2227

2228

2229 if ((*MulC & 1).isOne() || Mul->hasNoUnsignedWrap()) {

2230 Constant *NewC = ConstantInt::get(MulTy, C.udiv(*MulC));

2231 return new ICmpInst(Pred, X, NewC);

2232 }

2233 }

2234 }

2235

2236

2237

2238

2239

2242

2243 if (C.isMinSignedValue() && MulC->isAllOnes())

2244 return nullptr;

2247

2249 NewC = ConstantInt::get(

2251 } else {

2253 "Unexpected predicate");

2254 NewC = ConstantInt::get(

2256 }

2259 NewC = ConstantInt::get(

2261 } else {

2263 "Unexpected predicate");

2264 NewC = ConstantInt::get(

2266 }

2267 }

2268

2269 return NewC ? new ICmpInst(Pred, X, NewC) : nullptr;

2270}

2271

2272

2276 const APInt *C2;

2278 return nullptr;

2279

2281 unsigned TypeBits = C.getBitWidth();

2283 if (Cmp.isUnsigned()) {

2285 return nullptr;

2289

2290

2291 if (!CIsPowerOf2) {

2292

2293

2294

2295

2300 }

2301

2302 unsigned CLog2 = Div.logBase2();

2303 return new ICmpInst(Pred, Y, ConstantInt::get(ShiftType, CLog2));

2304 } else if (Cmp.isSigned() && C2->isOne()) {

2305 Constant *BitWidthMinusOne = ConstantInt::get(ShiftType, TypeBits - 1);

2306

2307

2310

2311

2312

2313

2314

2317 }

2318

2319 return nullptr;

2320}

2321

2322

2326 const APInt *ShiftVal;

2329

2331

2332

2333

2334

2335

2338

2339

2340

2344

2345

2346

2347

2348

2349

2350

2355

2356 const APInt *ShiftAmt;

2359

2360

2361

2362 unsigned TypeBits = C.getBitWidth();

2363 if (ShiftAmt->uge(TypeBits))

2364 return nullptr;

2365

2368

2369

2370

2371

2374

2375 APInt ShiftedC = C.ashr(*ShiftAmt);

2376 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));

2377 }

2379 C.ashr(*ShiftAmt).shl(*ShiftAmt) == C) {

2380 APInt ShiftedC = C.ashr(*ShiftAmt);

2381 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));

2382 }

2384

2385

2386

2387

2388 assert(C.isMinSignedValue() && "Unexpected icmp slt");

2389 APInt ShiftedC = (C - 1).ashr(*ShiftAmt) + 1;

2390 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));

2391 }

2392 }

2393

2394

2395

2396

2399

2400 APInt ShiftedC = C.lshr(*ShiftAmt);

2401 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));

2402 }

2404 C.lshr(*ShiftAmt).shl(*ShiftAmt) == C) {

2405 APInt ShiftedC = C.lshr(*ShiftAmt);

2406 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));

2407 }

2409

2410

2411

2412

2413 assert(C.ugt(0) && "ult 0 should have been eliminated");

2414 APInt ShiftedC = (C - 1).lshr(*ShiftAmt) + 1;

2415 return new ICmpInst(Pred, X, ConstantInt::get(ShType, ShiftedC));

2416 }

2417 }

2418

2419 if (Cmp.isEquality() && Shl->hasOneUse()) {

2420

2421 Constant *Mask = ConstantInt::get(

2422 ShType,

2425 Constant *LShrC = ConstantInt::get(ShType, C.lshr(*ShiftAmt));

2427 }

2428

2429

2430 bool TrueIfSigned = false;

2432

2433 Constant *Mask = ConstantInt::get(

2434 ShType,

2439 }

2440

2441

2442 if (Cmp.isUnsigned() && Shl->hasOneUse()) {

2443

2444 if ((C + 1).isPowerOf2() &&

2450 }

2451

2452 if (C.isPowerOf2() &&

2459 }

2460 }

2461

2462

2463

2464

2465

2466

2467

2469 if (Shl->hasOneUse() && Amt != 0 &&

2473

2475

2476

2477

2478

2479

2480

2482 Pred, ConstantInt::get(ShType->getContext(), C))) {

2483 CmpPred = FlippedStrictness->first;

2484 RHSC = cast(FlippedStrictness->second)->getValue();

2485 }

2486 }

2487

2491 ConstantInt::get(TruncTy, RHSC.ashr(*ShiftAmt).trunc(TypeBits - Amt));

2492 return new ICmpInst(CmpPred,

2493 Builder.CreateTrunc(X, TruncTy, "", false,

2495 NewC);

2496 }

2497 }

2498

2499 return nullptr;

2500}

2501

2502

2506

2507

2510 if (Cmp.isEquality() && Shr->isExact() && C.isZero())

2511 return new ICmpInst(Pred, X, Cmp.getOperand(1));

2512

2513 bool IsAShr = Shr->getOpcode() == Instruction::AShr;

2514 const APInt *ShiftValC;

2516 if (Cmp.isEquality())

2518

2519

2520

2521 bool TrueIfSigned;

2522 if (!IsAShr && ShiftValC->isNegative() &&

2527

2528

2529

2530

2531 if (!IsAShr && ShiftValC->isPowerOf2() &&

2534 assert(ShiftValC->uge(C) && "Expected simplify of compare");

2535 assert((IsUGT || C.isZero()) && "Expected X u< 0 to simplify");

2536

2537 unsigned CmpLZ = IsUGT ? C.countl_zero() : (C - 1).countl_zero();

2538 unsigned ShiftLZ = ShiftValC->countl_zero();

2539 Constant *NewC = ConstantInt::get(Shr->getType(), CmpLZ - ShiftLZ);

2542 }

2543 }

2544

2545 const APInt *ShiftAmtC;

2547 return nullptr;

2548

2549

2550

2551 unsigned TypeBits = C.getBitWidth();

2552 unsigned ShAmtVal = ShiftAmtC->getLimitedValue(TypeBits);

2553 if (ShAmtVal >= TypeBits || ShAmtVal == 0)

2554 return nullptr;

2555

2556 bool IsExact = Shr->isExact();

2558

2559

2560

2561

2562 if (IsAShr && Shr->hasOneUse()) {

2564 (C - 1).isPowerOf2() && C.countLeadingZeros() > ShAmtVal) {

2565

2566

2567

2568

2569

2570 APInt ShiftedC = (C - 1).shl(ShAmtVal) + 1;

2571 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));

2572 }

2574

2575

2576

2577 APInt ShiftedC = C.shl(ShAmtVal);

2578 if (ShiftedC.ashr(ShAmtVal) == C)

2579 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));

2580 }

2582

2583 APInt ShiftedC = (C + 1).shl(ShAmtVal) - 1;

2584 if (C.isMaxSignedValue() && !(C + 1).shl(ShAmtVal).isMinSignedValue() &&

2585 (ShiftedC + 1).ashr(ShAmtVal) == (C + 1))

2586 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));

2587 }

2589

2590

2591

2592 APInt ShiftedC = (C + 1).shl(ShAmtVal) - 1;

2593 if ((ShiftedC + 1).ashr(ShAmtVal) == (C + 1) ||

2594 (C + 1).shl(ShAmtVal).isMinSignedValue())

2595 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));

2596 }

2597

2598

2599

2600

2601

2602 if (C.getBitWidth() > 2 && C.getNumSignBits() <= ShAmtVal) {

2606 }

2610 }

2611 }

2612 } else if (!IsAShr) {

2614

2615

2616 APInt ShiftedC = C.shl(ShAmtVal);

2617 if (ShiftedC.lshr(ShAmtVal) == C)

2618 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));

2619 }

2621

2622 APInt ShiftedC = (C + 1).shl(ShAmtVal) - 1;

2623 if ((ShiftedC + 1).lshr(ShAmtVal) == (C + 1))

2624 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC));

2625 }

2626 }

2627

2628 if (!Cmp.isEquality())

2629 return nullptr;

2630

2631

2632

2633

2634

2635

2636 assert(((IsAShr && C.shl(ShAmtVal).ashr(ShAmtVal) == C) ||

2637 (!IsAShr && C.shl(ShAmtVal).lshr(ShAmtVal) == C)) &&

2638 "Expected icmp+shr simplify did not occur.");

2639

2640

2641

2643 return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, C << ShAmtVal));

2644

2646

2647

2649 Constant *Mask = ConstantInt::get(ShrTy, Val);

2651 return new ICmpInst(Pred, And, ConstantInt::get(ShrTy, C << ShAmtVal));

2652 }

2653

2654 return nullptr;

2655}

2656

2662

2663

2664

2665

2666

2667

2668 const APInt *DivisorC;

2670 return nullptr;

2671

2672 APInt NormalizedC = C;

2675 "ult X, 0 should have been simplified already.");

2676 --NormalizedC;

2677 }

2678 if (C.isNegative())

2681 "srem X, 0 should have been simplified already.");

2682 if (!NormalizedC.uge(DivisorC->abs() - 1))

2683 return nullptr;

2684

2691 }

2692

2693

2694

2697 return nullptr;

2698

2699

2700

2701

2703 return nullptr;

2704

2705 const APInt *DivisorC;

2707 return nullptr;

2708

2709

2710

2712 C.isZero()) ||

2714 C.isStrictlyPositive()))

2715 return nullptr;

2716

2717

2720 Constant *MaskC = ConstantInt::get(Ty, SignMask | (*DivisorC - 1));

2722

2724 return new ICmpInst(Pred, And, ConstantInt::get(Ty, C));

2725

2726

2727

2728

2731

2732

2733

2734

2736}

2737

2738

2746

2747 const APInt *C2;

2749 return nullptr;

2750

2751 assert(*C2 != 0 && "udiv 0, X should have been simplified already.");

2752

2753

2755 assert(C.isMaxValue() &&

2756 "icmp ugt X, UINT_MAX should have been simplified already.");

2758 ConstantInt::get(Ty, C2->udiv(C + 1)));

2759 }

2760

2761

2763 assert(C != 0 && "icmp ult X, 0 should have been simplified already.");

2765 ConstantInt::get(Ty, C2->udiv(C)));

2766 }

2767

2768 return nullptr;

2769}

2770

2771

2779 bool DivIsSigned = Div->getOpcode() == Instruction::SDiv;

2780

2781

2782

2783

2784

2785

2786

2787

2788

2789 if (Cmp.isEquality() && Div->hasOneUse() && C.isSignBitSet() &&

2790 (!DivIsSigned || C.isMinSignedValue())) {

2791 Value *XBig = Builder.CreateICmp(Pred, X, ConstantInt::get(Ty, C));

2792 Value *YOne = Builder.CreateICmp(Pred, Y, ConstantInt::get(Ty, 1));

2793 auto Logic = Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;

2795 }

2796

2797

2798

2799

2800

2801

2802

2803 const APInt *C2;

2805 return nullptr;

2806

2807

2808

2809

2810

2811

2812

2813

2814

2815 if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned())

2816 return nullptr;

2817

2818

2819

2820

2821

2823 return nullptr;

2824

2825

2826

2827

2828

2829 APInt Prod = C * *C2;

2830

2831

2832

2833

2834 bool ProdOV = (DivIsSigned ? Prod.sdiv(*C2) : Prod.udiv(*C2)) != C;

2835

2836

2837

2839

2840

2841

2842

2843

2844

2845

2846

2847 int LoOverflow = 0, HiOverflow = 0;

2848 APInt LoBound, HiBound;

2849

2850 if (!DivIsSigned) {

2851

2852 LoBound = Prod;

2853 HiOverflow = LoOverflow = ProdOV;

2854 if (!HiOverflow) {

2855

2856

2857 HiOverflow = addWithOverflow(HiBound, LoBound, RangeSize, false);

2858 }

2860 if (C.isZero()) {

2861

2862 LoBound = -(RangeSize - 1);

2863 HiBound = RangeSize;

2864 } else if (C.isStrictlyPositive()) {

2865 LoBound = Prod;

2866 HiOverflow = LoOverflow = ProdOV;

2867 if (!HiOverflow)

2868 HiOverflow = addWithOverflow(HiBound, Prod, RangeSize, true);

2869 } else {

2870

2871 HiBound = Prod + 1;

2872 LoOverflow = HiOverflow = ProdOV ? -1 : 0;

2873 if (!LoOverflow) {

2874 APInt DivNeg = -RangeSize;

2875 LoOverflow = addWithOverflow(LoBound, HiBound, DivNeg, true) ? -1 : 0;

2876 }

2877 }

2878 } else if (C2->isNegative()) {

2881 if (C.isZero()) {

2882

2883 LoBound = RangeSize + 1;

2884 HiBound = -RangeSize;

2885 if (HiBound == *C2) {

2886 HiOverflow = 1;

2887 HiBound = APInt();

2888 }

2889 } else if (C.isStrictlyPositive()) {

2890

2891 HiBound = Prod + 1;

2892 HiOverflow = LoOverflow = ProdOV ? -1 : 0;

2893 if (!LoOverflow)

2894 LoOverflow =

2895 addWithOverflow(LoBound, HiBound, RangeSize, true) ? -1 : 0;

2896 } else {

2897 LoBound = Prod;

2898 LoOverflow = HiOverflow = ProdOV;

2899 if (!HiOverflow)

2900 HiOverflow = subWithOverflow(HiBound, Prod, RangeSize, true);

2901 }

2902

2903

2905 }

2906

2907 switch (Pred) {

2908 default:

2911 if (LoOverflow && HiOverflow)

2913 if (HiOverflow)

2915 X, ConstantInt::get(Ty, LoBound));

2916 if (LoOverflow)

2918 X, ConstantInt::get(Ty, HiBound));

2920 Cmp, insertRangeTest(X, LoBound, HiBound, DivIsSigned, true));

2922 if (LoOverflow && HiOverflow)

2924 if (HiOverflow)

2926 X, ConstantInt::get(Ty, LoBound));

2927 if (LoOverflow)

2929 X, ConstantInt::get(Ty, HiBound));

2931 Cmp, insertRangeTest(X, LoBound, HiBound, DivIsSigned, false));

2934 if (LoOverflow == +1)

2936 if (LoOverflow == -1)

2938 return new ICmpInst(Pred, X, ConstantInt::get(Ty, LoBound));

2941 if (HiOverflow == +1)

2943 if (HiOverflow == -1)

2948 }

2949

2950 return nullptr;

2951}

2952

2953

2957 Value *X = Sub->getOperand(0), *Y = Sub->getOperand(1);

2959 Type *Ty = Sub->getType();

2960

2961

2962

2967 }

2968

2969

2970 const APInt *C2;

2971 APInt SubResult;

2973 bool HasNSW = Sub->hasNoSignedWrap();

2974 bool HasNUW = Sub->hasNoUnsignedWrap();

2976 ((Cmp.isUnsigned() && HasNUW) || (Cmp.isSigned() && HasNSW)) &&

2978 return new ICmpInst(SwappedPred, Y, ConstantInt::get(Ty, SubResult));

2979

2980

2981

2982

2983

2984

2985

2986 if (Cmp.isEquality() && C.isZero() &&

2987 none_of((Sub->users()), [](const User *U) { return isa(U); }))

2989

2990

2991

2992

2993

2994

2995 if (Sub->hasOneUse())

2996 return nullptr;

2997

2998 if (Sub->hasNoSignedWrap()) {

2999

3002

3003

3006

3007

3010

3011

3014 }

3015

3017 return nullptr;

3018

3019

3020

3022 (*C2 & (C - 1)) == (C - 1))

3024

3025

3026

3029

3030

3031

3032

3033 Value *Add = Builder.CreateAdd(Y, ConstantInt::get(Ty, ~(*C2)), "notsub",

3034 HasNUW, HasNSW);

3035 return new ICmpInst(SwappedPred, Add, ConstantInt::get(Ty, ~C));

3036}

3037

3040 bool HasOneUse) {

3041 auto FoldConstant = [&](bool Val) {

3042 Constant *Res = Val ? Builder.getTrue() : Builder.getFalse();

3046 return Res;

3047 };

3048

3049 switch (Table.to_ulong()) {

3050 case 0:

3051 return FoldConstant(false);

3052 case 1:

3053 return HasOneUse ? Builder.CreateNot(Builder.CreateOr(Op0, Op1)) : nullptr;

3054 case 2:

3055 return HasOneUse ? Builder.CreateAnd(Builder.CreateNot(Op0), Op1) : nullptr;

3056 case 3:

3057 return Builder.CreateNot(Op0);

3058 case 4:

3059 return HasOneUse ? Builder.CreateAnd(Op0, Builder.CreateNot(Op1)) : nullptr;

3060 case 5:

3061 return Builder.CreateNot(Op1);

3062 case 6:

3063 return Builder.CreateXor(Op0, Op1);

3064 case 7:

3065 return HasOneUse ? Builder.CreateNot(Builder.CreateAnd(Op0, Op1)) : nullptr;

3066 case 8:

3067 return Builder.CreateAnd(Op0, Op1);

3068 case 9:

3069 return HasOneUse ? Builder.CreateNot(Builder.CreateXor(Op0, Op1)) : nullptr;

3070 case 10:

3071 return Op1;

3072 case 11:

3073 return HasOneUse ? Builder.CreateOr(Builder.CreateNot(Op0), Op1) : nullptr;

3074 case 12:

3075 return Op0;

3076 case 13:

3077 return HasOneUse ? Builder.CreateOr(Op0, Builder.CreateNot(Op1)) : nullptr;

3078 case 14:

3079 return Builder.CreateOr(Op0, Op1);

3080 case 15:

3081 return FoldConstant(true);

3082 default:

3084 }

3085 return nullptr;

3086}

3087

3091 Constant *C1, *C2, *C3, *C4;

3096 Cmp.getType() != A->getType())

3097 return nullptr;

3098

3099 std::bitset<4> Table;

3100 auto ComputeTable = [&](bool First, bool Second) -> std::optional {

3102 Constant *R = Second ? C3 : C4;

3104 auto *Val = Res->getType()->isVectorTy() ? Res->getSplatValue() : Res;

3107 }

3108 return std::nullopt;

3109 };

3110

3111 for (unsigned I = 0; I < 4; ++I) {

3112 bool First = (I >> 1) & 1;

3113 bool Second = I & 1;

3114 if (auto Res = ComputeTable(First, Second))

3115 Table[I] = *Res;

3116 else

3117 return nullptr;

3118 }

3119

3120

3123 return nullptr;

3124}

3125

3126

3132

3133 Value *Op0, *Op1;

3135 const CmpPredicate Pred = Cmp.getCmpPredicate();

3142 unsigned BW = C.getBitWidth();

3143 std::bitset<4> Table;

3144 auto ComputeTable = [&](bool Op0Val, bool Op1Val) {

3145 APInt Res(BW, 0);

3146 if (Op0Val)

3148 if (Op1Val)

3151 };

3152

3153 Table[0] = ComputeTable(false, false);

3154 Table[1] = ComputeTable(false, true);

3155 Table[2] = ComputeTable(true, false);

3156 Table[3] = ComputeTable(true, true);

3157 if (auto *Cond =

3160 }

3161 const APInt *C2;

3163 return nullptr;

3164

3165

3166 Type *Ty = Add->getType();

3167

3168

3169

3170

3171 if (Add->hasNoUnsignedWrap() &&

3173 bool Overflow;

3174 APInt NewC = C.usub_ov(*C2, Overflow);

3175

3176 if (!Overflow)

3177

3178 return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC));

3179 }

3180

3182

3183 if (Add->hasNoSignedWrap() &&

3185 bool Overflow;

3186 APInt NewC = C.ssub_ov(*C2, Overflow);

3187 if (!Overflow)

3188

3189

3190 return new ICmpInst(ChosenPred, X, ConstantInt::get(Ty, NewC));

3191 }

3192

3194 C.isNonNegative() && (C - *C2).isNonNegative() &&

3197 ConstantInt::get(Ty, C - *C2));

3198

3202 if (Cmp.isSigned()) {

3203 if (Lower.isSignMask())

3205 if (Upper.isSignMask())

3207 } else {

3208 if (Lower.isMinValue())

3210 if (Upper.isMinValue())

3212 }

3213

3214

3215

3218

3219

3220

3223

3224

3227

3228

3231

3232

3235

3236

3241 }

3242

3243 if (Add->hasOneUse())

3244 return nullptr;

3245

3246

3247

3248

3252

3253

3254

3255

3258 ConstantInt::get(Ty, C * 2));

3259

3260

3261

3262

3266

3267

3268

3269

3272 Builder.CreateAdd(X, ConstantInt::get(Ty, *C2 - C - 1)),

3273 ConstantInt::get(Ty, ~C));

3274

3275

3278 Type *NewCmpTy = V->getType();

3280 if (shouldChangeType(Ty, NewCmpTy)) {

3284 APInt EquivOffset;

3285

3288 EquivPred,

3289 EquivOffset.isZero()

3290 ? V

3291 : Builder.CreateAdd(V, ConstantInt::get(NewCmpTy, EquivOffset)),

3292 ConstantInt::get(NewCmpTy, EquivInt));

3293 }

3294 }

3295

3296 return nullptr;

3297}

3298

3303

3304

3305

3306

3307

3308

3309

3313 return false;

3314 Value *EqualVal = SI->getTrueValue();

3315 Value *UnequalVal = SI->getFalseValue();

3316

3318 std::swap(EqualVal, UnequalVal);

3320 return false;

3322 Value *LHS2, *RHS2;

3325 return false;

3326

3327

3328 if (LHS2 != LHS) {

3329

3332 }

3333 if (LHS2 != LHS)

3334 return false;

3335

3337

3338 auto FlippedStrictness =

3340 if (!FlippedStrictness)

3341 return false;

3343 "basic correctness failure");

3344 RHS2 = FlippedStrictness->second;

3345

3348 }

3350}

3351

3355

3356 assert(C && "Cmp RHS should be a constant int!");

3357

3358

3359

3360

3361

3362 Value *OrigLHS, *OrigRHS;

3363 ConstantInt *C1LessThan, *C2Equal, *C3GreaterThan;

3364 if (Cmp.hasOneUse() &&

3366 C3GreaterThan)) {

3367 assert(C1LessThan && C2Equal && C3GreaterThan);

3368

3370 C1LessThan->getValue(), C->getValue(), Cmp.getPredicate());

3372 Cmp.getPredicate());

3374 C3GreaterThan->getValue(), C->getValue(), Cmp.getPredicate());

3375

3376

3377

3378

3379

3380

3381

3382

3383

3385 if (TrueWhenLessThan)

3388 if (TrueWhenEqual)

3391 if (TrueWhenGreaterThan)

3394

3396 }

3397 return nullptr;

3398}

3399

3402 if (!Bitcast)

3403 return nullptr;

3404

3406 Value *Op1 = Cmp.getOperand(1);

3407 Value *BCSrcOp = Bitcast->getOperand(0);

3408 Type *SrcType = Bitcast->getSrcTy();

3409 Type *DstType = Bitcast->getType();

3410

3411

3412

3413 if (SrcType->isVectorTy() == DstType->isVectorTy() &&

3414 SrcType->getScalarSizeInBits() == DstType->getScalarSizeInBits()) {

3415

3418

3419

3420

3421

3426

3427

3429 return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), 1));

3430

3431

3435 }

3436

3437

3438

3439

3441 if (Cmp.isEquality() && match(Op1, m_Zero()))

3443

3445 bool TrueIfSigned;

3446 if (match(Op1, m_APInt(C)) && Bitcast->hasOneUse()) {

3447

3448

3449

3450

3454

3455

3456 Type *XType = X->getType();

3457

3458

3459 if (!(XType->isPPC_FP128Ty() || SrcType->isPPC_FP128Ty())) {

3462 NewType = VectorType::get(NewType, XVTy->getElementCount());

3463 Value *NewBitcast = Builder.CreateBitCast(X, NewType);

3464 if (TrueIfSigned)

3467 else

3470 }

3471 }

3472

3473

3474 Type *FPType = SrcType->getScalarType();

3475 if (!Cmp.getParent()->getParent()->hasFnAttribute(

3476 Attribute::NoImplicitFloat) &&

3477 Cmp.isEquality() && FPType->isIEEELikeFPTy()) {

3481 Mask = ~Mask;

3483 Builder.createIsFPClass(BCSrcOp, Mask));

3484 }

3485 }

3486 }

3487 }

3488

3490 if (match(Cmp.getOperand(1), m_APInt(C)) || !DstType->isIntegerTy() ||

3491 !SrcType->isIntOrIntVectorTy())

3492 return nullptr;

3493

3494

3495

3496

3497

3498

3499

3500

3501 if (Cmp.isEquality() && C->isAllOnes() && Bitcast->hasOneUse()) {

3502 if (Value *NotBCSrcOp =

3504 Value *Cast = Builder.CreateBitCast(NotBCSrcOp, DstType);

3506 }

3507 }

3508

3509

3510

3511

3513 if (Cmp.isEquality() && C->isZero() && Bitcast->hasOneUse() &&

3516 Type *NewType = Builder.getIntNTy(VecTy->getPrimitiveSizeInBits());

3517 Value *NewCast = Builder.CreateBitCast(X, NewType);

3519 }

3520 }

3521

3522

3523

3524

3525

3526

3527

3528

3532

3536 if (C->isSplat(EltTy->getBitWidth())) {

3537

3538

3539

3540

3541

3543 Value *Extract = Builder.CreateExtractElement(Vec, Elem);

3544 Value *NewC = ConstantInt::get(EltTy, C->trunc(EltTy->getBitWidth()));

3545 return new ICmpInst(Pred, Extract, NewC);

3546 }

3547 }

3548 }

3549 return nullptr;

3550}

3551

3552

3553

3556

3560 return I;

3561

3563

3564

3565

3568 return I;

3569

3572 return I;

3573

3576 return I;

3577

3578

3579

3580

3581 Value *Cmp0 = Cmp.getOperand(0);

3583 if (C->isZero() && Cmp.isEquality() && Cmp0->hasOneUse() &&

3590 return new ICmpInst(Cmp.getPredicate(), X, Y);

3591 }

3592

3595

3596 return nullptr;

3597}

3598

3599

3600

3603

3604

3605 if (!Cmp.isEquality())

3606 return nullptr;

3607

3612

3614 case Instruction::SRem:

3615

3616 if (C.isZero() && BO->hasOneUse()) {

3617 const APInt *BOC;

3620 return new ICmpInst(Pred, NewRem,

3622 }

3623 }

3624 break;

3625 case Instruction::Add: {

3626

3627

3628

3632 } else if (C.isZero()) {

3633

3634

3635 if (Value *NegVal = dyn_castNegVal(BOp1))

3636 return new ICmpInst(Pred, BOp0, NegVal);

3637 if (Value *NegVal = dyn_castNegVal(BOp0))

3638 return new ICmpInst(Pred, NegVal, BOp1);

3640

3644 }

3647 return new ICmpInst(Pred, BOp0, Neg);

3648 }

3649 }

3650 break;

3651 }

3652 case Instruction::Xor:

3654

3655

3657 } else if (C.isZero()) {

3658

3659 return new ICmpInst(Pred, BOp0, BOp1);

3660 }

3661 break;

3662 case Instruction::Or: {

3663 const APInt *BOC;

3665

3666

3667

3671 }

3672

3673

3674

3675

3677 if (C.isZero() &&

3683 Cond->getType() == Cmp.getType()) {

3685

3692 Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or, Cmp,

3694 }

3695

3696

3697

3698

3699

3700

3701

3702

3703

3704

3705

3706

3715 Pred == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or, Cmp,

3716 NotCond);

3717 }

3718 }

3719 break;

3720 }

3721 case Instruction::UDiv:

3722 case Instruction::SDiv:

3724

3725

3726

3727

3728

3729 if (C.isZero())

3731 else if (C.isOne())

3732 return new ICmpInst(Pred, BOp0, BOp1);

3735 Instruction::Mul, BO->getOpcode() == Instruction::SDiv, BOp1,

3736 Cmp.getOperand(1), BO);

3739 Builder.CreateMul(BOp1, ConstantInt::get(BO->getType(), C));

3740 return new ICmpInst(Pred, YC, BOp0);

3741 }

3742 }

3743 }

3744 if (BO->getOpcode() == Instruction::UDiv && C.isZero()) {

3745

3747 return new ICmpInst(NewPred, BOp1, BOp0);

3748 }

3749 break;

3750 default:

3751 break;

3752 }

3753 return nullptr;

3754}

3755

3757 const APInt &CRhs,

3761 "Non-ctpop intrin in ctpop fold");

3763 return nullptr;

3764

3765

3766

3767

3768

3769

3770

3771

3772

3778

3780 Value *And = Builder.CreateAnd(

3787 }

3788 }

3789

3790 return nullptr;

3791}

3792

3793

3796 Type *Ty = II->getType();

3797 unsigned BitWidth = C.getBitWidth();

3799

3800 switch (II->getIntrinsicID()) {

3801 case Intrinsic::abs:

3802

3803

3804 if (C.isZero() || C.isMinSignedValue())

3805 return new ICmpInst(Pred, II->getArgOperand(0), ConstantInt::get(Ty, C));

3806 break;

3807

3808 case Intrinsic::bswap:

3809

3810 return new ICmpInst(Pred, II->getArgOperand(0),

3811 ConstantInt::get(Ty, C.byteSwap()));

3812

3813 case Intrinsic::bitreverse:

3814

3815 return new ICmpInst(Pred, II->getArgOperand(0),

3816 ConstantInt::get(Ty, C.reverseBits()));

3817

3818 case Intrinsic::ctlz:

3819 case Intrinsic::cttz: {

3820

3822 return new ICmpInst(Pred, II->getArgOperand(0),

3824

3825

3826

3827

3828 unsigned Num = C.getLimitedValue(BitWidth);

3829 if (Num != BitWidth && II->hasOneUse()) {

3830 bool IsTrailing = II->getIntrinsicID() == Intrinsic::cttz;

3833 APInt Mask2 = IsTrailing

3836 return new ICmpInst(Pred, Builder.CreateAnd(II->getArgOperand(0), Mask1),

3837 ConstantInt::get(Ty, Mask2));

3838 }

3839 break;

3840 }

3841

3842 case Intrinsic::ctpop: {

3843

3844

3845 bool IsZero = C.isZero();

3847 return new ICmpInst(Pred, II->getArgOperand(0),

3850

3851 break;

3852 }

3853

3854 case Intrinsic::fshl:

3855 case Intrinsic::fshr:

3856 if (II->getArgOperand(0) == II->getArgOperand(1)) {

3857 const APInt *RotAmtC;

3858

3859

3861 return new ICmpInst(Pred, II->getArgOperand(0),

3862 II->getIntrinsicID() == Intrinsic::fshl

3863 ? ConstantInt::get(Ty, C.rotr(*RotAmtC))

3864 : ConstantInt::get(Ty, C.rotl(*RotAmtC)));

3865 }

3866 break;

3867

3868 case Intrinsic::umax:

3869 case Intrinsic::uadd_sat: {

3870

3871

3872 if (C.isZero() && II->hasOneUse()) {

3873 Value *Or = Builder.CreateOr(II->getArgOperand(0), II->getArgOperand(1));

3875 }

3876 break;

3877 }

3878

3879 case Intrinsic::ssub_sat:

3880

3881 if (C.isZero())

3882 return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1));

3883 break;

3884 case Intrinsic::usub_sat: {

3885

3886 if (C.isZero()) {

3889 return new ICmpInst(NewPred, II->getArgOperand(0), II->getArgOperand(1));

3890 }

3891 break;

3892 }

3893 default:

3894 break;

3895 }

3896

3897 return nullptr;

3898}

3899

3900

3904 assert(Cmp.isEquality());

3905

3907 Value *Op0 = Cmp.getOperand(0);

3908 Value *Op1 = Cmp.getOperand(1);

3911 if (!IIOp0 || !IIOp1 || IIOp0->getIntrinsicID() != IIOp1->getIntrinsicID())

3912 return nullptr;

3913

3914 switch (IIOp0->getIntrinsicID()) {

3915 case Intrinsic::bswap:

3916 case Intrinsic::bitreverse:

3917

3918

3919 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));

3920 case Intrinsic::fshl:

3921 case Intrinsic::fshr: {

3922

3923

3924 if (IIOp0->getOperand(0) != IIOp0->getOperand(1))

3925 break;

3926 if (IIOp1->getOperand(0) != IIOp1->getOperand(1))

3927 break;

3928 if (IIOp0->getOperand(2) == IIOp1->getOperand(2))

3929 return new ICmpInst(Pred, IIOp0->getOperand(0), IIOp1->getOperand(0));

3930

3931

3932

3933

3934

3935 unsigned OneUses = IIOp0->hasOneUse() + IIOp1->hasOneUse();

3936 if (OneUses == 2 ||

3940 Builder.CreateSub(IIOp0->getOperand(2), IIOp1->getOperand(2));

3941 Value *CombinedRotate = Builder.CreateIntrinsic(

3942 Op0->getType(), IIOp0->getIntrinsicID(),

3943 {IIOp0->getOperand(0), IIOp0->getOperand(0), SubAmt});

3944 return new ICmpInst(Pred, IIOp1->getOperand(0), CombinedRotate);

3945 }

3946 } break;

3947 default:

3948 break;

3949 }

3950

3951 return nullptr;

3952}

3953

3954

3955

3956

3962 switch (II->getIntrinsicID()) {

3963 default:

3964 break;

3965 case Intrinsic::fshl:

3966 case Intrinsic::fshr:

3967 if (Cmp.isEquality() && II->getArgOperand(0) == II->getArgOperand(1)) {

3968

3969 if (C.isZero() || C.isAllOnes())

3970 return new ICmpInst(Pred, II->getArgOperand(0), Cmp.getOperand(1));

3971 }

3972 break;

3973 }

3974 }

3975

3976 return nullptr;

3977}

3978

3979

3984 case Instruction::Xor:

3986 return I;

3987 break;

3988 case Instruction::And:

3990 return I;

3991 break;

3992 case Instruction::Or:

3994 return I;

3995 break;

3996 case Instruction::Mul:

3998 return I;

3999 break;

4000 case Instruction::Shl:

4002 return I;

4003 break;

4004 case Instruction::LShr:

4005 case Instruction::AShr:

4007 return I;

4008 break;

4009 case Instruction::SRem:

4011 return I;

4012 break;

4013 case Instruction::UDiv:

4015 return I;

4016 [[fallthrough]];

4017 case Instruction::SDiv:

4019 return I;

4020 break;

4021 case Instruction::Sub:

4023 return I;

4024 break;

4025 case Instruction::Add:

4027 return I;

4028 break;

4029 default:

4030 break;

4031 }

4032

4033

4035 return I;

4036

4037

4038

4039

4041}

4042

4047

4048

4049 if (II->hasOneUse())

4050 return nullptr;

4051

4052

4053

4054

4055

4056

4057

4058

4059

4060

4061

4062

4063

4064

4065 Value *Op0 = II->getOperand(0);

4066 Value *Op1 = II->getOperand(1);

4067

4068 const APInt *COp1;

4069

4070

4072 return nullptr;

4073

4075 switch (II->getIntrinsicID()) {

4076 default:

4078 "This function only works with usub_sat and uadd_sat for now!");

4079 case Intrinsic::uadd_sat:

4081 break;

4082 case Intrinsic::usub_sat:

4084 break;

4085 }

4086

4087

4089

4090

4092 II->getBinaryOp(), *COp1, II->getNoWrapKind());

4093

4094

4095 if (SatValCheck)

4097

4099 if (II->getBinaryOp() == Instruction::Add)

4100 C2 = C2.sub(*COp1);

4101 else

4102 C2 = C2.add(*COp1);

4103

4105 SatValCheck ? Instruction::BinaryOps::Or : Instruction::BinaryOps::And;

4106

4107 std::optional Combination;

4108 if (CombiningOp == Instruction::BinaryOps::Or)

4110 else

4112

4113 if (!Combination)

4114 return nullptr;

4115

4118 APInt EquivOffset;

4119

4120 Combination->getEquivalentICmp(EquivPred, EquivInt, EquivOffset);

4121

4123 EquivPred,

4124 Builder.CreateAdd(Op0, ConstantInt::get(Op1->getType(), EquivOffset)),

4125 ConstantInt::get(Op1->getType(), EquivInt));

4126}

4127

4132 std::optionalICmpInst::Predicate NewPredicate = std::nullopt;

4133 switch (Pred) {

4136 if (C.isZero())

4137 NewPredicate = Pred;

4138 else if (C.isOne())

4139 NewPredicate =

4141 else if (C.isAllOnes())

4142 NewPredicate =

4144 break;

4145

4147 if (C.isAllOnes())

4149 else if (C.isZero())

4151 break;

4152

4154 if (C.isZero())

4156 else if (C.isOne())

4158 break;

4159

4161 if (C.ugt(1))

4163 break;

4164

4166 if (C.isZero() && C.isAllOnes())

4168 break;

4169

4170 default:

4171 break;

4172 }

4173

4174 if (!NewPredicate)

4175 return nullptr;

4176

4177 if (I->getIntrinsicID() == Intrinsic::scmp)

4182}

4183

4184

4189

4190

4191 switch (II->getIntrinsicID()) {

4192 default:

4193 break;

4194 case Intrinsic::uadd_sat:

4195 case Intrinsic::usub_sat:

4198 return Folded;

4199 break;

4200 case Intrinsic::ctpop: {

4203 return R;

4204 } break;

4205 case Intrinsic::scmp:

4206 case Intrinsic::ucmp:

4208 return Folded;

4209 break;

4210 }

4211

4212 if (Cmp.isEquality())

4214

4215 Type *Ty = II->getType();

4216 unsigned BitWidth = C.getBitWidth();

4217 switch (II->getIntrinsicID()) {

4218 case Intrinsic::ctpop: {

4219

4220 Value *X = II->getArgOperand(0);

4224

4228 break;

4229 }

4230 case Intrinsic::ctlz: {

4231

4233 unsigned Num = C.getLimitedValue();

4236 II->getArgOperand(0), ConstantInt::get(Ty, Limit));

4237 }

4238

4239

4241 unsigned Num = C.getLimitedValue();

4244 II->getArgOperand(0), ConstantInt::get(Ty, Limit));

4245 }

4246 break;

4247 }

4248 case Intrinsic::cttz: {

4249

4250 if (II->hasOneUse())

4251 return nullptr;

4252

4253

4257 Builder.CreateAnd(II->getArgOperand(0), Mask),

4259 }

4260

4261

4265 Builder.CreateAnd(II->getArgOperand(0), Mask),

4267 }

4268 break;

4269 }

4270 case Intrinsic::ssub_sat:

4271

4273 if (C.isZero())

4274 return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1));

4275

4278 II->getArgOperand(1));

4279

4282 II->getArgOperand(1));

4283 }

4284 break;

4285 default:

4286 break;

4287 }

4288

4289 return nullptr;

4290}

4291

4292

4294 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

4297 if (!RHSC || !LHSI)

4298 return nullptr;

4299

4301 case Instruction::IntToPtr:

4302

4308 break;

4309

4310 case Instruction::Load:

4311

4316 return Res;

4317 break;

4318 }

4319

4320 return nullptr;

4321}

4322

4325

4326

4327 auto SimplifyOp = [&](Value *Op, bool SelectCondIsTrue) -> Value * {

4329 return Res;

4331 SI->getCondition(), Pred, Op, RHS, DL, SelectCondIsTrue))

4332 return ConstantInt::get(I.getType(), *Impl);

4333 return nullptr;

4334 };

4335

4337 Value *Op1 = SimplifyOp(SI->getOperand(1), true);

4338 if (Op1)

4340

4341 Value *Op2 = SimplifyOp(SI->getOperand(2), false);

4342 if (Op2)

4344

4345 auto Simplifies = [&](Value *Op, unsigned Idx) {

4346

4347 const APInt *Dummy;

4348 return Op ||

4350 SI->getOperand(Idx)->hasOneUse() && match(RHS, m_APInt(Dummy)));

4351 };

4352

4353

4354

4355

4356

4357

4358

4359

4360 bool Transform = false;

4361 if (Op1 && Op2)

4362 Transform = true;

4363 else if (Simplifies(Op1, 1) || Simplifies(Op2, 2)) {

4364

4365 if (SI->hasOneUse())

4366 Transform = true;

4367

4368 else if (CI && !CI->isZero())

4369

4370

4371

4373 }

4374 if (Transform) {

4375 if (!Op1)

4376 Op1 = Builder.CreateICmp(Pred, SI->getOperand(1), RHS, I.getName());

4377 if (!Op2)

4378 Op2 = Builder.CreateICmp(Pred, SI->getOperand(2), RHS, I.getName());

4380 }

4381

4382 return nullptr;

4383}

4384

4385

4387 unsigned Depth = 0) {

4389 return true;

4390 if (V->getType()->getScalarSizeInBits() == 1)

4391 return true;

4393 return false;

4396 if (I)

4397 return false;

4398 switch (I->getOpcode()) {

4399 case Instruction::ZExt:

4400

4402 case Instruction::SExt:

4403

4404

4406 case Instruction::And:

4407 case Instruction::Or:

4408

4409

4410

4411

4414 case Instruction::Xor:

4417

4418

4419 if (Not)

4421

4422 else

4424 case Instruction::Select:

4425

4428 case Instruction::Shl:

4429

4431 case Instruction::LShr:

4432

4434 case Instruction::AShr:

4435

4436

4438 case Instruction::Add:

4439

4443 break;

4444 case Instruction::Sub:

4445

4446 if (Not && match(I->getOperand(0), m_Zero()))

4449 break;

4450 case Instruction::Call: {

4452 switch (II->getIntrinsicID()) {

4453

4454

4455 case Intrinsic::umax:

4456 case Intrinsic::smax:

4457 case Intrinsic::umin:

4458 case Intrinsic::smin:

4461

4462

4463 case Intrinsic::bitreverse:

4465 default:

4466 break;

4467 }

4468 }

4469 break;

4470 }

4471 default:

4472 break;

4473 }

4474 return false;

4475}

4476

4477

4478

4479

4480

4481

4482

4483

4484

4485

4486

4487

4488

4489

4490

4491

4492

4496

4498 switch (Pred) {

4500

4501

4502

4503

4504

4505

4507 break;

4509

4510

4511

4512

4513

4514

4516 break;

4518

4519

4520

4521

4523 break;

4525

4526

4527

4528

4530 break;

4532

4533

4534

4535

4537 break;

4539

4540

4541

4542

4544 break;

4545 default:

4546

4547

4548 return nullptr;

4549 }

4550

4552

4553 auto IsLowBitMask = [&]() {

4555 X = Op1;

4556

4560 }

4561

4562

4565 }

4566 return false;

4567 }

4570

4571 auto Check = [&]() {

4572

4574 if (Value *NotX =

4576 X = NotX;

4577 return true;

4578 }

4579 }

4580 return false;

4581 };

4583 return true;

4586 }

4589 auto Check = [&]() {

4590

4592 if (Value *NotM =

4594 M = NotM;

4595 return true;

4596 }

4597 }

4598 return false;

4599 };

4601 return true;

4604 }

4605 return false;

4606 };

4607

4608 if (!IsLowBitMask())

4609 return nullptr;

4610

4612}

4613

4614

4615

4616

4617

4618

4619

4620

4621

4627 const APInt *C0, *C1;

4628

4633 return nullptr;

4634

4635

4636

4637

4638

4639

4640

4641

4642 if (*C0 != *C1)

4643 return nullptr;

4644 const APInt &MaskedBits = *C0;

4645 assert(MaskedBits != 0 && "shift by zero should be folded away already.");

4646

4648 switch (SrcPred) {

4650

4651

4652

4654 break;

4656

4657

4658

4660 break;

4661

4662 default:

4663 return nullptr;

4664 }

4665

4666 auto *XType = X->getType();

4667 const unsigned XBitWidth = XType->getScalarSizeInBits();

4669 assert(BitWidth.ugt(MaskedBits) && "shifts should leave some bits untouched");

4670

4671

4674

4675 const APInt ICmpCst = APInt(XBitWidth, 1).shl(KeptBits);

4677

4678 const APInt AddCst = ICmpCst.lshr(1);

4680

4681

4682 Value *T0 = Builder.CreateAdd(X, ConstantInt::get(XType, AddCst));

4683

4684 Value *T1 = Builder.CreateICmp(DstPred, T0, ConstantInt::get(XType, ICmpCst));

4685

4686 return T1;

4687}

4688

4689

4690

4691

4692

4693

4694

4695

4699 if (I.isEquality() || match(I.getOperand(1), m_Zero()) ||

4700 I.getOperand(0)->hasOneUse())

4701 return nullptr;

4702

4704

4705

4706

4707 Instruction *XShift, *MaybeTruncation, *YShift;

4709 I.getOperand(0),

4714 return nullptr;

4715

4716

4717

4719

4720

4722

4723 Type *WidestTy = WidestShift->getType();

4724 Type *NarrowestTy = NarrowestShift->getType();

4725 assert(NarrowestTy == I.getOperand(0)->getType() &&

4726 "We did not look past any shifts while matching XShift though.");

4727 bool HadTrunc = WidestTy != I.getOperand(0)->getType();

4728

4729

4732

4733

4734 auto XShiftOpcode = XShift->getOpcode();

4735 if (XShiftOpcode == YShift->getOpcode())

4736 return nullptr;

4737

4738 Value *X, *XShAmt, *Y, *YShAmt;

4741

4742

4743

4744

4746

4747 if (match(I.getOperand(0),

4749 return nullptr;

4750 if (HadTrunc) {

4751

4752

4753 if (!MaybeTruncation->hasOneUse() &&

4755 return nullptr;

4756 }

4757 }

4758

4759

4760

4762 return nullptr;

4763

4764

4765

4766

4767

4768

4769

4770

4771

4772

4773 unsigned MaximalPossibleTotalShiftAmount =

4776 APInt MaximalRepresentableShiftAmount =

4778 if (MaximalRepresentableShiftAmount.ult(MaximalPossibleTotalShiftAmount))

4779 return nullptr;

4780

4781

4785 if (!NewShAmt)

4786 return nullptr;

4787 if (NewShAmt->getType() != WidestTy) {

4788 NewShAmt =

4790 if (!NewShAmt)

4791 return nullptr;

4792 }

4794

4795

4796

4797 if (match(NewShAmt,

4799 APInt(WidestBitWidth, WidestBitWidth))))

4800 return nullptr;

4801

4802

4804 auto CanFold = [NewShAmt, WidestBitWidth, NarrowestShift, SQ,

4805 WidestShift]() {

4806

4807

4808

4810 ? NewShAmt->getSplatValue()

4811 : NewShAmt;

4812

4813 if (NewShAmtSplat &&

4816 return true;

4817

4818

4822

4823 unsigned MaxActiveBits = Known.getBitWidth() - MinLeadZero;

4824 if (MaxActiveBits <= 1)

4825 return true;

4826

4827 if (NewShAmtSplat && NewShAmtSplat->getUniqueInteger().ule(MinLeadZero))

4828 return true;

4829 }

4833

4834 unsigned MaxActiveBits = Known.getBitWidth() - MinLeadZero;

4835 if (MaxActiveBits <= 1)

4836 return true;

4837

4838 if (NewShAmtSplat) {

4839 APInt AdjNewShAmt =

4841 if (AdjNewShAmt.ule(MinLeadZero))

4842 return true;

4843 }

4844 }

4845 return false;

4846 };

4847 if (!CanFold())

4848 return nullptr;

4849 }

4850

4851

4852 X = Builder.CreateZExt(X, WidestTy);

4853 Y = Builder.CreateZExt(Y, WidestTy);

4854

4855 Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr

4856 ? Builder.CreateLShr(X, NewShAmt)

4857 : Builder.CreateShl(X, NewShAmt);

4858 Value *T1 = Builder.CreateAnd(T0, Y);

4859 return Builder.CreateICmp(I.getPredicate(), T1,

4861}

4862

4863

4864

4865

4866

4867

4868

4869

4875 bool NeedNegation;

4876

4877 if (I.isEquality() &&

4882 Mul = nullptr;

4883

4884

4885 switch (Pred) {

4887 NeedNegation = false;

4888 break;

4890 NeedNegation = true;

4891 break;

4892 default:

4893 return nullptr;

4894 }

4895 } else

4896 if (I.isEquality() &&

4905 } else

4906 return nullptr;

4907

4909

4910

4911 bool MulHadOtherUses = Mul && Mul->hasOneUse();

4912 if (MulHadOtherUses)

4914

4916 Div->getOpcode() == Instruction::UDiv ? Intrinsic::umul_with_overflow

4917 : Intrinsic::smul_with_overflow,

4918 X->getType(), {X, Y}, nullptr, "mul");

4919

4920

4921

4922

4923 if (MulHadOtherUses)

4925

4927 if (NeedNegation)

4928 Res = Builder.CreateNot(Res, "mul.not.ov");

4929

4930

4931

4932 if (MulHadOtherUses)

4934

4935 return Res;

4936}

4937

4943

4948

4949

4952 }

4953

4954

4955

4958 Type *Ty = X->getType();

4962 Value *And = Builder.CreateAnd(X, MaxSignedVal);

4965 }

4966

4967 return nullptr;

4968}

4969

4972 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A;

4973

4978 }

4979

4981 return nullptr;

4982

4983

4986

4987

4990

4992

4993

4994

4996 if (auto *NotOp1 =

5000

5004 }

5005

5007 return nullptr;

5008

5010

5013

5015 return nullptr;

5016

5018

5019

5022

5024

5025

5028

5029 return nullptr;

5030}

5031

5034 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A;

5035

5036

5042 return nullptr;

5043 }

5044

5045

5048

5049

5052

5054

5059

5063 }

5064 return nullptr;

5065}

5066

5069 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *A;

5070

5075 }

5077 return nullptr;

5078

5079

5080

5081

5082

5085 return new ICmpInst(PredOut, Op0, Op1);

5086

5087

5088

5089

5093 default:

5094 return nullptr;

5098 break;

5102 break;

5103 }

5105 return new ICmpInst(NewPred, Op0, Const);

5106 }

5107

5108 return nullptr;

5109}

5110

5111

5112

5114 if (C.isOne())

5115 return true;

5116

5117 if (C.isPowerOf2())

5118 return false;

5119

5121}

5122

5123

5124

5125

5126

5130 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

5131

5132

5135 if (!BO0 && !BO1)

5136 return nullptr;

5137

5139 return NewICmp;

5140

5143

5144

5145

5149

5153

5154 {

5155

5162 }

5163

5169 }

5170 }

5171

5172

5173

5177

5182 }

5183

5184 {

5185

5186

5187

5188

5189

5198 return new ICmpInst(NewPred, Op1, Zero);

5199 }

5200

5207 return new ICmpInst(NewPred, Op0, Zero);

5208 }

5209 }

5210

5211 bool NoOp0WrapProblem = false, NoOp1WrapProblem = false;

5212 bool Op0HasNUW = false, Op1HasNUW = false;

5213 bool Op0HasNSW = false, Op1HasNSW = false;

5214

5215

5217 bool &HasNSW, bool &HasNUW) -> bool {

5224 } else if (BO.getOpcode() == Instruction::Or) {

5225 HasNUW = true;

5226 HasNSW = true;

5227 return true;

5228 } else {

5229 return false;

5230 }

5231 };

5232 Value *A = nullptr, *B = nullptr, *C = nullptr, *D = nullptr;

5233

5234 if (BO0) {

5236 NoOp0WrapProblem = hasNoWrapProblem(*BO0, Pred, Op0HasNSW, Op0HasNUW);

5237 }

5238 if (BO1) {

5240 NoOp1WrapProblem = hasNoWrapProblem(*BO1, Pred, Op1HasNSW, Op1HasNUW);

5241 }

5242

5243

5244

5245 if ((A == Op1 || B == Op1) && NoOp0WrapProblem)

5246 return new ICmpInst(Pred, A == Op1 ? B : A,

5248

5249

5250

5251 if ((C == Op0 || D == Op0) && NoOp1WrapProblem)

5253 C == Op0 ? D : C);

5254

5255

5256 if (A && C && (A == C || A == D || B == C || B == D) && NoOp0WrapProblem &&

5257 NoOp1WrapProblem) {

5258

5260 if (A == C) {

5261

5262 Y = B;

5263 Z = D;

5264 } else if (A == D) {

5265

5266 Y = B;

5267 Z = C;

5268 } else if (B == C) {

5269

5270 Y = A;

5271 Z = D;

5272 } else {

5274

5275 Y = A;

5276 Z = C;

5277 }

5278 return new ICmpInst(Pred, Y, Z);

5279 }

5280

5282

5283

5285 bool IsNegative) -> bool {

5286 const APInt *OffsetC;

5288 return false;

5289

5290

5291 if (IsNegative ? OffsetC->isAllOnes() : OffsetC->isOne())

5292 return true;

5293

5295 if (IsNegative)

5296 C.negate();

5297

5298 if (C.isStrictlyPositive())

5299 return false;

5300

5302 };

5303

5304

5305

5306

5307

5308

5309

5310

5311

5312

5313

5314

5315

5316

5317

5318

5319 if (A && NoOp0WrapProblem &&

5320 ShareCommonDivisor(A, Op1, B,

5323 Op1);

5324

5325

5326

5327

5328

5329

5330

5331 if (C && NoOp1WrapProblem &&

5332 ShareCommonDivisor(Op0, C, D,

5335 C);

5336 }

5337

5338

5339

5340

5341

5342

5343

5344

5345 if (A && C && NoOp0WrapProblem && NoOp1WrapProblem &&

5347 const APInt *AP1, *AP2;

5348

5349

5355 if (AP1Abs.uge(AP2Abs)) {

5356 APInt Diff = *AP1 - *AP2;

5359 A, C3, "", Op0HasNUW && Diff.ule(*AP1), Op0HasNSW);

5360 return new ICmpInst(Pred, NewAdd, C);

5361 } else {

5362 APInt Diff = *AP2 - *AP1;

5365 C, C3, "", Op1HasNUW && Diff.ule(*AP2), Op1HasNSW);

5366 return new ICmpInst(Pred, A, NewAdd);

5367 }

5368 }

5374 return new ICmpInst(Pred, A, NewAdd);

5375 }

5376 }

5377

5378

5379

5380 A = nullptr;

5381 B = nullptr;

5382 C = nullptr;

5383 D = nullptr;

5384 if (BO0 && BO0->getOpcode() == Instruction::Sub) {

5387 }

5388 if (BO1 && BO1->getOpcode() == Instruction::Sub) {

5391 }

5392

5393

5394 if (A == Op1 && NoOp0WrapProblem)

5396

5397 if (C == Op0 && NoOp1WrapProblem)

5399

5400

5401

5404

5407

5411

5415

5416

5417 if (B && D && B == D && NoOp0WrapProblem && NoOp1WrapProblem)

5419

5420

5421 if (A && C && A == C && NoOp0WrapProblem && NoOp1WrapProblem)

5423

5424

5429 if (RHSC->isNotMinSignedValue())

5430 return new ICmpInst(I.getSwappedPredicate(), X,

5432 }

5433

5435 return R;

5437 return R;

5438

5439 {

5440

5441

5448 if (Op0HasNSW && Op1HasNSW) {

5455 SQ.getWithInstruction(&I));

5456 if (LessThan && match(LessThan, m_One()))

5460 SQ.getWithInstruction(&I));

5461 if (GreaterThan && match(GreaterThan, m_One()))

5463 }

5464 } else {

5465 bool NonZero;

5467

5468 if (((Op0HasNSW && Op1HasNSW) || (Op0HasNUW && Op1HasNUW)) &&

5471

5473

5474

5478

5479

5480 if (NonZero && BO0 && BO1 && Op0HasNSW && Op1HasNSW)

5482 } else

5484

5485

5486

5487 if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)

5489 }

5490 }

5491 }

5492

5494

5495 if (BO0 && BO0->getOpcode() == Instruction::SRem && Op1 == BO0->getOperand(1))

5496 SRem = BO0;

5497

5498 else if (BO1 && BO1->getOpcode() == Instruction::SRem &&

5500 SRem = BO1;

5501 if (SRem) {

5502

5503

5505 default:

5506 break;

5519 }

5520 }

5521

5526 default:

5527 break;

5528 case Instruction::Add:

5529 case Instruction::Sub:

5530 case Instruction::Xor: {

5531 if (I.isEquality())

5533

5536

5537 if (C->isSignMask()) {

5540 }

5541

5542

5543 if (BO0->getOpcode() == Instruction::Xor && C->isMaxSignedValue()) {

5545 NewPred = I.getSwappedPredicate(NewPred);

5547 }

5548 }

5549 break;

5550 }

5551 case Instruction::Mul: {

5552 if (I.isEquality())

5553 break;

5554

5557 C->isOne()) {

5558

5559

5560 if (unsigned TZs = C->countr_zero()) {

5561 Constant *Mask = ConstantInt::get(

5566 return new ICmpInst(Pred, And1, And2);

5567 }

5568 }

5569 break;

5570 }

5571 case Instruction::UDiv:

5572 case Instruction::LShr:

5574 break;

5576

5577 case Instruction::SDiv:

5580 break;

5582

5583 case Instruction::AShr:

5585 break;

5587

5588 case Instruction::Shl: {

5589 bool NUW = Op0HasNUW && Op1HasNUW;

5590 bool NSW = Op0HasNSW && Op1HasNSW;

5591 if (!NUW && !NSW)

5592 break;

5593 if (!NSW && I.isSigned())

5594 break;

5596 }

5597 }

5598 }

5599

5600 if (BO0) {

5601

5604

5608 }

5609 }

5610

5611

5612

5613

5621 }

5622

5625

5627 return R;

5628

5631

5634

5635 return nullptr;

5636}

5637

5638

5645 return nullptr;

5647

5648

5649

5653 } else

5654 return nullptr;

5655 }

5657 auto IsCondKnownTrue = [](Value *Val) -> std::optional {

5658 if (!Val)

5659 return std::nullopt;

5661 return true;

5663 return false;

5664 return std::nullopt;

5665 };

5666

5667

5668

5669

5670 Pred = Pred.dropSameSign();

5673 if (!CmpXZ.has_value() && !CmpYZ.has_value())

5674 return nullptr;

5675 if (!CmpXZ.has_value()) {

5678 }

5679

5680 auto FoldIntoCmpYZ = [&]() -> Instruction * {

5681 if (CmpYZ.has_value())

5684 };

5685

5686 switch (Pred) {

5689

5690

5691

5692

5693

5694

5701 }

5702

5704 auto MinMaxCmpXZ = IsCondKnownTrue(simplifyICmpInst(NewPred, X, Z, Q));

5705 if (!MinMaxCmpXZ.has_value()) {

5708

5709 if (!CmpXZ.has_value() || (Pred == ICmpInst::ICMP_EQ) == *CmpXZ)

5710 break;

5711 MinMaxCmpXZ = IsCondKnownTrue(simplifyICmpInst(NewPred, X, Z, Q));

5712 }

5713 if (!MinMaxCmpXZ.has_value())

5714 break;

5715 if (*MinMaxCmpXZ) {

5716

5717

5718

5719

5720

5723 } else {

5724

5725

5726

5727

5728

5729 return FoldIntoCmpYZ();

5730 }

5731 break;

5732 }

5742 if (*CmpXZ) {

5743 if (IsSame) {

5744

5745

5746

5747

5748

5750 } else {

5751

5752

5753

5754

5755

5756 return FoldIntoCmpYZ();

5757 }

5758 } else {

5759 if (IsSame) {

5760

5761

5762

5763

5764

5765 return FoldIntoCmpYZ();

5766 } else {

5767

5768

5769

5770

5771

5773 }

5774 }

5775 break;

5776 }

5777 default:

5778 break;

5779 }

5780

5781 return nullptr;

5782}

5783

5784

5785

5786

5787

5788

5789

5790

5791

5794 if (I.isEquality() || !Min->hasOneUse() || !Min->isMin())

5795 return nullptr;

5796

5797 const APInt *Lo = nullptr, *Hi = nullptr;

5801 return nullptr;

5802 } else {

5805 return nullptr;

5806 }

5807

5813 else

5815

5816 if (Offset.isZero())

5817 X = Builder.CreateAdd(X, ConstantInt::get(X->getType(), Offset));

5818

5820 I, Builder.CreateICmp(Pred, X, ConstantInt::get(X->getType(), C)));

5821}

5822

5823

5826 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

5829 bool CheckIs;

5830 if (I.isEquality()) {

5831

5832

5836 A = nullptr;

5837

5838

5839

5841 A = Op1;

5842 else if (match(Op1,

5844 A = Op0;

5845

5848

5849

5850

5854 A = Op1;

5859 A = Op0;

5861 }

5862 }

5863

5864 if (A) {

5865 Type *Ty = A->getType();

5866 CallInst *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop, A);

5868 ConstantInt::get(Ty, 2))

5870 ConstantInt::get(Ty, 1));

5871 }

5872

5873 return nullptr;

5874}

5875

5876

5877using OffsetOp = std::pair<Instruction::BinaryOps, Value *>;

5879 bool AllowRecursion) {

5881 if (!Inst || !Inst->hasOneUse())

5882 return;

5883

5885 case Instruction::Add:

5886 Offsets.emplace_back(Instruction::Sub, Inst->getOperand(1));

5887 Offsets.emplace_back(Instruction::Sub, Inst->getOperand(0));

5888 break;

5889 case Instruction::Sub:

5890 Offsets.emplace_back(Instruction::Add, Inst->getOperand(1));

5891 break;

5892 case Instruction::Xor:

5893 Offsets.emplace_back(Instruction::Xor, Inst->getOperand(1));

5894 Offsets.emplace_back(Instruction::Xor, Inst->getOperand(0));

5895 break;

5896 case Instruction::Shl:

5898 Offsets.emplace_back(Instruction::AShr, Inst->getOperand(1));

5900 Offsets.emplace_back(Instruction::LShr, Inst->getOperand(1));

5901 break;

5902 case Instruction::Select:

5903 if (AllowRecursion) {

5906 }

5907 break;

5908 default:

5909 break;

5910 }

5911}

5912

5914

5918

5930 switch (Kind) {

5934 return V0;

5936 return Builder.CreateSelect(V0, V1, V2);

5937 }

5939 }

5940};

5941

5942

5943

5944

5948 assert(I.isEquality() && "Expected an equality icmp");

5949 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

5951 return nullptr;

5952

5954 collectOffsetOp(Op0, OffsetOps, true);

5955 collectOffsetOp(Op1, OffsetOps, true);

5956

5957 auto ApplyOffsetImpl = [&](Value *V, unsigned BinOpc, Value *RHS) -> Value * {

5958 switch (BinOpc) {

5959

5960 case Instruction::AShr: {

5961 const APInt *CV, *CRHS;

5963 CV->ashr(*CRHS).shl(*CRHS) == *CV) &&

5965 return nullptr;

5966 break;

5967 }

5968

5969 case Instruction::LShr: {

5970 const APInt *CV, *CRHS;

5972 CV->lshr(*CRHS).shl(*CRHS) == *CV) &&

5974 return nullptr;

5975 break;

5976 }

5977 default:

5978 break;

5979 }

5980

5982 if (!Simplified)

5983 return nullptr;

5984

5986 return nullptr;

5987

5989 };

5990

5991 auto ApplyOffset = [&](Value *V, unsigned BinOpc,

5994 if (!Sel->hasOneUse())

5996 Value *TrueVal = ApplyOffsetImpl(Sel->getTrueValue(), BinOpc, RHS);

5997 if (!TrueVal)

5999 Value *FalseVal = ApplyOffsetImpl(Sel->getFalseValue(), BinOpc, RHS);

6000 if (!FalseVal)

6003 }

6004 if (Value *Simplified = ApplyOffsetImpl(V, BinOpc, RHS))

6007 };

6008

6009 for (auto [BinOp, RHS] : OffsetOps) {

6010 auto BinOpc = static_cast<unsigned>(BinOp);

6011

6012 auto Op0Result = ApplyOffset(Op0, BinOpc, RHS);

6013 if (!Op0Result.isValid())

6014 continue;

6015 auto Op1Result = ApplyOffset(Op1, BinOpc, RHS);

6016 if (!Op1Result.isValid())

6017 continue;

6018

6019 Value *NewLHS = Op0Result.materialize(Builder);

6020 Value *NewRHS = Op1Result.materialize(Builder);

6021 return new ICmpInst(I.getPredicate(), NewLHS, NewRHS);

6022 }

6023

6024 return nullptr;

6025}

6026

6028 if (I.isEquality())

6029 return nullptr;

6030

6031 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

6035 if (A == Op1 || B == Op1) {

6036 Value *OtherVal = A == Op1 ? B : A;

6038 }

6039

6041

6044 Op1->hasOneUse()) {

6048 }

6049

6050

6051 if (A == C)

6053 if (A == D)

6055 if (B == C)

6057 if (B == D)

6059 }

6060 }

6061

6063

6064 Value *OtherVal = A == Op0 ? B : A;

6066 }

6067

6068

6071 Value *X = nullptr, *Y = nullptr, *Z = nullptr;

6072

6073 if (A == C) {

6074 X = B;

6075 Y = D;

6076 Z = A;

6077 } else if (A == D) {

6078 X = B;

6079 Y = C;

6080 Z = A;

6081 } else if (B == C) {

6082 X = A;

6083 Y = D;

6084 Z = B;

6085 } else if (B == D) {

6086 X = A;

6087 Y = C;

6088 Z = B;

6089 }

6090

6091 if (X) {

6092

6093

6094

6095 const APInt *C0, *C1;

6097 (*C0 ^ *C1).isNegatedPowerOf2();

6098

6099

6100

6101

6102 int UseCnt =

6103 int(Op0->hasOneUse()) + int(Op1->hasOneUse()) +

6105 if (XorIsNegP2 || UseCnt >= 2) {

6106

6108 Op1 = Builder.CreateAnd(Op1, Z);

6110 }

6111 }

6112 }

6113

6114 {

6115

6116

6124 }

6125 }

6126

6128 (Op0->hasOneUse() || Op1->hasOneUse())) {

6129

6130

6131 const APInt *MaskC;

6133 MaskC->countr_one() == A->getType()->getScalarSizeInBits())

6135 }

6136

6137

6138

6139 const APInt *AP1, *AP2;

6144 if (*AP1 != *AP2)

6145 return nullptr;

6148 if (ShAmt < TypeBits && ShAmt != 0) {

6153 return new ICmpInst(NewPred, Xor, ConstantInt::get(A->getType(), CmpVal));

6154 }

6155 }

6156

6157

6161 unsigned TypeBits = Cst1->getBitWidth();

6163 if (ShAmt < TypeBits && ShAmt != 0) {

6167 Builder.CreateAnd(Xor, Builder.getInt(AndVal), I.getName() + ".mask");

6169 }

6170 }

6171

6172

6173

6178

6179

6180 A->hasOneUse()) {

6181 unsigned ASize = cast(A->getType())->getPrimitiveSizeInBits();

6182

6183 if (ShAmt < ASize) {

6186 MaskV <<= ShAmt;

6187

6189 CmpV <<= ShAmt;

6190

6193 }

6194 }

6195

6197 return ICmp;

6198

6199

6200

6201

6202

6206 A->getType()->getScalarSizeInBits() == BitWidth * 2 &&

6207 (I.getOperand(0)->hasOneUse() || I.getOperand(1)->hasOneUse())) {

6209 Value *Add = Builder.CreateAdd(A, ConstantInt::get(A->getType(), C));

6212 Add, ConstantInt::get(A->getType(), C.shl(1)));

6213 }

6214

6215

6216

6217

6218

6223

6228

6229

6230

6231

6232

6233

6238 Pred, A,

6239 Builder.CreateIntrinsic(Op0->getType(), Intrinsic::fshl, {A, A, B}));

6240

6241

6242

6247

6248 {

6249

6250 auto m_Matcher =

6254 std::optional IsZero = std::nullopt;

6257 IsZero = false;

6258

6261 IsZero = true;

6262

6264

6265

6266

6267

6269 *IsZero ? A

6271 }

6272

6275 return Res;

6276

6277 return nullptr;

6278}

6279

6283

6284

6285

6289 return nullptr;

6290

6291

6292

6294 true)) {

6296 Constant *C = ConstantInt::get(Res->X->getType(), Res->C);

6298 }

6299

6300 unsigned SrcBits = X->getType()->getScalarSizeInBits();

6302 if (II->getIntrinsicID() == Intrinsic::cttz ||

6303 II->getIntrinsicID() == Intrinsic::ctlz) {

6304 unsigned MaxRet = SrcBits;

6305

6306

6307

6309 MaxRet--;

6310

6311

6312

6316 return I;

6317 }

6318 }

6319

6320 return nullptr;

6321}

6322

6328 return nullptr;

6329

6330 bool IsSignedExt = CastOp0->getOpcode() == Instruction::SExt;

6331 bool IsSignedCmp = ICmp.isSigned();

6332

6333

6338

6339 if (IsZext0 != IsZext1) {

6340

6341

6342

6343

6344 if (ICmp.isEquality() && X->getType()->isIntOrIntVectorTy(1) &&

6345 Y->getType()->isIntOrIntVectorTy(1))

6348

6349

6350

6351

6354

6355 bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();

6356 bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();

6357

6358 if ((IsZext0 && IsNonNeg0) || (IsZext1 && IsNonNeg1))

6359 IsSignedExt = true;

6360 else

6361 return nullptr;

6362 }

6363

6364

6365 Type *XTy = X->getType(), *YTy = Y->getType();

6366 if (XTy != YTy) {

6367

6369 return nullptr;

6370

6372 IsSignedExt ? Instruction::SExt : Instruction::ZExt;

6374 X = Builder.CreateCast(CastOpcode, X, YTy);

6376 Y = Builder.CreateCast(CastOpcode, Y, XTy);

6377 else

6378 return nullptr;

6379 }

6380

6381

6382

6385

6386

6387

6388 if (IsSignedCmp && IsSignedExt)

6390

6391

6393 }

6394

6395

6397 if (C)

6398 return nullptr;

6399

6400

6401 Type *SrcTy = CastOp0->getSrcTy();

6403 if (Res) {

6406

6407

6408

6409 if (IsSignedExt && IsSignedCmp)

6411

6412

6414 }

6415

6416

6417

6418

6419

6420

6422 return nullptr;

6423

6424

6425

6428

6429

6430

6433}

6434

6435

6437

6438

6439

6440 Value *SimplifiedOp0 = simplifyIntToPtrRoundTripCast(ICmp.getOperand(0));

6441 Value *SimplifiedOp1 = simplifyIntToPtrRoundTripCast(ICmp.getOperand(1));

6442 if (SimplifiedOp0 || SimplifiedOp1)

6444 SimplifiedOp0 ? SimplifiedOp0 : ICmp.getOperand(0),

6445 SimplifiedOp1 ? SimplifiedOp1 : ICmp.getOperand(1));

6446

6448 if (!CastOp0)

6449 return nullptr;

6451 return nullptr;

6452

6453 Value *Op0Src = CastOp0->getOperand(0);

6454 Type *SrcTy = CastOp0->getSrcTy();

6455 Type *DestTy = CastOp0->getDestTy();

6456

6457

6458

6459 auto CompatibleSizes = [&](Type *PtrTy, Type *IntTy) {

6463 }

6464 return DL.getPointerTypeSizeInBits(PtrTy) == IntTy->getIntegerBitWidth();

6465 };

6466 if (CastOp0->getOpcode() == Instruction::PtrToInt &&

6467 CompatibleSizes(SrcTy, DestTy)) {

6468 Value *NewOp1 = nullptr;

6470 Value *PtrSrc = PtrToIntOp1->getOperand(0);

6472 NewOp1 = PtrToIntOp1->getOperand(0);

6475 }

6476

6477 if (NewOp1)

6479 }

6480

6481

6482 if (CastOp0->getOpcode() == Instruction::IntToPtr &&

6483 CompatibleSizes(DestTy, SrcTy)) {

6484 Value *NewOp1 = nullptr;

6486 Value *IntSrc = IntToPtrOp1->getOperand(0);

6488 NewOp1 = IntToPtrOp1->getOperand(0);

6491 }

6492

6493 if (NewOp1)

6495 }

6496

6498 return R;

6499

6501}

6502

6504 bool IsSigned) {

6505 switch (BinaryOp) {

6506 default:

6508 case Instruction::Add:

6509 case Instruction::Sub:

6511 case Instruction::Mul:

6512 return !(RHS->getType()->isIntOrIntVectorTy(1) && IsSigned) &&

6514 }

6515}

6516

6519 bool IsSigned, Value *LHS, Value *RHS,

6521 switch (BinaryOp) {

6522 default:

6524 case Instruction::Add:

6525 if (IsSigned)

6527 else

6529 case Instruction::Sub:

6530 if (IsSigned)

6532 else

6534 case Instruction::Mul:

6535 if (IsSigned)

6537 else

6539 }

6540}

6541

6543 bool IsSigned, Value *LHS,

6549

6550

6551

6552

6553

6554 Builder.SetInsertPoint(&OrigI);

6555

6558 OverflowTy = VectorType::get(OverflowTy, LHSTy->getElementCount());

6559

6561 Result = LHS;

6563 return true;

6564 }

6565

6568 return false;

6571 Result = Builder.CreateBinOp(BinaryOp, LHS, RHS);

6572 Result->takeName(&OrigI);

6574 return true;

6576 Result = Builder.CreateBinOp(BinaryOp, LHS, RHS);

6577 Result->takeName(&OrigI);

6580 if (IsSigned)

6581 Inst->setHasNoSignedWrap();

6582 else

6583 Inst->setHasNoUnsignedWrap();

6584 }

6585 return true;

6586 }

6587

6589}

6590

6591

6592

6593

6594

6595

6596

6597

6598

6599

6600

6601

6602

6603

6604

6606 const APInt *OtherVal,

6608

6609

6611 return nullptr;

6612

6614 if (!MulInstr)

6615 return nullptr;

6616 assert(MulInstr->getOpcode() == Instruction::Mul);

6617

6620 assert(LHS->getOpcode() == Instruction::ZExt);

6621 assert(RHS->getOpcode() == Instruction::ZExt);

6622 Value *A = LHS->getOperand(0), *B = RHS->getOperand(0);

6623

6624

6625 Type *TyA = A->getType(), *TyB = B->getType();

6627 WidthB = TyB->getPrimitiveSizeInBits();

6628 unsigned MulWidth;

6629 Type *MulType;

6630 if (WidthB > WidthA) {

6631 MulWidth = WidthB;

6632 MulType = TyB;

6633 } else {

6634 MulWidth = WidthA;

6635 MulType = TyA;

6636 }

6637

6638

6639

6640

6642 for (User *U : MulVal->users()) {

6643 if (U == &I)

6644 continue;

6646

6647 unsigned TruncWidth = TI->getType()->getPrimitiveSizeInBits();

6648 if (TruncWidth > MulWidth)

6649 return nullptr;

6651

6652 if (BO->getOpcode() != Instruction::And)

6653 return nullptr;

6655 const APInt &CVal = CI->getValue();

6657 return nullptr;

6658 } else {

6659

6660

6661

6662 return nullptr;

6663 }

6664 } else {

6665

6666 return nullptr;

6667 }

6668 }

6669

6670

6671 switch (I.getPredicate()) {

6673

6674

6675

6678 if (MaxVal.eq(*OtherVal))

6679 break;

6680 return nullptr;

6681 }

6682

6684

6685

6686

6688 if (MaxVal.eq(*OtherVal))

6689 break;

6690 return nullptr;

6691 }

6692

6693 default:

6694 return nullptr;

6695 }

6696

6699

6700

6701 Value *MulA = A, *MulB = B;

6702 if (WidthA < MulWidth)

6703 MulA = Builder.CreateZExt(A, MulType);

6704 if (WidthB < MulWidth)

6705 MulB = Builder.CreateZExt(B, MulType);

6707 Builder.CreateIntrinsic(Intrinsic::umul_with_overflow, MulType,

6708 {MulA, MulB}, nullptr, "umul");

6710

6711

6712

6713

6715 Value *Mul = Builder.CreateExtractValue(Call, 0, "umul.value");

6717 if (U == &I)

6718 continue;

6720 if (TI->getType()->getPrimitiveSizeInBits() == MulWidth)

6722 else

6725 assert(BO->getOpcode() == Instruction::And);

6726

6729 Value *ShortAnd = Builder.CreateAnd(Mul, ShortMask);

6730 Value *Zext = Builder.CreateZExt(ShortAnd, BO->getType());

6732 } else {

6734 }

6736 }

6737 }

6738

6739

6740

6742 Value *Res = Builder.CreateExtractValue(Call, 1);

6744 }

6745

6747}

6748

6749

6750

6751

6756

6757

6758

6759 bool UnusedBit;

6762

6763 switch (I.getPredicate()) {

6764

6765

6766

6767

6770

6771

6772

6775

6776 default:

6778 }

6779}

6780

6781

6782

6783

6784

6785

6786

6787

6788

6789

6790

6794 assert(DI && UI && "Instruction not defined\n");

6795

6797 return false;

6798

6800 return false;

6801

6803 return false;

6804 for (const User *U : DI->users()) {

6806 if (Usr != UI && DT.dominates(DB, Usr->getParent()))

6807 return false;

6808 }

6809 return true;

6810}

6811

6812

6815 if (!BB)

6816 return false;

6818 if (!BI || BI->getNumSuccessors() != 2)

6819 return false;

6821 if (!IC || (IC->getOperand(0) != SI && IC->getOperand(1) != SI))

6822 return false;

6823 return true;

6824}

6825

6826

6827

6828

6829

6830

6831

6832

6833

6834

6835

6836

6837

6838

6839

6840

6841

6842

6843

6844

6845

6846

6847

6848

6849

6850

6851

6852

6853

6854

6855

6856

6857

6858

6859

6860

6861

6862

6863

6864

6865

6868 const unsigned SIOpd) {

6869 assert((SIOpd == 1 || SIOpd == 2) && "Invalid select operand!");

6871 BasicBlock *Succ = SI->getParent()->getTerminator()->getSuccessor(1);

6872

6873

6874

6875

6876

6877

6878

6879

6880

6881

6882

6884 NumSel++;

6885 SI->replaceUsesOutsideBlock(SI->getOperand(SIOpd), SI->getParent());

6886 return true;

6887 }

6888 }

6889 return false;

6890}

6891

6892

6893

6895 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

6898

6899

6900 unsigned BitWidth = Ty->isIntOrIntVectorTy()

6901 ? Ty->getScalarSizeInBits()

6902 : DL.getPointerTypeSizeInBits(Ty->getScalarType());

6903

6905 return nullptr;

6906

6909

6910 {

6911

6912

6913

6914 SimplifyQuery Q = SQ.getWithoutDomCondCache().getWithInstruction(&I);

6916 Op0Known, Q))

6917 return &I;

6918

6920 return &I;

6921 }

6922

6929

6930 if (std::optional Res = ICmpInst::compare(Op0Known, Op1Known, Pred))

6932

6933

6934

6935

6938 if (I.isSigned()) {

6943 } else {

6948 }

6949

6950

6951

6952

6953

6954 auto isMinMaxCmp = [&](Instruction &Cmp) {

6955 if (!Cmp.hasOneUse())

6956 return false;

6960 return false;

6963 };

6964 if (!isMinMaxCmp(I)) {

6965 switch (Pred) {

6966 default:

6967 break;

6969 if (Op1Min == Op0Max)

6971 const APInt *CmpC;

6973

6974 if (*CmpC == Op0Min + 1)

6976 ConstantInt::get(Op1->getType(), *CmpC - 1));

6977

6978

6982 }

6983 break;

6984 }

6986 if (Op1Max == Op0Min)

6988 const APInt *CmpC;

6990

6991 if (*CmpC == Op0Max - 1)

6993 ConstantInt::get(Op1->getType(), *CmpC + 1));

6994

6995

6999 }

7000 break;

7001 }

7003 if (Op1Min == Op0Max)

7005 const APInt *CmpC;

7007 if (*CmpC == Op0Min + 1)

7009 ConstantInt::get(Op1->getType(), *CmpC - 1));

7010 }

7011 break;

7012 }

7014 if (Op1Max == Op0Min)

7016 const APInt *CmpC;

7018 if (*CmpC == Op0Max - 1)

7020 ConstantInt::get(Op1->getType(), *CmpC + 1));

7021 }

7022 break;

7023 }

7024 }

7025 }

7026

7027

7028

7029 switch (Pred) {

7030 default:

7031 break;

7034

7035

7036

7037 APInt Op0KnownZeroInverted = ~Op0Known.Zero;

7038 if (Op1Known.isZero()) {

7039

7040 Value *LHS = nullptr;

7041 const APInt *LHSC;

7043 *LHSC != Op0KnownZeroInverted)

7044 LHS = Op0;

7045

7047 const APInt *C1;

7049 Type *XTy = X->getType();

7051 APInt C2 = Op0KnownZeroInverted;

7052 APInt C2Pow2 = (C2 & ~(*C1 - 1)) + *C1;

7054

7055

7056

7058 auto *CmpC = ConstantInt::get(XTy, Log2C2 - Log2C1);

7059 auto NewPred =

7061 return new ICmpInst(NewPred, X, CmpC);

7062 }

7063 }

7064 }

7065

7066

7068 (Op0Known & Op1Known) == Op0Known)

7071 break;

7072 }

7074 if (Op1Min == Op0Max)

7076 break;

7078 if (Op1Max == Op0Min)

7080 break;

7082 if (Op1Min == Op0Max)

7084 break;

7086 if (Op1Max == Op0Min)

7088 break;

7089 }

7090

7091

7092

7093

7094 if ((I.isSigned() || (I.isUnsigned() && I.hasSameSign())) &&

7097 I.setPredicate(I.getUnsignedPredicate());

7098 I.setSameSign();

7099 return &I;

7100 }

7101

7102 return nullptr;

7103}

7104

7105

7106

7110

7111

7112

7115 return BinaryOperator::CreateAnd(Builder.CreateIsNull(X), Y);

7116

7117

7118

7121 return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y);

7122

7123

7132 bool IsSExt = ExtI->getOpcode() == Instruction::SExt;

7134 auto CreateRangeCheck = [&] {

7140 Pred1 == ICmpInst::ICMP_EQ ? Instruction::Or : Instruction::And,

7141 CmpV1, CmpV2);

7142 };

7143 if (C->isZero()) {

7145

7146

7149 } else if (!IsSExt || HasOneUse) {

7150

7151

7152

7153

7154 return CreateRangeCheck();

7155 }

7156 } else if (IsSExt ? C->isAllOnes() : C->isOne()) {

7158

7159

7160

7161

7164 } else if (!IsSExt || HasOneUse) {

7165

7166

7167

7168

7169 return CreateRangeCheck();

7170 }

7171 } else {

7172

7173

7174

7175

7176

7177

7178

7179

7180

7181

7183 Instruction::ICmp, Pred1, X,

7185 ? (IsSExt ? -1 : 1)

7186 : 0));

7187 }

7188 }

7189

7190 return nullptr;

7191}

7192

7193

7194

7195

7200 return nullptr;

7201

7202 Value *Op0 = I.getOperand(0);

7203 Value *Op1 = I.getOperand(1);

7205 if (!Op1C)

7206 return nullptr;

7207

7209 if (!FlippedStrictness)

7210 return nullptr;

7211

7212 return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);

7213}

7214

7215

7216

7218

7221 return nullptr;

7222

7223

7225 return nullptr;

7226

7227

7228

7230 I.setName(I.getName() + ".not");

7231

7232

7234

7235 return &I;

7236}

7237

7238

7241 Value *A = I.getOperand(0), *B = I.getOperand(1);

7242 assert(A->getType()->isIntOrIntVectorTy(1) && "Bools only");

7243

7244

7245

7246

7248 switch (I.getPredicate()) {

7253 default:

7254 llvm_unreachable("ICmp i1 X, C not simplified as expected.");

7255 }

7257 switch (I.getPredicate()) {

7262 default:

7263 llvm_unreachable("ICmp i1 X, C not simplified as expected.");

7264 }

7265 }

7266

7267 switch (I.getPredicate()) {

7268 default:

7271

7273

7275

7276 return BinaryOperator::CreateXor(A, B);

7277

7279

7281 [[fallthrough]];

7283

7284 return BinaryOperator::CreateAnd(Builder.CreateNot(A), B);

7285

7287

7289 [[fallthrough]];

7291

7292 return BinaryOperator::CreateAnd(Builder.CreateNot(B), A);

7293

7295

7297 [[fallthrough]];

7299

7300 return BinaryOperator::CreateOr(Builder.CreateNot(A), B);

7301

7303

7305 [[fallthrough]];

7307

7308 return BinaryOperator::CreateOr(Builder.CreateNot(B), A);

7309 }

7310}

7311

7312

7313

7314

7315

7316

7317

7324 switch (Pred) {

7327 break;

7330 break;

7331 default:

7332 return nullptr;

7333 }

7340

7341

7342

7343 switch (Pred) {

7346 break;

7349 break;

7350 default:

7351 return nullptr;

7352 }

7353 } else

7354 return nullptr;

7355

7356 Value *NewX = Builder.CreateLShr(X, Y, X->getName() + ".highbits");

7358 return CmpInst::Create(Instruction::ICmp, NewPred, NewX, Zero);

7359}

7360

7364 Value *LHS = Cmp.getOperand(0), *RHS = Cmp.getOperand(1);

7366

7368 Value *V = Builder.CreateCmp(Pred, X, Y, Cmp.getName());

7370 I->copyIRFlags(&Cmp);

7371 Module *M = Cmp.getModule();

7373 M, Intrinsic::vector_reverse, V->getType());

7375 };

7376

7378

7380 (LHS->hasOneUse() || RHS->hasOneUse()))

7381 return createCmpReverse(Pred, V1, V2);

7382

7383

7385 return createCmpReverse(Pred, V1, RHS);

7386 }

7387

7389 return createCmpReverse(Pred, LHS, V2);

7390

7393 return nullptr;

7394

7395

7396

7397

7400 V1Ty == V2->getType() && (LHS->hasOneUse() || RHS->hasOneUse())) {

7401 Value *NewCmp = Builder.CreateCmp(Pred, V1, V2);

7403 }

7404

7405

7406

7407

7410 return nullptr;

7411

7412

7413

7414 Constant *ScalarC = C->getSplatValue( true);

7415 int MaskSplatIndex;

7417

7418

7420 ScalarC);

7422 Value *NewCmp = Builder.CreateCmp(Pred, V1, C);

7424 }

7425

7426 return nullptr;

7427}

7428

7429

7430

7433 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

7434

7439 if (match(Op0, UAddOvResultPat) &&

7445

7446

7447

7450 (Op0 == A || Op0 == B))

7451

7453 else

7454 return nullptr;

7455

7457}

7458

7460 if (I.getOperand(0)->getType()->isPointerTy() ||

7462 I.getParent()->getParent(),

7463 I.getOperand(0)->getType()->getPointerAddressSpace())) {

7464 return nullptr;

7465 }

7469 Op->isLaunderOrStripInvariantGroup()) {

7471 Op->getOperand(0), I.getOperand(1));

7472 }

7473 return nullptr;

7474}

7475

7476

7477

7478

7479

7483 if (I.getType()->isVectorTy())

7484 return nullptr;

7487

7488

7489

7490

7491

7492

7493

7494

7495

7496

7497

7498

7499

7504 return nullptr;

7506 if (!LHSTy || !LHSTy->getElementType()->isIntegerTy())

7507 return nullptr;

7508 unsigned NumBits =

7509 LHSTy->getNumElements() * LHSTy->getElementType()->getIntegerBitWidth();

7510

7511 if (DL.isLegalInteger(NumBits))

7512 return nullptr;

7513

7515 auto *ScalarTy = Builder.getIntNTy(NumBits);

7516 LHS = Builder.CreateBitCast(LHS, ScalarTy, LHS->getName() + ".scalar");

7517 RHS = Builder.CreateBitCast(RHS, ScalarTy, RHS->getName() + ".scalar");

7519 I.getName());

7520 }

7521

7522 return nullptr;

7523}

7524

7525

7529

7532 return NI;

7533

7536 return NI;

7537

7540 return Res;

7541

7543 return Res;

7544 }

7545

7546 {

7549

7552 }

7553

7554

7555

7556

7557

7558

7559

7560

7561

7562

7563

7564 {

7573 bool IsIntMinPosion = C->isAllOnesValue();

7574 switch (Pred) {

7585 CxtI, IsIntMinPosion

7586 ? Builder.CreateICmpSGT(X, AllOnesValue)

7587 : Builder.CreateICmpULT(

7588 X, ConstantInt::get(X->getType(), SMin + 1)));

7589 }

7594 CxtI, IsIntMinPosion

7595 ? Builder.CreateICmpSLT(X, NullValue)

7596 : Builder.CreateICmpUGT(

7597 X, ConstantInt::get(X->getType(), SMin)));

7598 }

7599 default:

7601 }

7602 }

7603 }

7604

7608

7609

7610 auto CheckUGT1 = [](const APInt &Divisor) { return Divisor.ugt(1); };

7611 {

7615 }

7616

7621 }

7622 }

7623

7624

7625 auto CheckNE0 = [](const APInt &Shift) { return !Shift.isZero(); };

7626 {

7630 }

7631

7636 }

7637 }

7638

7639 return nullptr;

7640}

7641

7645 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

7648

7649

7650

7651

7652 if (Op0Cplxity < Op1Cplxity) {

7653 I.swapOperands();

7656 }

7657

7660

7661

7662

7664 Value *Cond, *SelectTrue, *SelectFalse;

7666 m_Value(SelectFalse)))) {

7667 if (Value *V = dyn_castNegVal(SelectTrue)) {

7668 if (V == SelectFalse)

7669 return CmpInst::Create(Instruction::ICmp, I.getPredicate(), V, Op1);

7670 } else if (Value *V = dyn_castNegVal(SelectFalse)) {

7671 if (V == SelectTrue)

7672 return CmpInst::Create(Instruction::ICmp, I.getPredicate(), V, Op1);

7673 }

7674 }

7675 }

7676

7678 return Res;

7679

7682 return Res;

7683

7685 return Res;

7686

7688 return Res;

7689

7691 return Res;

7692

7694 return Res;

7695

7697 return Res;

7698

7700 return Res;

7701

7703 return Res;

7704

7705

7706

7707

7708

7709

7710

7711

7712

7713

7714 if (I.hasOneUse())

7719 return nullptr;

7720 }

7721

7722

7724 return Res;

7725

7726

7727

7728

7729

7730

7734

7738 }

7739

7740

7744 }

7745 }

7746

7747

7748

7749

7750

7751

7752

7754 return Res;

7755

7757 return Res;

7758

7759

7760

7762 return New;

7763

7766 return NV;

7769 return NV;

7770

7772 return Res;

7773

7775 return Res;

7778 return Res;

7779

7780 if (I.isCommutative()) {

7781 if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) {

7784 return &I;

7785 }

7786 }

7787

7788

7789

7790

7791

7792

7793

7794

7795

7796

7797

7798

7799

7800

7801 {

7805 (Op0->hasOneUse() || Op1->hasOneUse())) {

7806

7810 }

7811

7815 }

7816 }

7817 }

7818

7819

7820

7821

7822 {

7829 bool I0NUW = I0->hasNoUnsignedWrap();

7830 bool I1NUW = I1->hasNoUnsignedWrap();

7831 bool I0NSW = I0->hasNoSignedWrap();

7832 bool I1NSW = I1->hasNoSignedWrap();

7836 ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {

7838 ConstantInt::get(Op0->getType(), 0));

7839 }

7840 }

7841 }

7842

7843

7845 assert(Op1->getType()->isPointerTy() &&

7846 "Comparing pointer with non-pointer?");

7849 return nullptr;

7852 return nullptr;

7853 }

7854

7856 return Res;

7857

7858

7860 return R;

7861

7862 {

7864

7865

7866

7869 I.isEquality())

7870 return new ICmpInst(I.getInversePredicate(), Builder.CreateAnd(X, Y),

7871 Op1);

7872

7873

7875 bool ConsumesOp0, ConsumesOp1;

7877 isFreeToInvert(Op1, Op1->hasOneUse(), ConsumesOp1) &&

7878 (ConsumesOp0 || ConsumesOp1)) {

7881 assert(InvOp0 && InvOp1 &&

7882 "Mismatch between isFreeToInvert and getFreelyInverted");

7883 return new ICmpInst(I.getSwappedPredicate(), InvOp0, InvOp1);

7884 }

7885 }

7886

7893

7894

7895 if (AddI->getOpcode() == Instruction::Add &&

7896 OptimizeOverflowCheck(Instruction::Add, false, X, Y, *AddI,

7897 Result, Overflow)) {

7901 }

7902 }

7903

7904

7908 return R;

7909 }

7910

7911

7912

7913

7915 if ((I.isUnsigned() || I.isEquality()) &&

7918 Y->getType()->getScalarSizeInBits() == 1 &&

7919 (Op0->hasOneUse() || Op1->hasOneUse())) {

7924 OpWidth - 1))))) {

7925 unsigned ExtOpc = ExtI->getOpcode();

7926 unsigned ShiftOpc = ShiftI->getOpcode();

7927 if ((ExtOpc == Instruction::ZExt && ShiftOpc == Instruction::LShr) ||

7928 (ExtOpc == Instruction::SExt && ShiftOpc == Instruction::AShr)) {

7929 Value *SLTZero =

7931 Value *Cmp = Builder.CreateICmp(Pred, SLTZero, Y, I.getName());

7933 }

7934 }

7935 }

7936 }

7937

7939 return Res;

7940

7942 return Res;

7943

7945 return Res;

7946

7947

7948

7949

7950

7951

7952

7953

7954

7955

7959 if (EVI->getIndices()[0] == 0 && ACXI->getCompareOperand() == Op1 &&

7960 !ACXI->isWeak())

7962

7964 return Res;

7965

7966 if (I.getType()->isVectorTy())

7968 return Res;

7969

7971 return Res;

7972

7974 return Res;

7975

7976 {

7978 const APInt *C1, *C2;

7981

7982

7985 Type *InputTy = A->getType();

7987

7989 APInt TruncC1 = C1->trunc(InputBitWidth);

7990

7992 TruncC1.setBit(InputBitWidth - 1);

7995 Pred, AndInst,

7996 ConstantInt::get(InputTy, C2->trunc(InputBitWidth)));

7997 }

7998 }

7999 }

8000 }

8001

8002 return Changed ? &I : nullptr;

8003}

8004

8005

8011 return nullptr;

8012

8013

8014

8016 if (MantissaWidth == -1)

8017 return nullptr;

8018

8022

8023 if (I.isEquality()) {

8025 bool IsExact = false;

8026 APSInt RHSCvt(IntWidth, LHSUnsigned);

8028

8029

8030

8031 if (!IsExact) {

8032

8033 APFloat RHSRoundInt(*RHS);

8035 if (*RHS != RHSRoundInt) {

8038

8041 }

8042 }

8043

8044

8045

8046 }

8047

8048

8049

8050

8051

8052

8053

8054

8055 if ((int)IntWidth > MantissaWidth) {

8056

8057 int Exp = ilogb(*RHS);

8060 if (MaxExponent < (int)IntWidth - !LHSUnsigned)

8061

8062 return nullptr;

8063 } else {

8064

8065

8066 if (MantissaWidth <= Exp && Exp <= (int)IntWidth - !LHSUnsigned)

8067

8068 return nullptr;

8069 }

8070 }

8071

8072

8073

8074

8075 assert(!RHS->isNaN() && "NaN comparison not already folded!");

8076

8078 switch (I.getPredicate()) {

8079 default:

8084 break;

8088 break;

8092 break;

8096 break;

8100 break;

8104 break;

8109 }

8110

8111

8112

8113

8114

8115 if (!LHSUnsigned) {

8116

8117

8121 if (SMax < *RHS) {

8126 }

8127 } else {

8128

8129

8133 if (UMax < *RHS) {

8138 }

8139 }

8140

8141 if (!LHSUnsigned) {

8142

8146 if (SMin > *RHS) {

8151 }

8152 } else {

8153

8157 if (UMin > *RHS) {

8162 }

8163 }

8164

8165

8166

8167

8168

8169 APSInt RHSInt(IntWidth, LHSUnsigned);

8170 bool IsExact;

8172 if (!RHS->isZero()) {

8173 if (!IsExact) {

8174

8175

8176

8177 switch (Pred) {

8178 default:

8185

8186

8187 if (RHS->isNegative())

8189 break;

8191

8192

8193 if (RHS->isNegative())

8195 break;

8197

8198

8199 if (RHS->isNegative())

8202 break;

8204

8205

8206 if (!RHS->isNegative())

8208 break;

8210

8211

8212 if (RHS->isNegative())

8214 break;

8216

8217

8218 if (RHS->isNegative())

8220 break;

8222

8223

8224 if (RHS->isNegative())

8227 break;

8229

8230

8231 if (!RHS->isNegative())

8233 break;

8234 }

8235 }

8236 }

8237

8238

8239

8242}

8243

8244

8247

8248

8249

8250

8251

8252

8253

8254

8255

8256

8257

8258

8259

8261

8262

8265 return nullptr;

8266

8267

8269 return nullptr;

8270

8271

8272 if (!LHSI->hasNoInfs() || I.hasNoInfs())

8273 return nullptr;

8274

8275

8276

8279 return nullptr;

8280

8281 if (C->isZero())

8282 return nullptr;

8283

8284

8285 if (C->isNegative())

8286 Pred = I.getSwappedPredicate();

8287

8289}

8290

8291

8292

8293

8294

8295

8296

8297

8298

8302 bool RoundDown = false;

8303

8306 RoundDown = true;

8309 RoundDown = false;

8310 else

8311 return nullptr;

8312

8315 return nullptr;

8316

8318 return nullptr;

8319

8320 auto ConvertFltSema = [](const APFloat &Src, const fltSemantics &Sema) {

8321 bool LosesInfo;

8324 return Dest;

8325 };

8326

8327 auto NextValue = [](const APFloat &Value, bool RoundDown) {

8329 NextValue.next(RoundDown);

8330 return NextValue;

8331 };

8332

8333 APFloat NextCValue = NextValue(*CValue, RoundDown);

8334

8338

8339 APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);

8340 APFloat ExtNextCValue = ConvertFltSema(NextCValue, DestFltSema);

8341

8342

8343

8344

8345

8347 APFloat PrevCValue = NextValue(*CValue, !RoundDown);

8348 APFloat Bias = ConvertFltSema(*CValue - PrevCValue, DestFltSema);

8349

8350 ExtNextCValue = ExtCValue + Bias;

8351 }

8352

8355

8357 C.getType()->getScalarType()->getFltSemantics();

8358

8359

8360 APFloat MidValue = ConvertFltSema(ExtMidValue, SrcFltSema);

8361 if (MidValue != *CValue)

8362 ExtMidValue.next(!RoundDown);

8363

8364

8365

8366

8367

8369

8370 if (ConvertFltSema(ExtMidValue, SrcFltSema).isInfinity())

8371 return nullptr;

8372

8373

8374 APFloat NextExtMidValue = NextValue(ExtMidValue, RoundDown);

8375 if (ConvertFltSema(NextExtMidValue, SrcFltSema).isFinite())

8376 return nullptr;

8377 }

8378

8380 ConstantFP::get(DestType, ExtMidValue), "", &I);

8381}

8382

8383

8387 return nullptr;

8388

8391 return nullptr;

8392

8393 if (C->isPosZero()) {

8394 if (C->isSmallestNormalized())

8395 return nullptr;

8396

8397 const Function *F = I.getFunction();

8401

8405 };

8406

8407 switch (I.getPredicate()) {

8409

8412

8415

8418

8420 default:

8421 break;

8422 }

8423 }

8424

8425 return nullptr;

8426 }

8427

8429 I->setPredicate(P);

8431 };

8432

8433 switch (I.getPredicate()) {

8436

8437

8439

8441

8443

8445

8447

8449

8451

8453

8455

8457

8458 assert(I.hasNoNaNs() && "fcmp should have simplified");

8460

8462

8463 assert(I.hasNoNaNs() && "fcmp should have simplified");

8465

8472

8473

8474

8475

8476

8477 return replacePredAndOp0(&I, I.getPredicate(), X);

8478

8479 default:

8480 return nullptr;

8481 }

8482}

8483

8484

8488 return nullptr;

8489

8491 return nullptr;

8492

8494 I.setPredicate(P);

8496 };

8497

8498

8500 I.setHasNoInfs(false);

8501

8502 switch (I.getPredicate()) {

8505

8506

8514

8515

8516

8517

8518

8519

8521

8523

8526

8529

8532

8535

8538

8540 default:

8542 }

8543}

8544

8547 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

8548

8549

8552 Pred = I.getSwappedPredicate();

8553 }

8554

8556 return nullptr;

8557

8558

8559

8561 return new FCmpInst(Pred, Op0, Zero, "", &I);

8562}

8563

8569 switch (Pred) {

8570 default:

8571 break;

8578

8579

8580

8581

8586 break;

8587

8588 [[fallthrough]];

8595

8597 I.getFunction()->getDenormalMode(

8604 I.setHasNoNaNs(true);

8605 return &I;

8606 }

8607 break;

8608 }

8609

8610 return nullptr;

8611}

8612

8615 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);

8616 Type *OpType = LHS->getType();

8618

8621

8622 if (!FloorX && !CeilX) {

8626 Pred = I.getSwappedPredicate();

8627 }

8628 }

8629

8630 switch (Pred) {

8632

8633 if (FloorX)

8635 "", &I);

8636 break;

8638

8639 if (FloorX)

8641 break;

8643

8644 if (CeilX)

8646 "", &I);

8647 break;

8649

8650 if (CeilX)

8652 break;

8654

8655 if (FloorX)

8657 break;

8659

8660 if (FloorX)

8662 "", &I);

8663 break;

8665

8666 if (CeilX)

8668 break;

8670

8671 if (CeilX)

8673 "", &I);

8674 break;

8675 default:

8676 break;

8677 }

8678

8679 return nullptr;

8680}

8681

8684

8685

8686

8687

8689 I.swapOperands();

8691 }

8692

8694 Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

8696 SQ.getWithInstruction(&I)))

8698

8699

8701 assert(OpType == Op1->getType() && "fcmp with different-typed operands?");

8702 if (Op0 == Op1) {

8703 switch (Pred) {

8704 default:

8705 break;

8710

8713 return &I;

8714

8717 case FCmpInst::FCMP_OGE:

8719

8722 return &I;

8723 }

8724 }

8725

8726 if (I.isCommutative()) {

8727 if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) {

8730 return &I;

8731 }

8732 }

8733

8734

8735

8740

8744 }

8745

8746

8749 return new FCmpInst(I.getSwappedPredicate(), X, Y, "", &I);

8750

8752 return R;

8753

8754

8755

8756

8757

8758

8759

8760

8761 if (I.hasOneUse())

8766 return nullptr;

8767 }

8768

8769

8770

8773

8774

8775

8776

8777

8778

8779

8780

8781

8782

8783

8784

8785

8786

8787

8788

8789

8790

8794 default:

8795 break;

8807 "", &I);

8814 "", &I);

8817 }

8818 }

8819

8820

8821

8829

8831 Type *IntTy = X->getType();

8832 const APInt &SignMask = ~APInt::getSignMask(IntTy->getScalarSizeInBits());

8833 Value *MaskX = Builder.CreateAnd(X, ConstantInt::get(IntTy, SignMask));

8835 }

8836 }

8837

8838

8843 case Instruction::Select:

8844

8849 return NV;

8850 break;

8851 case Instruction::FSub:

8854 return NV;

8855 break;

8856 case Instruction::PHI:

8858 return NV;

8859 break;

8860 case Instruction::SIToFP:

8861 case Instruction::UIToFP:

8863 return NV;

8864 break;

8865 case Instruction::FDiv:

8867 return NV;

8868 break;

8869 case Instruction::Load:

8873 return Res;

8874 break;

8875 case Instruction::FPTrunc:

8877 return NV;

8878 break;

8879 }

8880 }

8881

8883 return R;

8884

8886 return R;

8887

8889 return R;

8890

8892

8896 return new FCmpInst(I.getSwappedPredicate(), X, NegC, "", &I);

8897 }

8898

8899

8901 return new FCmpInst(Pred, X, Op1, "", &I);

8902

8903

8905 return new FCmpInst(Pred, Op0, Y, "", &I);

8906

8908

8910 return new FCmpInst(Pred, X, Y, "", &I);

8911

8915 X->getType()->getScalarType()->getFltSemantics();

8916 bool Lossy;

8919

8920 if (Lossy) {

8921

8922

8923

8924 switch (Pred) {

8926

8929

8933

8937

8939 default:

8940 break;

8941 }

8942 }

8943

8944

8945

8946

8949 if (!Lossy &&

8951 Constant *NewC = ConstantFP::get(X->getType(), TruncC);

8952 return new FCmpInst(Pred, X, NewC, "", &I);

8953 }

8954 }

8955 }

8956

8957

8958

8959

8960

8964 Type *IntType = Builder.getIntNTy(X->getType()->getScalarSizeInBits());

8966 IntType = VectorType::get(IntType, VecTy->getElementCount());

8967

8968

8970 Value *IntX = Builder.CreateBitCast(X, IntType);

8973 }

8974 }

8975

8976 {

8977 Value *CanonLHS = nullptr;

8979

8980 if (CanonLHS == Op1)

8981 return new FCmpInst(Pred, Op1, Op1, "", &I);

8982

8983 Value *CanonRHS = nullptr;

8985

8986 if (CanonRHS == Op0)

8987 return new FCmpInst(Pred, Op0, Op0, "", &I);

8988

8989

8990 if (CanonLHS && CanonRHS)

8991 return new FCmpInst(Pred, CanonLHS, CanonRHS, "", &I);

8992 }

8993

8994 if (I.getType()->isVectorTy())

8996 return Res;

8997

8998 return Changed ? &I : nullptr;

8999}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

AMDGPU Register Bank Select

This file declares a class to represent arbitrary precision floating point values and provide a varie...

This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

static Instruction * foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI, Constant *RHSC)

Fold (C / X) < 0.0 --> X < 0.0 if possible. Swap predicate if necessary.

Definition InstCombineCompares.cpp:8245

static Instruction * foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)

Optimize fabs(X) compared with zero.

Definition InstCombineCompares.cpp:8384

static void collectOffsetOp(Value *V, SmallVectorImpl< OffsetOp > &Offsets, bool AllowRecursion)

Definition InstCombineCompares.cpp:5878

static Value * rewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags NW, const DataLayout &DL, SetVector< Value * > &Explored, InstCombiner &IC)

Returns a re-written value of Start as an indexed GEP using Base as a pointer.

Definition InstCombineCompares.cpp:507

static Instruction * foldICmpEqualityWithOffset(ICmpInst &I, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)

Offset both sides of an equality icmp to see if we can save some instructions: icmp eq/ne X,...

Definition InstCombineCompares.cpp:5945

static bool addWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)

Compute Result = In1+In2, returning true if the result overflowed for this type.

Definition InstCombineCompares.cpp:46

static Instruction * foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)

Definition InstCombineCompares.cpp:4970

static Instruction * foldVectorCmp(CmpInst &Cmp, InstCombiner::BuilderTy &Builder)

Definition InstCombineCompares.cpp:7361

static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q, unsigned Depth=0)

Definition InstCombineCompares.cpp:4386

static Value * createLogicFromTable(const std::bitset< 4 > &Table, Value *Op0, Value *Op1, IRBuilderBase &Builder, bool HasOneUse)

Definition InstCombineCompares.cpp:3038

static Instruction * foldICmpOfUAddOv(ICmpInst &I)

Definition InstCombineCompares.cpp:7431

static bool isChainSelectCmpBranch(const SelectInst *SI)

Return true when the instruction sequence within a block is select-cmp-br.

Definition InstCombineCompares.cpp:6813

static Instruction * foldICmpInvariantGroup(ICmpInst &I)

Definition InstCombineCompares.cpp:7459

std::pair< Instruction::BinaryOps, Value * > OffsetOp

Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.

Definition InstCombineCompares.cpp:5877

static Instruction * foldReductionIdiom(ICmpInst &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)

This function folds patterns produced by lowering of reduce idioms, such as llvm.vector....

Definition InstCombineCompares.cpp:7480

static Instruction * canonicalizeICmpBool(ICmpInst &I, InstCombiner::BuilderTy &Builder)

Integer compare with boolean values can always be turned into bitwise ops.

Definition InstCombineCompares.cpp:7239

OffsetKind

Definition InstCombineCompares.cpp:5913

@ Invalid

Definition InstCombineCompares.cpp:5913

@ Value

Definition InstCombineCompares.cpp:5913

@ Select

Definition InstCombineCompares.cpp:5913

static Instruction * foldFCmpFSubIntoFCmp(FCmpInst &I, Instruction *LHSI, Constant *RHSC, InstCombinerImpl &CI)

Definition InstCombineCompares.cpp:8564

static Value * foldICmpOrXorSubChain(ICmpInst &Cmp, BinaryOperator *Or, InstCombiner::BuilderTy &Builder)

Fold icmp eq/ne (or (xor/sub (X1, X2), xor/sub (X3, X4))), 0.

Definition InstCombineCompares.cpp:2022

static bool hasBranchUse(ICmpInst &I)

Given an icmp instruction, return true if any use of this comparison is a branch on sign bit comparis...

Definition InstCombineCompares.cpp:72

static Value * foldICmpWithLowBitMaskedVal(CmpPredicate Pred, Value *Op0, Value *Op1, const SimplifyQuery &Q, InstCombiner &IC)

Some comparisons can be simplified.

Definition InstCombineCompares.cpp:4493

static APInt getDemandedBitsLHSMask(ICmpInst &I, unsigned BitWidth)

When performing a comparison against a constant, it is possible that not all the bits in the LHS are ...

Definition InstCombineCompares.cpp:6752

static Instruction * foldICmpShlLHSC(ICmpInst &Cmp, Instruction *Shl, const APInt &C)

Fold icmp (shl nuw C2, Y), C.

Definition InstCombineCompares.cpp:2273

static Instruction * foldFCmpWithFloorAndCeil(FCmpInst &I, InstCombinerImpl &IC)

Definition InstCombineCompares.cpp:8613

static Instruction * foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)

Definition InstCombineCompares.cpp:5067

static Instruction * foldICmpOfCmpIntrinsicWithConstant(CmpPredicate Pred, IntrinsicInst *I, const APInt &C, InstCombiner::BuilderTy &Builder)

Definition InstCombineCompares.cpp:4129

static Instruction * processUMulZExtIdiom(ICmpInst &I, Value *MulVal, const APInt *OtherVal, InstCombinerImpl &IC)

Recognize and process idiom involving test for multiplication overflow.

Definition InstCombineCompares.cpp:6605

static Instruction * foldSqrtWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC)

Optimize sqrt(X) compared with zero.

Definition InstCombineCompares.cpp:8485

static Instruction * foldFCmpFNegCommonOp(FCmpInst &I)

Definition InstCombineCompares.cpp:8545

static Instruction * foldICmpWithHighBitMask(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)

Definition InstCombineCompares.cpp:7318

static ICmpInst * canonicalizeCmpWithConstant(ICmpInst &I)

If we have an icmp le or icmp ge instruction with a constant operand, turn it into the appropriate ic...

Definition InstCombineCompares.cpp:7196

static Instruction * foldICmpIntrinsicWithIntrinsic(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder)

Fold an icmp with LLVM intrinsics.

Definition InstCombineCompares.cpp:3902

static Instruction * foldICmpUSubSatOrUAddSatWithConstant(CmpPredicate Pred, SaturatingInst *II, const APInt &C, InstCombiner::BuilderTy &Builder)

Definition InstCombineCompares.cpp:4044

static Instruction * foldICmpPow2Test(ICmpInst &I, InstCombiner::BuilderTy &Builder)

Definition InstCombineCompares.cpp:5824

static bool subWithOverflow(APInt &Result, const APInt &In1, const APInt &In2, bool IsSigned=false)

Compute Result = In1-In2, returning true if the result overflowed for this type.

Definition InstCombineCompares.cpp:59

static bool canRewriteGEPAsOffset(Value *Start, Value *Base, GEPNoWrapFlags &NW, const DataLayout &DL, SetVector< Value * > &Explored)

Returns true if we can rewrite Start as a GEP with pointer Base and some integer offset.

Definition InstCombineCompares.cpp:393

static Instruction * foldFCmpFpTrunc(FCmpInst &I, const Instruction &FPTrunc, const Constant &C)

Definition InstCombineCompares.cpp:8299

static Instruction * foldICmpXNegX(ICmpInst &I, InstCombiner::BuilderTy &Builder)

Definition InstCombineCompares.cpp:4938

static Instruction * processUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B, ConstantInt *CI2, ConstantInt *CI1, InstCombinerImpl &IC)

The caller has matched a pattern of the form: I = icmp ugt (add (add A, B), CI2), CI1 If this is of t...

Definition InstCombineCompares.cpp:1060

static Value * foldShiftIntoShiftInAnotherHandOfAndInICmp(ICmpInst &I, const SimplifyQuery SQ, InstCombiner::BuilderTy &Builder)

Definition InstCombineCompares.cpp:4697

static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C)

Returns true if the exploded icmp can be expressed as a signed comparison to zero and updates the pre...

Definition InstCombineCompares.cpp:83

static Instruction * transformToIndexedCompare(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, const DataLayout &DL, InstCombiner &IC)

Converts (CMP GEPLHS, RHS) if this change would make RHS a constant.

Definition InstCombineCompares.cpp:601

static Instruction * foldCtpopPow2Test(ICmpInst &I, IntrinsicInst *CtpopLhs, const APInt &CRhs, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)

Definition InstCombineCompares.cpp:3756

static void setInsertionPoint(IRBuilder<> &Builder, Value *V, bool Before=true)

Definition InstCombineCompares.cpp:481

static bool isNeutralValue(Instruction::BinaryOps BinaryOp, Value *RHS, bool IsSigned)

Definition InstCombineCompares.cpp:6503

static bool isMultipleOf(Value *X, const APInt &C, const SimplifyQuery &Q)

Return true if X is a multiple of C.

Definition InstCombineCompares.cpp:5113

static Value * foldICmpWithTruncSignExtendedVal(ICmpInst &I, InstCombiner::BuilderTy &Builder)

Some comparisons can be simplified.

Definition InstCombineCompares.cpp:4623

static Instruction * foldICmpOrXX(ICmpInst &I, const SimplifyQuery &Q, InstCombinerImpl &IC)

Definition InstCombineCompares.cpp:5032

This file provides internal interfaces used to implement the InstCombine.

This file provides the interface for the instcombine pass implementation.

const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]

static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)

uint64_t IntrinsicInst * II

const SmallVectorImpl< MachineOperand > & Cond

static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))

This file implements a set that has insertion order iteration characteristics.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

static SymbolRef::Type getType(const Symbol *Sym)

static constexpr roundingMode rmTowardZero

static constexpr roundingMode rmNearestTiesToEven

LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)

static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)

Returns the smallest (by magnitude) normalized finite number in the given semantics.

APInt bitcastToAPInt() const

static APFloat getLargest(const fltSemantics &Sem, bool Negative=false)

Returns the largest finite number in the given semantics.

opStatus next(bool nextDown)

static APFloat getInf(const fltSemantics &Sem, bool Negative=false)

Factory for Positive and Negative Infinity.

LLVM_ABI FPClassTest classify() const

Return the FPClassTest which will return true for the value.

opStatus roundToIntegral(roundingMode RM)

Class for arbitrary precision integers.

LLVM_ABI APInt udiv(const APInt &RHS) const

Unsigned division operation.

static APInt getAllOnes(unsigned numBits)

Return an APInt of a specified width with all bits set.

static LLVM_ABI void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)

Dual division/remainder interface.

bool isNegatedPowerOf2() const

Check if this APInt's negated value is a power of two greater than zero.

LLVM_ABI APInt zext(unsigned width) const

Zero extend to a new width.

static APInt getSignMask(unsigned BitWidth)

Get the SignMask for a specific bit width.

bool isMinSignedValue() const

Determine if this is the smallest signed value.

uint64_t getZExtValue() const

Get zero extended value.

unsigned getActiveBits() const

Compute the number of active bits in the value.

LLVM_ABI APInt trunc(unsigned width) const

Truncate to new width.

static APInt getMaxValue(unsigned numBits)

Gets maximum unsigned value of APInt for specific bit width.

void setBit(unsigned BitPosition)

Set the given bit to 1 whose position is given as "bitPosition".

APInt abs() const

Get the absolute value.

unsigned ceilLogBase2() const

bool sgt(const APInt &RHS) const

Signed greater than comparison.

bool isAllOnes() const

Determine if all bits are set. This is true for zero-width values.

LLVM_ABI APInt usub_ov(const APInt &RHS, bool &Overflow) const

bool ugt(const APInt &RHS) const

Unsigned greater than comparison.

bool isZero() const

Determine if this value is zero, i.e. all bits are clear.

bool isSignMask() const

Check if the APInt's value is returned by getSignMask.

unsigned getBitWidth() const

Return the number of bits in the APInt.

bool ult(const APInt &RHS) const

Unsigned less than comparison.

static APInt getSignedMaxValue(unsigned numBits)

Gets maximum signed value of APInt for a specific bit width.

static APInt getMinValue(unsigned numBits)

Gets minimum unsigned value of APInt for a specific bit width.

bool isNegative() const

Determine sign of this APInt.

LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const

bool eq(const APInt &RHS) const

Equality comparison.

LLVM_ABI APInt sdiv(const APInt &RHS) const

Signed division function for APInt.

LLVM_ABI APInt uadd_ov(const APInt &RHS, bool &Overflow) const

void negate()

Negate this APInt in place.

unsigned countr_zero() const

Count the number of trailing zero bits.

unsigned countl_zero() const

The APInt version of std::countl_zero.

static APInt getSignedMinValue(unsigned numBits)

Gets minimum signed value of APInt for a specific bit width.

bool isStrictlyPositive() const

Determine if this APInt Value is positive.

void flipAllBits()

Toggle every bit to its opposite value.

unsigned countl_one() const

Count the number of leading one bits.

unsigned logBase2() const

uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const

If this value is smaller than the specified limit, return it, otherwise return the limit value.

APInt ashr(unsigned ShiftAmt) const

Arithmetic right-shift function.

bool isMaxSignedValue() const

Determine if this is the largest signed value.

bool ule(const APInt &RHS) const

Unsigned less or equal comparison.

APInt shl(unsigned shiftAmt) const

Left-shift function.

bool isPowerOf2() const

Check if this APInt's value is a power of two greater than zero.

static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)

Constructs an APInt value that has the bottom loBitsSet bits set.

static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)

Constructs an APInt value that has the top hiBitsSet bits set.

static APInt getZero(unsigned numBits)

Get the '0' value for the specified bit-width.

bool sge(const APInt &RHS) const

Signed greater or equal comparison.

LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const

bool isOne() const

Determine if this is a value of 1.

static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)

Constructs an APInt value that has a contiguous range of bits set.

static APInt getOneBitSet(unsigned numBits, unsigned BitNo)

Return an APInt with exactly one bit set in the result.

APInt lshr(unsigned shiftAmt) const

Logical right-shift function.

unsigned countr_one() const

Count the number of trailing one bits.

bool uge(const APInt &RHS) const

Unsigned greater or equal comparison.

An arbitrary precision integer that knows its signedness.

an instruction to allocate memory on the stack

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

LLVM Basic Block Representation.

LLVM_ABI const_iterator getFirstInsertionPt() const

Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...

LLVM_ABI const BasicBlock * getSinglePredecessor() const

Return the predecessor of this block if it has a single predecessor block.

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

BinaryOps getOpcode() const

static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)

static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)

Construct a binary instruction, given the opcode and the two operands.

Conditional or Unconditional Branch instruction.

Value * getArgOperand(unsigned i) const

This class represents a function call, abstracting a target machine's calling convention.

static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

This class is the base class for the comparison instructions.

static Type * makeCmpResultType(Type *opnd_type)

Create a result type for fcmp/icmp.

Predicate getStrictPredicate() const

For example, SGE -> SGT, SLE -> SLT, ULE -> ULT, UGE -> UGT.

static LLVM_ABI Predicate getFlippedStrictnessPredicate(Predicate pred)

This is a static version that you can use without an instruction available.

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ FCMP_OEQ

0 0 0 1 True if ordered and equal

@ FCMP_TRUE

1 1 1 1 Always true (always folded)

@ ICMP_SLT

signed less than

@ ICMP_SLE

signed less or equal

@ FCMP_OLT

0 1 0 0 True if ordered and less than

@ FCMP_ULE

1 1 0 1 True if unordered, less than, or equal

@ FCMP_OGT

0 0 1 0 True if ordered and greater than

@ FCMP_OGE

0 0 1 1 True if ordered and greater than or equal

@ ICMP_UGE

unsigned greater or equal

@ ICMP_UGT

unsigned greater than

@ ICMP_SGT

signed greater than

@ FCMP_ULT

1 1 0 0 True if unordered or less than

@ FCMP_ONE

0 1 1 0 True if ordered and operands are unequal

@ FCMP_UEQ

1 0 0 1 True if unordered or equal

@ ICMP_ULT

unsigned less than

@ FCMP_UGT

1 0 1 0 True if unordered or greater than

@ FCMP_OLE

0 1 0 1 True if ordered and less than or equal

@ FCMP_ORD

0 1 1 1 True if ordered (no nans)

@ ICMP_SGE

signed greater or equal

@ FCMP_UNE

1 1 1 0 True if unordered or not equal

@ ICMP_ULE

unsigned less or equal

@ FCMP_UGE

1 0 1 1 True if unordered, greater than, or equal

@ FCMP_FALSE

0 0 0 0 Always false (always folded)

@ FCMP_UNO

1 0 0 0 True if unordered: isnan(X) | isnan(Y)

Predicate getSwappedPredicate() const

For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.

bool isTrueWhenEqual() const

This is just a convenience.

static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Construct a compare instruction, given the opcode, the predicate and the two operands.

Predicate getNonStrictPredicate() const

For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.

static LLVM_ABI bool isStrictPredicate(Predicate predicate)

This is a static version that you can use without an instruction available.

Predicate getInversePredicate() const

For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...

Predicate getPredicate() const

Return the predicate for this instruction.

static bool isIntPredicate(Predicate P)

An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...

static LLVM_ABI CmpPredicate getSwapped(CmpPredicate P)

Get the swapped predicate of a CmpPredicate.

static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)

static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)

Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.

static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)

static LLVM_ABI Constant * getNot(Constant *C)

static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)

static LLVM_ABI Constant * getXor(Constant *C1, Constant *C2)

static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)

static LLVM_ABI Constant * getZero(Type *Ty, bool Negative=false)

This is the shared class of boolean and integer constants.

uint64_t getLimitedValue(uint64_t Limit=~0ULL) const

getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...

static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)

bool isZero() const

This is just a convenience method to make client code smaller for a common code.

static ConstantInt * getSigned(IntegerType *Ty, int64_t V)

Return a ConstantInt with the specified value for the specified type.

static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)

unsigned getBitWidth() const

getBitWidth - Return the scalar bitwidth of this constant.

const APInt & getValue() const

Return the constant as an APInt value reference.

static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)

This class represents a range of values.

LLVM_ABI ConstantRange add(const ConstantRange &Other) const

Return a new range representing the possible values resulting from an addition of a value in this ran...

LLVM_ABI std::optional< ConstantRange > exactUnionWith(const ConstantRange &CR) const

Union the two ranges and return the result if it can be represented exactly, otherwise return std::nu...

LLVM_ABI bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const

Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.

LLVM_ABI ConstantRange subtract(const APInt &CI) const

Subtract the specified constant from the endpoints of this constant range.

const APInt * getSingleElement() const

If this set contains a single element, return it, otherwise return null.

LLVM_ABI ConstantRange difference(const ConstantRange &CR) const

Subtract the specified range from this range (aka relative complement of the sets).

LLVM_ABI bool isEmptySet() const

Return true if this set contains no members.

LLVM_ABI ConstantRange truncate(uint32_t BitWidth, unsigned NoWrapKind=0) const

Return a new range in the specified integer type, which must be strictly smaller than the current typ...

static LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)

Produce the exact range such that all values in the returned range satisfy the given predicate with a...

LLVM_ABI ConstantRange inverse() const

Return a new range that is the logical not of the current set.

LLVM_ABI std::optional< ConstantRange > exactIntersectWith(const ConstantRange &CR) const

Intersect the two ranges and return the result if it can be represented exactly, otherwise return std...

LLVM_ABI ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const

Return the range that results from the intersection of this range with another range.

static ConstantRange getNonEmpty(APInt Lower, APInt Upper)

Create non-empty constant range with the given bounds.

LLVM_ABI ConstantRange sub(const ConstantRange &Other) const

Return a new range representing the possible values resulting from a subtraction of a value in this r...

static LLVM_ABI ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, const APInt &Other, unsigned NoWrapKind)

Produce the range that contains X if and only if "X BinOp Other" does not wrap.

static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)

Return a ConstantVector with the specified constant in each element.

This is an important base class in LLVM.

static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)

Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...

static LLVM_ABI Constant * getAllOnesValue(Type *Ty)

LLVM_ABI const APInt & getUniqueInteger() const

If C is a constant integer then return its value, otherwise C must be a vector of constant integers,...

static LLVM_ABI Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

LLVM_ABI bool isNullValue() const

Return true if this is the value that would be returned by getNullValue.

A parsed version of the target data layout string in and methods for querying it.

iterator find(const_arg_type_t< KeyT > Val)

bool contains(const_arg_type_t< KeyT > Val) const

Return true if the specified key is in the map, false otherwise.

This instruction compares its operands according to the predicate given to the constructor.

static bool isEquality(Predicate Pred)

Represents flags for the getelementptr instruction/expression.

bool hasNoUnsignedSignedWrap() const

bool hasNoUnsignedWrap() const

GEPNoWrapFlags intersectForOffsetAdd(GEPNoWrapFlags Other) const

Given (gep (gep p, x), y), determine the nowrap flags for (gep p, x+y).

static GEPNoWrapFlags none()

bool isInBounds() const

Test whether this is an inbounds GEP, as defined by LangRef.html.

LLVM_ABI Type * getSourceElementType() const

Value * getPointerOperand()

GEPNoWrapFlags getNoWrapFlags() const

bool hasAllConstantIndices() const

Return true if all of the indices of this GEP are constant integers.

an instruction for type-safe pointer arithmetic to access elements of arrays and structs

This instruction compares its operands according to the predicate given to the constructor.

static bool isGE(Predicate P)

Return true if the predicate is SGE or UGE.

static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)

Return result of LHS Pred RHS comparison.

static bool isLT(Predicate P)

Return true if the predicate is SLT or ULT.

static bool isGT(Predicate P)

Return true if the predicate is SGT or UGT.

Predicate getFlippedSignednessPredicate() const

For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.

Predicate getSignedPredicate() const

For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.

bool isEquality() const

Return true if this predicate is either EQ or NE.

static bool isEquality(Predicate P)

Return true if this predicate is either EQ or NE.

bool isRelational() const

Return true if the predicate is relational (not EQ or NE).

Predicate getUnsignedPredicate() const

For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.

static bool isLE(Predicate P)

Return true if the predicate is SLE or ULE.

Common base class shared among various IRBuilders.

Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")

void SetInsertPoint(BasicBlock *TheBB)

This specifies that created instructions should be appended to the end of the specified block.

Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")

Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)

ConstantInt * getInt(const APInt &AI)

Get a constant integer value.

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

Instruction * foldICmpShrConstant(ICmpInst &Cmp, BinaryOperator *Shr, const APInt &C)

Fold icmp ({al}shr X, Y), C.

Definition InstCombineCompares.cpp:2503

Instruction * foldICmpWithZextOrSext(ICmpInst &ICmp)

Definition InstCombineCompares.cpp:6323

Instruction * foldICmpSelectConstant(ICmpInst &Cmp, SelectInst *Select, ConstantInt *C)

Definition InstCombineCompares.cpp:3352

Instruction * foldICmpSRemConstant(ICmpInst &Cmp, BinaryOperator *UDiv, const APInt &C)

Definition InstCombineCompares.cpp:2657

Instruction * foldICmpBinOpWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)

Fold an icmp with BinaryOp and constant operand: icmp Pred BO, C.

Definition InstCombineCompares.cpp:3980

Instruction * foldICmpOrConstant(ICmpInst &Cmp, BinaryOperator *Or, const APInt &C)

Fold icmp (or X, Y), C.

Definition InstCombineCompares.cpp:2081

Instruction * foldICmpTruncWithTruncOrExt(ICmpInst &Cmp, const SimplifyQuery &Q)

Fold icmp (trunc nuw/nsw X), (trunc nuw/nsw Y).

Definition InstCombineCompares.cpp:1533

Instruction * foldSignBitTest(ICmpInst &I)

Fold equality-comparison between zero and any (maybe truncated) right-shift by one-less-than-bitwidth...

Definition InstCombineCompares.cpp:1166

Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)

Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...

Value * insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi, bool isSigned, bool Inside)

Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise (V < Lo || V >= Hi).

Instruction * foldICmpBinOp(ICmpInst &Cmp, const SimplifyQuery &SQ)

Try to fold icmp (binop), X or icmp X, (binop).

Definition InstCombineCompares.cpp:5127

Instruction * foldCmpLoadFromIndexedGlobal(LoadInst *LI, GetElementPtrInst *GEP, CmpInst &ICI, ConstantInt *AndCst=nullptr)

This is called when we see this pattern: cmp pred (load (gep GV, ...)), cmpcst where GV is a global v...

Definition InstCombineCompares.cpp:113

Instruction * foldICmpSubConstant(ICmpInst &Cmp, BinaryOperator *Sub, const APInt &C)

Fold icmp (sub X, Y), C.

Definition InstCombineCompares.cpp:2954

Instruction * foldICmpWithClamp(ICmpInst &Cmp, Value *X, MinMaxIntrinsic *Min)

Match and fold patterns like: icmp eq/ne X, min(max(X, Lo), Hi) which represents a range check and ca...

Definition InstCombineCompares.cpp:5792

Instruction * foldICmpInstWithConstantNotInt(ICmpInst &Cmp)

Handle icmp with constant (but not simple integer constant) RHS.

Definition InstCombineCompares.cpp:4293

bool SimplifyDemandedBits(Instruction *I, unsigned Op, const APInt &DemandedMask, KnownBits &Known, const SimplifyQuery &Q, unsigned Depth=0) override

This form of SimplifyDemandedBits simplifies the specified instruction operand if possible,...

Instruction * foldICmpShlConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)

Handle "(icmp eq/ne (shl AP2, A), AP1)" -> (icmp eq/ne A, TrailingZeros(AP1) - TrailingZeros(AP2)).

Definition InstCombineCompares.cpp:1016

Value * reassociateShiftAmtsOfTwoSameDirectionShifts(BinaryOperator *Sh0, const SimplifyQuery &SQ, bool AnalyzeForSignBitExtraction=false)

Instruction * foldICmpEqIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)

Fold an equality icmp with LLVM intrinsic and constant operand.

Definition InstCombineCompares.cpp:3794

Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false, bool SimplifyBothArms=false)

Given an instruction with a select as one operand and a constant as the other operand,...

Value * foldMultiplicationOverflowCheck(ICmpInst &Cmp)

Fold (-1 u/ x) u< y ((x * y) ?

Definition InstCombineCompares.cpp:4870

Instruction * foldICmpWithConstant(ICmpInst &Cmp)

Fold icmp Pred X, C.

Definition InstCombineCompares.cpp:1316

CmpInst * canonicalizeICmpPredicate(CmpInst &I)

If we have a comparison with a non-canonical predicate, if we can update all the users,...

Definition InstCombineCompares.cpp:7217

Instruction * eraseInstFromFunction(Instruction &I) override

Combiner aware instruction erasure.

Instruction * foldICmpWithZero(ICmpInst &Cmp)

Definition InstCombineCompares.cpp:1197

Instruction * foldICmpCommutative(CmpPredicate Pred, Value *Op0, Value *Op1, ICmpInst &CxtI)

Definition InstCombineCompares.cpp:7526

Instruction * foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)

Fold an icmp equality instruction with binary operator LHS and constant RHS: icmp eq/ne BO,...

Definition InstCombineCompares.cpp:3601

Instruction * foldICmpUsingBoolRange(ICmpInst &I)

If one operand of an icmp is effectively a bool (value range of {0,1}), then try to reduce patterns b...

Definition InstCombineCompares.cpp:7107

Instruction * foldICmpWithTrunc(ICmpInst &Cmp)

Definition InstCombineCompares.cpp:6280

Instruction * foldICmpIntrinsicWithConstant(ICmpInst &ICI, IntrinsicInst *II, const APInt &C)

Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C.

Definition InstCombineCompares.cpp:4185

bool matchThreeWayIntCompare(SelectInst *SI, Value *&LHS, Value *&RHS, ConstantInt *&Less, ConstantInt *&Equal, ConstantInt *&Greater)

Match a select chain which produces one of three values based on whether the LHS is less than,...

Definition InstCombineCompares.cpp:3299

Instruction * visitFCmpInst(FCmpInst &I)

Definition InstCombineCompares.cpp:8682

Instruction * foldICmpUsingKnownBits(ICmpInst &Cmp)

Try to fold the comparison based on range information we can get by checking whether bits are known t...

Definition InstCombineCompares.cpp:6894

Instruction * foldICmpDivConstant(ICmpInst &Cmp, BinaryOperator *Div, const APInt &C)

Fold icmp ({su}div X, Y), C.

Definition InstCombineCompares.cpp:2772

Instruction * foldIRemByPowerOfTwoToBitTest(ICmpInst &I)

If we have: icmp eq/ne (urem/srem x, y), 0 iff y is a power-of-two, we can replace this with a bit te...

Definition InstCombineCompares.cpp:1147

Instruction * foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI, Constant *RHSC)

Fold fcmp ([us]itofp x, cst) if possible.

Definition InstCombineCompares.cpp:8006

Instruction * foldICmpUDivConstant(ICmpInst &Cmp, BinaryOperator *UDiv, const APInt &C)

Fold icmp (udiv X, Y), C.

Definition InstCombineCompares.cpp:2739

Instruction * foldICmpAddOpConst(Value *X, const APInt &C, CmpPredicate Pred)

Fold "icmp pred (X+C), X".

Definition InstCombineCompares.cpp:907

Instruction * foldICmpWithCastOp(ICmpInst &ICmp)

Handle icmp (cast x), (cast or constant).

Definition InstCombineCompares.cpp:6436

Instruction * foldICmpTruncConstant(ICmpInst &Cmp, TruncInst *Trunc, const APInt &C)

Fold icmp (trunc X), C.

Definition InstCombineCompares.cpp:1442

Instruction * foldICmpAddConstant(ICmpInst &Cmp, BinaryOperator *Add, const APInt &C)

Fold icmp (add X, Y), C.

Definition InstCombineCompares.cpp:3127

Instruction * foldICmpMulConstant(ICmpInst &Cmp, BinaryOperator *Mul, const APInt &C)

Fold icmp (mul X, Y), C.

Definition InstCombineCompares.cpp:2182

Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)

Instruction * foldICmpXorConstant(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)

Fold icmp (xor X, Y), C.

Definition InstCombineCompares.cpp:1592

Instruction * foldSelectICmp(CmpPredicate Pred, SelectInst *SI, Value *RHS, const ICmpInst &I)

Definition InstCombineCompares.cpp:4323

Instruction * foldICmpInstWithConstantAllowPoison(ICmpInst &Cmp, const APInt &C)

Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...

Definition InstCombineCompares.cpp:3958

Instruction * foldIsMultipleOfAPowerOfTwo(ICmpInst &Cmp)

Fold icmp eq (num + mask) & ~mask, num to icmp eq (and num, mask), 0 Where mask is a low bit mask.

Definition InstCombineCompares.cpp:1286

Instruction * foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1, const APInt &C2)

Fold icmp (and (sh X, Y), C2), C1.

Definition InstCombineCompares.cpp:1693

Instruction * foldICmpBinOpWithConstantViaTruthTable(ICmpInst &Cmp, BinaryOperator *BO, const APInt &C)

Definition InstCombineCompares.cpp:3088

Instruction * foldICmpInstWithConstant(ICmpInst &Cmp)

Try to fold integer comparisons with a constant operand: icmp Pred X, C where X is some kind of instr...

Definition InstCombineCompares.cpp:3554

Instruction * foldICmpXorShiftConst(ICmpInst &Cmp, BinaryOperator *Xor, const APInt &C)

For power-of-2 C: ((X s>> ShiftC) ^ X) u< C --> (X + C) u< (C << 1) ((X s>> ShiftC) ^ X) u> (C - 1) -...

Definition InstCombineCompares.cpp:1664

Instruction * foldICmpShlConstant(ICmpInst &Cmp, BinaryOperator *Shl, const APInt &C)

Fold icmp (shl X, Y), C.

Definition InstCombineCompares.cpp:2323

Instruction * foldICmpAndConstant(ICmpInst &Cmp, BinaryOperator *And, const APInt &C)

Fold icmp (and X, Y), C.

Definition InstCombineCompares.cpp:1927

Instruction * foldICmpEquality(ICmpInst &Cmp)

Definition InstCombineCompares.cpp:6027

Instruction * foldICmpWithMinMax(Instruction &I, MinMaxIntrinsic *MinMax, Value *Z, CmpPredicate Pred)

Fold icmp Pred min|max(X, Y), Z.

Definition InstCombineCompares.cpp:5639

bool dominatesAllUses(const Instruction *DI, const Instruction *UI, const BasicBlock *DB) const

True when DB dominates all uses of DI except UI.

Definition InstCombineCompares.cpp:6791

bool foldAllocaCmp(AllocaInst *Alloca)

Definition InstCombineCompares.cpp:829

Instruction * visitICmpInst(ICmpInst &I)

Definition InstCombineCompares.cpp:7642

OverflowResult computeOverflow(Instruction::BinaryOps BinaryOp, bool IsSigned, Value *LHS, Value *RHS, Instruction *CxtI) const

Definition InstCombineCompares.cpp:6518

Instruction * foldICmpWithDominatingICmp(ICmpInst &Cmp)

Canonicalize icmp instructions based on dominating conditions.

Definition InstCombineCompares.cpp:1366

bool replacedSelectWithOperand(SelectInst *SI, const ICmpInst *Icmp, const unsigned SIOpd)

Try to replace select with select operand SIOpd in SI-ICmp sequence.

Definition InstCombineCompares.cpp:6866

Instruction * foldICmpShrConstConst(ICmpInst &I, Value *ShAmt, const APInt &C1, const APInt &C2)

Handle "(icmp eq/ne (ashr/lshr AP2, A), AP1)" -> (icmp eq/ne A, Log2(AP2/AP1)) -> (icmp eq/ne A,...

Definition InstCombineCompares.cpp:957

void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)

Freely adapt every user of V as-if V was changed to !V.

Instruction * foldICmpAndConstConst(ICmpInst &Cmp, BinaryOperator *And, const APInt &C1)

Fold icmp (and X, C2), C1.

Definition InstCombineCompares.cpp:1780

Instruction * foldICmpBitCast(ICmpInst &Cmp)

Definition InstCombineCompares.cpp:3400

Instruction * foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond, Instruction &I)

Fold comparisons between a GEP instruction and something else.

Definition InstCombineCompares.cpp:645

The core instruction combiner logic.

OverflowResult computeOverflowForSignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const

unsigned ComputeMaxSignificantBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const

IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy

An IRBuilder that automatically inserts new instructions into the worklist.

bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)

Return true if the specified value is free to invert (apply ~ to).

OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS, const Instruction *CxtI, bool IsNSW=false) const

static unsigned getComplexity(Value *V)

Assign a complexity or rank value to LLVM Values.

Instruction * replaceInstUsesWith(Instruction &I, Value *V)

A combiner-aware RAUW-like routine.

uint64_t MaxArraySizeForCombine

Maximum size of array considered when transforming.

OverflowResult computeOverflowForSignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CxtI) const

static Constant * SubOne(Constant *C)

Subtract one from a Constant.

OverflowResult computeOverflowForUnsignedSub(const Value *LHS, const Value *RHS, const Instruction *CxtI) const

static bool isCanonicalPredicate(CmpPredicate Pred)

Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...

void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const

bool canFreelyInvertAllUsersOf(Instruction *V, Value *IgnoredUser)

Given i1 V, can every user of V be freely adapted if V is changed to !V ?

void addToWorklist(Instruction *I)

Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)

Replace operand of instruction and add old operand to the worklist.

OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS, const Instruction *CxtI) const

OverflowResult computeOverflowForUnsignedAdd(const WithCache< const Value * > &LHS, const WithCache< const Value * > &RHS, const Instruction *CxtI) const

Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)

const SimplifyQuery & getSimplifyQuery() const

bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero=false, const Instruction *CxtI=nullptr, unsigned Depth=0)

LLVM_ABI bool hasNoNaNs() const LLVM_READONLY

Determine whether the no-NaNs flag is set.

LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY

Determine whether the no unsigned wrap flag is set.

LLVM_ABI bool hasNoInfs() const LLVM_READONLY

Determine whether the no-infs flag is set.

bool isArithmeticShift() const

Return true if this is an arithmetic shift right.

LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY

Determine whether the no signed wrap flag is set.

LLVM_ABI bool isCommutative() const LLVM_READONLY

Return true if the instruction is commutative:

LLVM_ABI bool isExact() const LLVM_READONLY

Determine whether the exact flag is set.

unsigned getOpcode() const

Returns a member of one of the enums like Instruction::Add.

static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)

This static method is the primary way of constructing an IntegerType.

A wrapper class for inspecting calls to intrinsic functions.

Intrinsic::ID getIntrinsicID() const

Return the intrinsic ID of this intrinsic.

An instruction for reading from memory.

bool isVolatile() const

Return true if this is a load from a volatile memory location.

This class represents min/max intrinsics.

static bool isMin(Intrinsic::ID ID)

Whether the intrinsic is a smin or umin.

static bool isSigned(Intrinsic::ID ID)

Whether the intrinsic is signed or unsigned.

A Module instance is used to store all the information related to an LLVM module.

void addIncoming(Value *V, BasicBlock *BB)

Add an incoming value to the end of the PHI list.

static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...

Represents a saturating add/sub intrinsic.

This class represents the LLVM 'select' instruction.

static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)

A vector that has set insertion semantics.

size_type size() const

Determine the number of elements in the SetVector.

bool contains(const_arg_type key) const

Check if the SetVector contains the given key.

bool insert(const value_type &X)

Insert a new element into the SetVector.

This instruction constructs a fixed permutation of two input vectors.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

reference emplace_back(ArgTypes &&... Args)

void push_back(const T &Elt)

reverse_iterator rbegin()

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

This class represents a truncation of integer types.

bool hasNoSignedWrap() const

Test whether this operation is known to never undergo signed overflow, aka the nsw property.

bool hasNoUnsignedWrap() const

Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.

The instances of the Type class are immutable: once they are created, they are never changed.

bool isVectorTy() const

True if this is an instance of VectorType.

bool isIntOrIntVectorTy() const

Return true if this is an integer type or a vector of integer types.

bool isPointerTy() const

True if this is an instance of PointerType.

bool isPPC_FP128Ty() const

Return true if this is powerpc long double.

Type * getScalarType() const

If this is a vector type, return the element type, otherwise return 'this'.

LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

Return the basic size of this type if it is a primitive type.

LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const

Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...

LLVMContext & getContext() const

Return the LLVMContext in which this type was uniqued.

LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY

If this is a vector type, return the getPrimitiveSizeInBits value for the element type.

static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)

LLVM_ABI int getFPMantissaWidth() const

Return the width of the mantissa of this type.

LLVM_ABI const fltSemantics & getFltSemantics() const

A Use represents the edge between a Value definition and its users.

void setOperand(unsigned i, Value *Val)

Value * getOperand(unsigned i) const

unsigned getNumOperands() const

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

bool hasOneUse() const

Return true if there is exactly one use of this value.

iterator_range< user_iterator > users()

LLVM_ABI bool hasNUsesOrMore(unsigned N) const

Return true if this value has N uses or more.

LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const

Accumulate the constant offset this value has compared to a base pointer.

LLVM_ABI const Value * stripPointerCasts() const

Strip off pointer casts, all-zero GEPs and address space casts.

LLVM_ABI LLVMContext & getContext() const

All values hold a context through their type.

iterator_range< use_iterator > uses()

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

LLVM_ABI void takeName(Value *V)

Transfer the name from V to this value.

static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)

This static method is the primary way to construct an VectorType.

constexpr ScalarTy getFixedValue() const

constexpr bool isScalable() const

Returns whether the quantity is scaled by a runtime quantity (vscale).

const ParentTy * getParent() const

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

LLVM_ABI APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)

Return A unsign-divided by B, rounded by the given rounding mode.

LLVM_ABI APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM)

Return A sign-divided by B, rounded by the given rounding mode.

@ C

The default llvm calling convention, compatible with C.

LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})

Look up the Function declaration of the intrinsic id in the Module M.

SpecificConstantMatch m_ZeroInt()

Convenience matchers for specific integer values.

BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)

Matches a register negated by a G_SUB.

BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)

Matches a register not-ed by a G_XOR.

OneUse_match< SubPat > m_OneUse(const SubPat &SP)

cst_pred_ty< is_all_ones > m_AllOnes()

Match an integer or vector with all bits set.

cst_pred_ty< is_lowbit_mask > m_LowBitMask()

Match an integer or vector with only the low bit(s) set.

BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)

cst_pred_ty< is_negative > m_Negative()

Match an integer or vector of negative values.

BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)

class_match< BinaryOperator > m_BinOp()

Match an arbitrary binary operation and ignore it.

cst_pred_ty< is_sign_mask > m_SignMask()

Match an integer or vector with only the sign bit(s) set.

OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWAdd(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)

cst_pred_ty< is_power2 > m_Power2()

Match an integer or vector power-of-2.

BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)

match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)

class_match< Constant > m_Constant()

Match an arbitrary Constant and ignore it.

ap_match< APInt > m_APInt(const APInt *&Res)

Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.

BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)

Matches an And with LHS and RHS in either order.

CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)

Matches Trunc.

BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)

ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)

Match APInt while allowing poison in splat vector constants.

specific_intval< false > m_SpecificInt(const APInt &V)

Match a specific integer value or vector with all elements equal to the value.

match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(const OpTy &Op)

bool match(Val *V, const Pattern &P)

BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)

Matches integer division operations.

bind_ty< Instruction > m_Instruction(Instruction *&I)

Match an instruction, capturing it if we match.

cstfp_pred_ty< is_any_zero_fp > m_AnyZeroFP()

Match a floating-point negative zero or positive zero.

specificval_ty m_Specific(const Value *V)

Match if we have a specific specified value.

BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)

Matches logical shift operations.

specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)

ap_match< APFloat > m_APFloat(const APFloat *&Res)

Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...

CmpClass_match< LHS, RHS, ICmpInst, true > m_c_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)

Matches an ICmp with a predicate over LHS and RHS in either order.

OverflowingBinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap > m_NSWNeg(const ValTy &V)

Matches a 'Neg' as 'sub nsw 0, V'.

cst_pred_ty< is_nonnegative > m_NonNegative()

Match an integer or vector of non-negative values.

class_match< ConstantInt > m_ConstantInt()

Match an arbitrary ConstantInt and ignore it.

cst_pred_ty< is_one > m_One()

Match an integer 1 or a vector with all elements equal to 1.

IntrinsicID_match m_Intrinsic()

Match intrinsic calls like this: m_IntrinsicIntrinsic::fabs(m_Value(X))

ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)

Matches SelectInst.

ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)

Match a single index ExtractValue instruction.

BinOpPred_match< LHS, RHS, is_logical_shift_op > m_LogicalShift(const LHS &L, const RHS &R)

Matches logical shift operations.

match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)

Combine two pattern matchers matching L && R.

MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)

m_Intrinsic_Ty< Opnd0 >::Ty m_Sqrt(const Opnd0 &Op0)

BinaryOp_match< LHS, RHS, Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R)

Matches an Xor with LHS and RHS in either order.

BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)

deferredval_ty< Value > m_Deferred(Value *const &V)

Like m_Specific(), but works if the specific value to match is determined as part of the same match()...

NoWrapTrunc_match< OpTy, TruncInst::NoSignedWrap > m_NSWTrunc(const OpTy &Op)

Matches trunc nsw.

TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)

Matches ShuffleVectorInst independently of mask value.

ThreeOps_match< decltype(m_Value()), LHS, RHS, Instruction::Select, true > m_c_Select(const LHS &L, const RHS &R)

Match Select(C, LHS, RHS) or Select(C, RHS, LHS)

CastInst_match< OpTy, FPExtInst > m_FPExt(const OpTy &Op)

OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)

CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)

Matches ZExt.

OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)

OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)

MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)

match_immconstant_ty m_ImmConstant()

Match an arbitrary immediate Constant and ignore it.

cst_pred_ty< is_negated_power2_or_zero > m_NegatedPower2OrZero()

Match a integer or vector negated power-of-2.

NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)

Matches trunc nuw.

cst_pred_ty< custom_checkfn< APInt > > m_CheckedInt(function_ref< bool(const APInt &)> CheckFn)

Match an integer or vector where CheckFn(ele) for each element is true.

cst_pred_ty< is_lowbit_mask_or_zero > m_LowBitMaskOrZero()

Match an integer or vector with only the low bit(s) set.

BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)

Matches a Add with LHS and RHS in either order.

match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)

Match either "add" or "or disjoint".

CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)

CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)

Matches BitCast.

BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)

MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)

class_match< Value > m_Value()

Match an arbitrary value and ignore it.

Signum_match< Val_t > m_Signum(const Val_t &V)

Matches a signum pattern.

CastInst_match< OpTy, SIToFPInst > m_SIToFP(const OpTy &Op)

BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)

CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)

match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)

FNeg_match< OpTy > m_FNeg(const OpTy &X)

Match 'fneg X' as 'fsub -0.0, X'.

cstfp_pred_ty< is_pos_zero_fp > m_PosZeroFP()

Match a floating-point positive zero.

BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)

UAddWithOverflow_match< LHS_t, RHS_t, Sum_t > m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S)

Match an icmp instruction checking for unsigned overflow on addition.

m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)

BinOpPred_match< LHS, RHS, is_irem_op > m_IRem(const LHS &L, const RHS &R)

Matches integer remainder operations.

match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > > > m_MaxOrMin(const LHS &L, const RHS &R)

CastInst_match< OpTy, FPTruncInst > m_FPTrunc(const OpTy &Op)

auto m_Undef()

Match an arbitrary undef constant.

BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)

CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)

Matches SExt.

is_zero m_Zero()

Match any null constant or a vector with all elements equal to 0.

BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)

Matches an Or with LHS and RHS in either order.

ElementWiseBitCast_match< OpTy > m_ElementWiseBitCast(const OpTy &Op)

m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)

BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)

Matches a Mul with LHS and RHS in either order.

CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)

Matches PtrToInt.

BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)

match_unless< Ty > m_Unless(const Ty &M)

Match if the inner matcher does NOT match.

match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)

Combine two pattern matchers matching L || R.

cst_pred_ty< icmp_pred_with_threshold > m_SpecificInt_ICMP(ICmpInst::Predicate Predicate, const APInt &Threshold)

Match an integer or vector with every element comparing 'pred' (eg/ne/...) to Threshold.

This is an optimization pass for GlobalISel generic memory operations.

detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)

zip iterator for two or more iteratable types.

@ NeverOverflows

Never overflows.

@ AlwaysOverflowsHigh

Always overflows in the direction of signed/unsigned max value.

@ AlwaysOverflowsLow

Always overflows in the direction of signed/unsigned min value.

@ MayOverflow

May or may not overflow.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI bool isKnownNeverInfinity(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if the floating-point scalar value is not an infinity or if the floating-point vector val...

LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)

Given an exploded icmp instruction, return true if the comparison only checks the sign bit.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

LLVM_ABI Value * stripNullTest(Value *V)

Returns the inner value X if the expression has the form f(X) where f(X) == 0 if and only if X == 0,...

LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)

Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

LLVM_ABI Value * simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)

Given operands for an FCmpInst, fold the result or return null.

int ilogb(const APFloat &Arg)

Returns the exponent of the internal representation of the APFloat.

LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, bool UseInstrInfo=true, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)

Determine the possible constant range of an integer or vector of integer value.

LLVM_ABI bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if 'V & Mask' is known to be zero.

LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for an Add, fold the result or return null.

LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)

ConstantFoldConstant - Fold the constant using the specified DataLayout.

auto dyn_cast_or_null(const Y &Val)

LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)

Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...

unsigned Log2_32(uint32_t Value)

Return the floor log base 2 of the specified value, -1 if the value is zero.

int countl_zero(T Val)

Count number of 0's from the most significant bit to the least stopping at the first 1.

LLVM_ABI Value * emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)

Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...

constexpr unsigned MaxAnalysisRecursionDepth

LLVM_ABI Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)

Attempt to constant fold a unary operation with the specified operand.

LLVM_ABI bool isKnownNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Returns true if the given value is known be negative (i.e.

SelectPatternFlavor

Specific patterns of select instructions we can match.

LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)

Return true if V is poison given that ValAssumedPoison is already poison.

LLVM_ABI LinearExpression decomposeLinearExpression(const DataLayout &DL, Value *Ptr)

Decompose a pointer into a linear expression.

LLVM_ABI bool isFinite(const Loop *L)

Return true if this loop can be assumed to run for a finite number of iterations.

FPClassTest

Floating-point class tests, supported by 'is_fpclass' intrinsic.

APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)

Returns: X * 2^Exp for integral exponents.

LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)

Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...

LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)

Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...

LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)

Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...

bool none_of(R &&Range, UnaryPredicate P)

Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an ICmpInst, fold the result or return null.

LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)

Attempt to constant fold a cast with the specified operand.

LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)

Extract value of C at the given Offset reinterpreted as Ty.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)

Attempt to constant fold a binary operation with the specified operands.

LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)

Return true if the given value is known to be non-zero when defined.

constexpr T divideCeil(U Numerator, V Denominator)

Returns the integer ceil(Numerator / Denominator).

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for a BinaryOperator, fold the result or return null.

@ UMin

Unsigned integer min implemented in terms of select(cmp()).

@ Mul

Product of integers.

@ Xor

Bitwise or logical XOR of integers.

@ SMax

Signed integer max implemented in terms of select(cmp()).

@ SMin

Signed integer min implemented in terms of select(cmp()).

@ Sub

Subtraction of integers.

@ UMax

Unsigned integer max implemented in terms of select(cmp()).

LLVM_ABI bool isKnownNonEqual(const Value *V1, const Value *V2, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if the given values are known to be non-equal when defined.

DWARFExpression::Operation Op

LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)

PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...

constexpr unsigned BitWidth

LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)

Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...

auto count_if(R &&Range, UnaryPredicate P)

Wrapper function around std::count_if to count the number of times an element satisfying a given pred...

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

LLVM_ABI bool isKnownNeverNaN(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...

LLVM_ABI std::optional< std::pair< CmpPredicate, Constant * > > getFlippedStrictnessPredicateAndConstant(CmpPredicate Pred, Constant *C)

Convert an integer comparison with a constant RHS into an equivalent form with the strictness flipped...

bool all_equal(std::initializer_list< T > Values)

Returns true if all Values in the initializer lists are equal or the list.

LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)

Return true if the given value is known to have exactly one bit set when defined.

LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)

This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....

LLVM_ABI bool isKnownPositive(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Returns true if the given value is known be positive (i.e.

LLVM_ABI bool isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Returns true if the give value is known to be non-negative.

constexpr detail::IsaCheckPredicate< Types... > IsaPred

Function object wrapper for the llvm::isa type check.

LLVM_ABI std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)

Return true if RHS is known to be implied true by LHS.

std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)

Decompose an icmp into the form ((X & Mask) pred C) if possible.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

OffsetKind Kind

Definition InstCombineCompares.cpp:5916

Value * V2

Definition InstCombineCompares.cpp:5917

Value * V1

Definition InstCombineCompares.cpp:5917

Value * materialize(InstCombiner::BuilderTy &Builder) const

Definition InstCombineCompares.cpp:5929

bool isValid() const

Definition InstCombineCompares.cpp:5928

static OffsetResult value(Value *V)

Definition InstCombineCompares.cpp:5922

static OffsetResult select(Value *Cond, Value *TrueV, Value *FalseV)

Definition InstCombineCompares.cpp:5925

Value * V0

Definition InstCombineCompares.cpp:5917

static OffsetResult invalid()

Definition InstCombineCompares.cpp:5919

This callback is used in conjunction with PointerMayBeCaptured.

static CommonPointerBase compute(Value *LHS, Value *RHS)

Represent subnormal handling kind for floating point instruction inputs and outputs.

@ PreserveSign

The sign of a flushed-to-zero number is preserved in the sign of 0.

@ PositiveZero

Denormals are flushed to positive zero.

static constexpr DenormalMode getIEEE()

bool isNonNegative() const

Returns true if this value is known to be non-negative.

bool isZero() const

Returns true if value is all zero.

unsigned countMinTrailingZeros() const

Returns the minimum number of trailing zero bits.

unsigned countMaxTrailingZeros() const

Returns the maximum number of trailing zero bits possible.

APInt getSignedMaxValue() const

Return the maximal signed value possible given these KnownBits.

unsigned countMaxPopulation() const

Returns the maximum number of bits that could be one.

unsigned getBitWidth() const

Get the bit width of this value.

bool isConstant() const

Returns true if we know the value of all bits.

unsigned countMinLeadingZeros() const

Returns the minimum number of leading zero bits.

APInt getMaxValue() const

Return the maximal unsigned value possible given these KnownBits.

APInt getMinValue() const

Return the minimal unsigned value possible given these KnownBits.

bool isStrictlyPositive() const

Returns true if this value is known to be positive.

bool isNegative() const

Returns true if this value is known to be negative.

unsigned countMinPopulation() const

Returns the number of bits known to be one.

APInt getSignedMinValue() const

Return the minimal signed value possible given these KnownBits.

const APInt & getConstant() const

Returns the value when all bits have a known value.

Linear expression BasePtr + Index * Scale + Offset.

SelectPatternFlavor Flavor

static bool isMinOrMax(SelectPatternFlavor SPF)

When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?

SimplifyQuery getWithInstruction(const Instruction *I) const

A MapVector that performs no allocations if smaller than a certain size.

Capture information for a specific Use.