LLVM: lib/Analysis/InstructionSimplify.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

20

45#include

46#include

47using namespace llvm;

49

50#define DEBUG_TYPE "instsimplify"

51

53

54STATISTIC(NumExpand, "Number of expansions");

55STATISTIC(NumReassoc, "Number of reassociations");

56

58 unsigned);

63 unsigned);

72 unsigned);

74 unsigned);

82 unsigned MaxRecurse);

83

84

85

87

88

89

91

92

94 CmpInst *Cmp = dyn_cast(V);

95 if (!Cmp)

96 return false;

98 Value *CLHS = Cmp->getOperand(0), *CRHS = Cmp->getOperand(1);

99 if (CPred == Pred && CLHS == LHS && CRHS == RHS)

100 return true;

102 CRHS == LHS;

103}

104

105

106

107

108

109

112 unsigned MaxRecurse, Constant *TrueOrFalse) {

114 if (SimplifiedCmp == Cond) {

115

116 return TrueOrFalse;

118

119

120 return TrueOrFalse;

121 }

122 return SimplifiedCmp;

123}

124

125

128 unsigned MaxRecurse) {

131}

132

133

136 unsigned MaxRecurse) {

139}

140

141

142

146 unsigned MaxRecurse) {

147

148

149

150

151

152

155 return V;

156

157

160 return V;

161

162

166 return V;

167 return nullptr;

168}

169

170

173 if (I)

174

175 return true;

176

177

178 if (DT)

180

181

182

183 if (I->getParent()->isEntryBlock() && !isa(I) &&

184 !isa(I))

185 return true;

186

187 return false;

188}

189

190

191

192

196 auto *B = dyn_cast(V);

197 if (B || B->getOpcode() != OpcodeToExpand)

198 return nullptr;

199 Value *B0 = B->getOperand(0), *B1 = B->getOperand(1);

202 if (!L)

203 return nullptr;

206 if (!R)

207 return nullptr;

208

209

210 if ((L == B0 && R == B1) ||

212 ++NumExpand;

213 return B;

214 }

215

216

218 if (!S)

219 return nullptr;

220

221 ++NumExpand;

222 return S;

223}

224

225

226

231 unsigned MaxRecurse) {

232

233 if (!MaxRecurse--)

234 return nullptr;

235

236 if (Value *V = expandBinOp(Opcode, L, R, OpcodeToExpand, Q, MaxRecurse))

237 return V;

238 if (Value *V = expandBinOp(Opcode, R, L, OpcodeToExpand, Q, MaxRecurse))

239 return V;

240 return nullptr;

241}

242

243

244

248 unsigned MaxRecurse) {

250

251

252 if (!MaxRecurse--)

253 return nullptr;

254

257

258

259 if (Op0 && Op0->getOpcode() == Opcode) {

263

264

266

267

268 if (V == B)

269 return LHS;

270

272 ++NumReassoc;

273 return W;

274 }

275 }

276 }

277

278

279 if (Op1 && Op1->getOpcode() == Opcode) {

283

284

286

287

288 if (V == B)

289 return RHS;

290

292 ++NumReassoc;

293 return W;

294 }

295 }

296 }

297

298

300 return nullptr;

301

302

303 if (Op0 && Op0->getOpcode() == Opcode) {

307

308

310

311

312 if (V == A)

313 return LHS;

314

316 ++NumReassoc;

317 return W;

318 }

319 }

320 }

321

322

323 if (Op1 && Op1->getOpcode() == Opcode) {

327

328

330

331

332 if (V == C)

333 return RHS;

334

336 ++NumReassoc;

337 return W;

338 }

339 }

340 }

341

342 return nullptr;

343}

344

345

346

347

348

351 unsigned MaxRecurse) {

352

353 if (!MaxRecurse--)

354 return nullptr;

355

357 if (isa(LHS)) {

358 SI = cast(LHS);

359 } else {

360 assert(isa(RHS) && "No select instruction operand!");

361 SI = cast(RHS);

362 }

363

364

367 if (SI == LHS) {

368 TV = simplifyBinOp(Opcode, SI->getTrueValue(), RHS, Q, MaxRecurse);

369 FV = simplifyBinOp(Opcode, SI->getFalseValue(), RHS, Q, MaxRecurse);

370 } else {

371 TV = simplifyBinOp(Opcode, LHS, SI->getTrueValue(), Q, MaxRecurse);

372 FV = simplifyBinOp(Opcode, LHS, SI->getFalseValue(), Q, MaxRecurse);

373 }

374

375

376

377 if (TV == FV)

378 return TV;

379

380

382 return FV;

384 return TV;

385

386

387

388 if (TV == SI->getTrueValue() && FV == SI->getFalseValue())

389 return SI;

390

391

392

393

394 if ((FV && !TV) || (TV && !FV)) {

395

396

397 Instruction *Simplified = dyn_cast(FV ? FV : TV);

398 if (Simplified && Simplified->getOpcode() == unsigned(Opcode) &&

399 !Simplified->hasPoisonGeneratingFlags()) {

400

401

402

403 Value *UnsimplifiedBranch = FV ? SI->getTrueValue() : SI->getFalseValue();

404 Value *UnsimplifiedLHS = SI == LHS ? UnsimplifiedBranch : LHS;

405 Value *UnsimplifiedRHS = SI == LHS ? RHS : UnsimplifiedBranch;

406 if (Simplified->getOperand(0) == UnsimplifiedLHS &&

407 Simplified->getOperand(1) == UnsimplifiedRHS)

408 return Simplified;

409 if (Simplified->isCommutative() &&

410 Simplified->getOperand(1) == UnsimplifiedLHS &&

411 Simplified->getOperand(0) == UnsimplifiedRHS)

412 return Simplified;

413 }

414 }

415

416 return nullptr;

417}

418

419

420

421

422

423

424

425

426

427

430

431 if (!MaxRecurse--)

432 return nullptr;

433

434

435 if (!isa(LHS)) {

438 }

439 assert(isa(LHS) && "Not comparing with a select instruction!");

441 Value *Cond = SI->getCondition();

442 Value *TV = SI->getTrueValue();

443 Value *FV = SI->getFalseValue();

444

445

446

448 if (!TCmp)

449 return nullptr;

450

451

453 if (!FCmp)

454 return nullptr;

455

456

457

458 if (TCmp == FCmp)

459 return TCmp;

460

461

462

465

466 return nullptr;

467}

468

469

470

471

472

475 unsigned MaxRecurse) {

476

477 if (!MaxRecurse--)

478 return nullptr;

479

481 if (isa(LHS)) {

482 PI = cast(LHS);

483

485 return nullptr;

486 } else {

487 assert(isa(RHS) && "No PHI instruction operand!");

488 PI = cast(RHS);

489

491 return nullptr;

492 }

493

494

495 Value *CommonValue = nullptr;

497

499 continue;

506

507

508 if (!V || (CommonValue && V != CommonValue))

509 return nullptr;

510 CommonValue = V;

511 }

512

513 return CommonValue;

514}

515

516

517

518

519

522

523 if (!MaxRecurse--)

524 return nullptr;

525

526

527 if (!isa(LHS)) {

530 }

531 assert(isa(LHS) && "Not comparing with a phi instruction!");

533

534

536 return nullptr;

537

538

539 Value *CommonValue = nullptr;

543

545 continue;

546

547

548

550 MaxRecurse);

551

552

553 if (!V || (CommonValue && V != CommonValue))

554 return nullptr;

555 CommonValue = V;

556 }

557

558 return CommonValue;

559}

560

564 if (auto *CLHS = dyn_cast(Op0)) {

565 if (auto *CRHS = dyn_cast(Op1)) {

566 switch (Opcode) {

567 default:

568 break;

569 case Instruction::FAdd:

570 case Instruction::FSub:

571 case Instruction::FMul:

572 case Instruction::FDiv:

573 case Instruction::FRem:

574 if (Q.CxtI != nullptr)

576 }

578 }

579

580

583 }

584 return nullptr;

585}

586

587

588

592 return C;

593

594

595 if (isa(Op1))

596 return Op1;

597

598

600 return Op1;

601

602

604 return Op0;

605

606

609

610

611

612

616 return Y;

617

618

622

623

624

625

628 return Y;

629

630

632 return Op1;

633

634

637 return V;

638

639

642 return V;

643

644

645

646

647

648

649

650

651

652

653 return nullptr;

654}

655

658 return ::simplifyAddInst(Op0, Op1, IsNSW, IsNUW, Query, RecursionLimit);

659}

660

661

662

663

664

665

666

667

668

669

671 bool AllowNonInbounds = false) {

672 assert(V->getType()->isPtrOrPtrVectorTy());

673

675 V = V->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds);

676

677

678 return Offset.sextOrTrunc(DL.getIndexTypeSizeInBits(V->getType()));

679}

680

681

682

687

688

689

691 return nullptr;

692

693

694

695

696

698 if (auto *VecTy = dyn_cast(LHS->getType()))

700 return Res;

701}

702

703

704

705

706

709

711 return nullptr;

712

713 std::optional Imp =

715 if (Imp && *Imp) {

717 switch (Opcode) {

718 case Instruction::Sub:

719 case Instruction::Xor:

720 case Instruction::URem:

721 case Instruction::SRem:

723

724 case Instruction::SDiv:

725 case Instruction::UDiv:

726 return ConstantInt::get(Ty, 1);

727

728 case Instruction::And:

729 case Instruction::Or:

730

731 return Op1;

732 default:

733 break;

734 }

735 }

736 return nullptr;

737}

738

739

740

744 return C;

745

746

747

748 if (isa(Op0) || isa(Op1))

750

751

752

755

756

758 return Op0;

759

760

761 if (Op0 == Op1)

763

764

766

767 if (IsNUW)

769

772

773

774 if (IsNSW)

776

777

778 return Op1;

779 }

780 }

781

782

783

784 Value *X = nullptr, *Y = nullptr, *Z = Op1;

786

788

789 if (Value *W = simplifyBinOp(Instruction::Add, X, V, Q, MaxRecurse - 1)) {

790

791 ++NumReassoc;

792 return W;

793 }

794

796

797 if (Value *W = simplifyBinOp(Instruction::Add, Y, V, Q, MaxRecurse - 1)) {

798

799 ++NumReassoc;

800 return W;

801 }

802 }

803

804

805

806 X = Op0;

808

810

811 if (Value *W = simplifyBinOp(Instruction::Sub, V, Z, Q, MaxRecurse - 1)) {

812

813 ++NumReassoc;

814 return W;

815 }

816

818

819 if (Value *W = simplifyBinOp(Instruction::Sub, V, Y, Q, MaxRecurse - 1)) {

820

821 ++NumReassoc;

822 return W;

823 }

824 }

825

826

827

828 Z = Op0;

830

832

833 if (Value *W = simplifyBinOp(Instruction::Add, V, Y, Q, MaxRecurse - 1)) {

834

835 ++NumReassoc;

836 return W;

837 }

838

839

842 if (X->getType() == Y->getType())

843

845

847 Q, MaxRecurse - 1))

848

849 return W;

850

851

855 Q.DL);

856

857

860 return V;

861

862

863

864

865

866

867

868

869

870

872 return V;

873

874

875 if (IsNUW) {

879 return X;

880 }

881

882 return nullptr;

883}

884

887 return ::simplifySubInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);

888}

889

890

891

895 return C;

896

897

898 if (isa(Op1))

899 return Op1;

900

901

902

905

906

908 return Op0;

909

910

916 return X;

917

919

920

921 if (IsNSW)

922 return ConstantInt::getNullValue(Op0->getType());

923

924

925 if (MaxRecurse)

927 return V;

928 }

929

930

933 return V;

934

935

937 Instruction::Add, Q, MaxRecurse))

938 return V;

939

940

941

942 if (isa(Op0) || isa(Op1))

945 return V;

946

947

948

949 if (isa(Op0) || isa(Op1))

952 return V;

953

954 return nullptr;

955}

956

959 return ::simplifyMulInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);

960}

961

962

963

964

968 Constant *C = dyn_cast_or_null(V);

969 return (C && C->isAllOnesValue());

970}

971

972

973

975 unsigned MaxRecurse, bool IsSigned) {

976

977 if (!MaxRecurse--)

978 return false;

979

980 if (IsSigned) {

981

983 return true;

984

985

986

987

988

989

990

991

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

995

996

997

998 Constant *PosDividendC = ConstantInt::get(Ty, C->abs());

999 Constant *NegDividendC = ConstantInt::get(Ty, -C->abs());

1002 return true;

1003 }

1005

1006

1007

1008 if (C->isMinSignedValue())

1010

1011

1012

1013

1014 Constant *PosDivisorC = ConstantInt::get(Ty, C->abs());

1015 Constant *NegDivisorC = ConstantInt::get(Ty, -C->abs());

1018 return true;

1019 }

1020 return false;

1021 }

1022

1023

1024

1025

1026

1027

1031 return true;

1032

1033

1034

1035 return isICmpTrue(ICmpInst::ICMP_ULT, X, Y, Q, MaxRecurse);

1036}

1037

1038

1039

1042 unsigned MaxRecurse) {

1043 bool IsDiv = (Opcode == Instruction::SDiv || Opcode == Instruction::UDiv);

1044 bool IsSigned = (Opcode == Instruction::SDiv || Opcode == Instruction::SRem);

1045

1047

1048

1049

1050 if (Q.isUndefValue(Op1) || isa(Op1))

1052

1053

1054

1055

1058

1059

1060

1061 if (isa(Op0))

1062 return Op0;

1063

1064

1065

1068

1069

1070

1073

1074

1075

1076 if (Op0 == Op1)

1078

1080

1081

1082

1083

1084

1087

1088

1089

1090

1091

1092

1095

1096

1097

1098

1101 auto *Mul = cast(Op0);

1102

1103

1109 }

1110 }

1111

1112 if (isDivZero(Op0, Op1, Q, MaxRecurse, IsSigned))

1114

1116 return V;

1117

1118

1119

1120 if (isa(Op0) || isa(Op1))

1122 return V;

1123

1124

1125

1126 if (isa(Op0) || isa(Op1))

1128 return V;

1129

1130 return nullptr;

1131}

1132

1133

1136 unsigned MaxRecurse) {

1138 return C;

1139

1141 return V;

1142

1143 const APInt *DivC;

1145

1146

1147

1152 }

1153

1154

1155

1156

1159 (Opcode == Instruction::UDiv

1162 return X;

1163 }

1164

1165 return nullptr;

1166}

1167

1168

1172 return C;

1173

1175 return V;

1176

1177

1179 if ((Opcode == Instruction::SRem &&

1181 (Opcode == Instruction::URem &&

1184

1185 const APInt *C0;

1187

1188

1189 if (Opcode == Instruction::SRem

1192 return C.srem(*C0).isZero();

1193 })))

1196 return C.urem(*C0).isZero();

1197 }))))

1199 }

1200 }

1201 return nullptr;

1202}

1203

1204

1205

1208

1211

1212 return simplifyDiv(Instruction::SDiv, Op0, Op1, IsExact, Q, MaxRecurse);

1213}

1214

1217 return ::simplifySDivInst(Op0, Op1, IsExact, Q, RecursionLimit);

1218}

1219

1220

1221

1224 return simplifyDiv(Instruction::UDiv, Op0, Op1, IsExact, Q, MaxRecurse);

1225}

1226

1229 return ::simplifyUDivInst(Op0, Op1, IsExact, Q, RecursionLimit);

1230}

1231

1232

1233

1235 unsigned MaxRecurse) {

1236

1237

1240 return ConstantInt::getNullValue(Op0->getType());

1241

1242

1244 return ConstantInt::getNullValue(Op0->getType());

1245

1246 return simplifyRem(Instruction::SRem, Op0, Op1, Q, MaxRecurse);

1247}

1248

1250 return ::simplifySRemInst(Op0, Op1, Q, RecursionLimit);

1251}

1252

1253

1254

1256 unsigned MaxRecurse) {

1257 return simplifyRem(Instruction::URem, Op0, Op1, Q, MaxRecurse);

1258}

1259

1261 return ::simplifyURemInst(Op0, Op1, Q, RecursionLimit);

1262}

1263

1264

1266 Constant *C = dyn_cast(Amount);

1267 if (C)

1268 return false;

1269

1270

1272 return true;

1273

1274

1275

1276 const APInt *AmountC;

1278 return true;

1279

1280

1281

1282 if (isa(C) || isa(C)) {

1283 for (unsigned I = 0,

1284 E = cast(C->getType())->getNumElements();

1285 I != E; ++I)

1287 return false;

1288 return true;

1289 }

1290

1291 return false;

1292}

1293

1294

1295

1298 unsigned MaxRecurse) {

1300 return C;

1301

1302

1303 if (isa(Op0))

1304 return Op0;

1305

1306

1309

1310

1311

1312

1316 return Op0;

1317

1318

1321

1322

1323

1324 if (isa(Op0) || isa(Op1))

1326 return V;

1327

1328

1329

1330 if (isa(Op0) || isa(Op1))

1332 return V;

1333

1334

1335

1339

1340

1341

1344 return Op0;

1345

1346

1347 if (IsNSW) {

1348 assert(Opcode == Instruction::Shl && "Expected shl for nsw instruction");

1351

1356

1359 }

1360

1361 return nullptr;

1362}

1363

1364

1365

1367 Value *Op1, bool IsExact,

1370 simplifyShift(Opcode, Op0, Op1, false, Q, MaxRecurse))

1371 return V;

1372

1373

1374 if (Op0 == Op1)

1376

1377

1378

1381

1382

1383

1384 if (IsExact) {

1386 if (Op0Known.One[0])

1387 return Op0;

1388 }

1389

1390 return nullptr;

1391}

1392

1393

1394

1398 simplifyShift(Instruction::Shl, Op0, Op1, IsNSW, Q, MaxRecurse))

1399 return V;

1400

1402

1403

1406

1407

1411 return X;

1412

1413

1415 return Op0;

1416

1417

1418

1419

1420

1421

1422 if (IsNSW && IsNUW &&

1425

1426 return nullptr;

1427}

1428

1431 return ::simplifyShlInst(Op0, Op1, IsNSW, IsNUW, Q, RecursionLimit);

1432}

1433

1434

1435

1439 MaxRecurse))

1440 return V;

1441

1442

1445 return X;

1446

1447

1448

1449

1450

1451

1453 const APInt *ShRAmt, *ShLAmt;

1456 *ShRAmt == *ShLAmt) {

1459 if (ShRAmt->uge(EffWidthY))

1460 return X;

1461 }

1462

1463 return nullptr;

1464}

1465

1468 return ::simplifyLShrInst(Op0, Op1, IsExact, Q, RecursionLimit);

1469}

1470

1471

1472

1476 MaxRecurse))

1477 return V;

1478

1479

1480

1481

1485

1486

1489 return X;

1490

1491

1494 return Op0;

1495

1496 return nullptr;

1497}

1498

1501 return ::simplifyAShrInst(Op0, Op1, IsExact, Q, RecursionLimit);

1502}

1503

1504

1505

1507 ICmpInst *UnsignedICmp, bool IsAnd,

1510

1514 return nullptr;

1515

1517

1519

1521 if (match(UnsignedICmp,

1523 ICmpInst::isUnsigned(UnsignedPred)) {

1524

1525 if ((UnsignedPred == ICmpInst::ICMP_UGE ||

1526 UnsignedPred == ICmpInst::ICMP_ULE) &&

1527 EqPred == ICmpInst::ICMP_NE && !IsAnd)

1529

1530 if ((UnsignedPred == ICmpInst::ICMP_ULT ||

1531 UnsignedPred == ICmpInst::ICMP_UGT) &&

1532 EqPred == ICmpInst::ICMP_EQ && IsAnd)

1534

1535

1536

1537 if (EqPred == ICmpInst::ICMP_NE && (UnsignedPred == ICmpInst::ICMP_ULT ||

1538 UnsignedPred == ICmpInst::ICMP_UGT))

1539 return IsAnd ? UnsignedICmp : ZeroICmp;

1540

1541

1542

1543 if (EqPred == ICmpInst::ICMP_EQ && (UnsignedPred == ICmpInst::ICMP_ULE ||

1544 UnsignedPred == ICmpInst::ICMP_UGE))

1545 return IsAnd ? ZeroICmp : UnsignedICmp;

1546 }

1547

1548

1549

1550

1551 if (match(UnsignedICmp,

1553 if (UnsignedPred == ICmpInst::ICMP_UGE && IsAnd &&

1555 return UnsignedICmp;

1556 if (UnsignedPred == ICmpInst::ICMP_ULT && !IsAnd &&

1558 return UnsignedICmp;

1559 }

1560 }

1561

1563 ICmpInst::isUnsigned(UnsignedPred))

1564 ;

1565 else if (match(UnsignedICmp,

1567 ICmpInst::isUnsigned(UnsignedPred))

1568 UnsignedPred = ICmpInst::getSwappedPredicate(UnsignedPred);

1569 else

1570 return nullptr;

1571

1572

1573

1574 if (UnsignedPred == ICmpInst::ICMP_UGT && EqPred == ICmpInst::ICMP_EQ &&

1576 return IsAnd ? ZeroICmp : UnsignedICmp;

1577

1578

1579

1580 if (UnsignedPred == ICmpInst::ICMP_ULE && EqPred == ICmpInst::ICMP_NE &&

1582 return IsAnd ? UnsignedICmp : ZeroICmp;

1583

1584

1585

1586

1587

1588

1589

1590

1591 if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_NE)

1592 return IsAnd ? UnsignedICmp : ZeroICmp;

1593

1594

1595

1596 if (UnsignedPred == ICmpInst::ICMP_UGE && EqPred == ICmpInst::ICMP_EQ)

1597 return IsAnd ? ZeroICmp : UnsignedICmp;

1598

1599

1600 if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_EQ &&

1601 IsAnd)

1603

1604

1605 if (UnsignedPred == ICmpInst::ICMP_UGE && EqPred == ICmpInst::ICMP_NE &&

1606 !IsAnd)

1608

1609 return nullptr;

1610}

1611

1612

1613

1614

1616 bool IsAnd) {

1617

1619 return nullptr;

1620

1621 const APInt *C0, *C1;

1624 return nullptr;

1625

1628

1629

1630

1631 if (IsAnd && Range0.intersectWith(Range1).isEmptySet())

1633

1634

1635

1636 if (!IsAnd && Range0.unionWith(Range1).isFullSet())

1638

1639

1640

1641

1642

1643

1644 if (Range0.contains(Range1))

1645 return IsAnd ? Cmp1 : Cmp0;

1646 if (Range1.contains(Range0))

1647 return IsAnd ? Cmp0 : Cmp1;

1648

1649 return nullptr;

1650}

1651

1654

1656 const APInt *C0, *C1;

1659 return nullptr;

1660

1662 return nullptr;

1663

1664 auto *AddInst = cast(Op0->getOperand(0));

1665 if (AddInst->getOperand(1) != Op1->getOperand(1))

1666 return nullptr;

1667

1671

1672 const APInt Delta = *C1 - *C0;

1674 if (Delta == 2) {

1675 if (Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_SGT)

1677 if (Pred0 == ICmpInst::ICMP_SLT && Pred1 == ICmpInst::ICMP_SGT && IsNSW)

1679 }

1680 if (Delta == 1) {

1681 if (Pred0 == ICmpInst::ICMP_ULE && Pred1 == ICmpInst::ICMP_SGT)

1683 if (Pred0 == ICmpInst::ICMP_SLE && Pred1 == ICmpInst::ICMP_SGT && IsNSW)

1685 }

1686 }

1688 if (Delta == 2)

1689 if (Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_UGT)

1691 if (Delta == 1)

1692 if (Pred0 == ICmpInst::ICMP_ULE && Pred1 == ICmpInst::ICMP_UGT)

1694 }

1695

1696 return nullptr;

1697}

1698

1699

1701 bool IsAnd) {

1705 if (match(Cmp0, m_ICmp(Pred0, m_IntrinsicIntrinsic::ctpop(m_Value(X)),

1708 return nullptr;

1709

1710

1711 if (!IsAnd && Pred0 == ICmpInst::ICMP_EQ && Pred1 == ICmpInst::ICMP_NE)

1712 return Cmp1;

1713

1714 if (IsAnd && Pred0 == ICmpInst::ICMP_NE && Pred1 == ICmpInst::ICMP_EQ)

1715 return Cmp1;

1716

1717 return nullptr;

1718}

1719

1723 return X;

1725 return X;

1726

1728 return X;

1729

1731 return X;

1733 return X;

1734

1736 return X;

1738 return X;

1739

1740 return nullptr;

1741}

1742

1745

1747 const APInt *C0, *C1;

1750 return nullptr;

1751

1753 return nullptr;

1754

1755 auto *AddInst = cast(Op0->getOperand(0));

1756 if (AddInst->getOperand(1) != Op1->getOperand(1))

1757 return nullptr;

1758

1762

1763 const APInt Delta = *C1 - *C0;

1765 if (Delta == 2) {

1766 if (Pred0 == ICmpInst::ICMP_UGE && Pred1 == ICmpInst::ICMP_SLE)

1768 if (Pred0 == ICmpInst::ICMP_SGE && Pred1 == ICmpInst::ICMP_SLE && IsNSW)

1770 }

1771 if (Delta == 1) {

1772 if (Pred0 == ICmpInst::ICMP_UGT && Pred1 == ICmpInst::ICMP_SLE)

1774 if (Pred0 == ICmpInst::ICMP_SGT && Pred1 == ICmpInst::ICMP_SLE && IsNSW)

1776 }

1777 }

1779 if (Delta == 2)

1780 if (Pred0 == ICmpInst::ICMP_UGE && Pred1 == ICmpInst::ICMP_ULE)

1782 if (Delta == 1)

1783 if (Pred0 == ICmpInst::ICMP_UGT && Pred1 == ICmpInst::ICMP_ULE)

1785 }

1786

1787 return nullptr;

1788}

1789

1793 return X;

1795 return X;

1796

1798 return X;

1799

1801 return X;

1803 return X;

1804

1806 return X;

1808 return X;

1809

1810 return nullptr;

1811}

1812

1814 FCmpInst *RHS, bool IsAnd) {

1815 Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);

1816 Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1);

1818 return nullptr;

1819

1822 if ((PredL == FCmpInst::FCMP_ORD || PredL == FCmpInst::FCMP_UNO) &&

1823 ((FCmpInst::isOrdered(PredR) && IsAnd) ||

1824 (FCmpInst::isUnordered(PredR) && !IsAnd))) {

1825

1826

1827

1828

1829 if ((match(RHS0, AbsOrSelfLHS0) || match(RHS1, AbsOrSelfLHS0)) &&

1831 return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)

1834 }

1835

1837 if ((PredR == FCmpInst::FCMP_ORD || PredR == FCmpInst::FCMP_UNO) &&

1838 ((FCmpInst::isOrdered(PredL) && IsAnd) ||

1839 (FCmpInst::isUnordered(PredL) && !IsAnd))) {

1840

1841

1842

1843

1844 if ((match(LHS0, AbsOrSelfRHS0) || match(LHS1, AbsOrSelfRHS0)) &&

1846 return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)

1849 }

1850

1851 return nullptr;

1852}

1853

1855 Value *Op1, bool IsAnd) {

1856

1857 auto *Cast0 = dyn_cast(Op0);

1858 auto *Cast1 = dyn_cast(Op1);

1859 if (Cast0 && Cast1 && Cast0->getOpcode() == Cast1->getOpcode() &&

1860 Cast0->getSrcTy() == Cast1->getSrcTy()) {

1861 Op0 = Cast0->getOperand(0);

1862 Op1 = Cast1->getOperand(0);

1863 }

1864

1865 Value *V = nullptr;

1866 auto *ICmp0 = dyn_cast(Op0);

1867 auto *ICmp1 = dyn_cast(Op1);

1868 if (ICmp0 && ICmp1)

1871

1872 auto *FCmp0 = dyn_cast(Op0);

1873 auto *FCmp1 = dyn_cast(Op1);

1874 if (FCmp0 && FCmp1)

1876

1877 if (!V)

1878 return nullptr;

1879 if (!Cast0)

1880 return V;

1881

1882

1883

1884 if (auto *C = dyn_cast(V))

1886 Q.DL);

1887

1888 return nullptr;

1889}

1890

1893 bool AllowRefinement,

1895 unsigned MaxRecurse);

1896

1899 unsigned MaxRecurse) {

1900 assert((Opcode == Instruction::And || Opcode == Instruction::Or) &&

1901 "Must be and/or");

1906 return nullptr;

1907

1908 auto Simplify = [&](Value *Res) -> Value * {

1910

1911

1912

1913

1914 if (Pred ==

1915 (Opcode == Instruction::And ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE)) {

1916 if (Res == Absorber)

1917 return Absorber;

1919 return Op0;

1920 return nullptr;

1921 }

1922

1923

1924

1925

1926 if (Res == Absorber)

1927 return Op1;

1928 return nullptr;

1929 };

1930

1931

1932

1933

1935 true,

1936 nullptr, MaxRecurse))

1937 return Simplify(Res);

1939 true,

1940 nullptr, MaxRecurse))

1941 return Simplify(Res);

1942

1943 return nullptr;

1944}

1945

1946

1947

1951 assert(BinaryOperator::isBitwiseLogicOp(Opcode) && "Expected logic op");

1959

1960

1961

1963 return Opcode == Instruction::And ? ConstantInt::getNullValue(Ty)

1964 : ConstantInt::getAllOnesValue(Ty);

1965 }

1966 }

1967 return nullptr;

1968}

1969

1970

1973 unsigned MaxRecurse) {

1974

1977

1978

1980 return Op1;

1981

1982

1986 return X;

1987

1988

1989

1990

1992 return Op1;

1993

1994

1997 return Op1;

1998

1999

2000

2004

2005

2006

2007 const APInt *Shift1, *Shift2;

2012 Shift1->uge(*Shift2))

2014

2017 return V;

2018

2019 return nullptr;

2020}

2021

2022

2023

2025 unsigned MaxRecurse) {

2027 return C;

2028

2029

2030 if (isa(Op1))

2031 return Op1;

2032

2033

2036

2037

2038 if (Op0 == Op1)

2039 return Op0;

2040

2041

2044

2045

2047 return Op0;

2048

2050 return Res;

2052 return Res;

2053

2055 return V;

2056

2057

2058 const APInt *Mask;

2059 const APInt *ShAmt;

2062

2063

2065 (~(*Mask)).lshr(*ShAmt).isZero())

2066 return Op0;

2067

2068

2069

2071 (~(*Mask)).shl(*ShAmt).isZero())

2072 return Op0;

2073 }

2074

2075

2076 const APInt *PowerC;

2081 Q.DT)) {

2083

2085 return ConstantInt::getNullValue(Op1->getType());

2086 }

2087

2089 return V;

2090

2091

2094 return V;

2095

2096

2098 Instruction::Or, Q, MaxRecurse))

2099 return V;

2100

2101

2103 Instruction::Xor, Q, MaxRecurse))

2104 return V;

2105

2106 if (isa(Op0) || isa(Op1)) {

2108

2110 return Op1;

2112 return Op0;

2113 }

2114

2115

2116

2119 return V;

2120 }

2121

2122

2123

2124 if (isa(Op0) || isa(Op1))

2127 return V;

2128

2129

2130

2131

2132

2133

2134

2135

2136

2137

2138

2139 Value *XShifted;

2148 if (EffWidthY <= ShftCnt) {

2153

2154

2156 return Y;

2158 return XShifted;

2159 }

2160 }

2161

2162

2163

2170

2171 const APInt *C1;

2173

2177

2180

2181 if (*Implied == true)

2182 return Op0;

2183

2184 if (*Implied == false)

2186 }

2188

2189 if (*Implied)

2190 return Op1;

2191

2192 if (!*Implied)

2194 }

2195 }

2196

2198 return V;

2199

2200 return nullptr;

2201}

2202

2204 return ::simplifyAndInst(Op0, Op1, Q, RecursionLimit);

2205}

2206

2207

2209 assert(X->getType() == Y->getType() && "Expected same type for 'or' ops");

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

2211

2212

2214 return ConstantInt::getAllOnesValue(Ty);

2215

2216

2218 return ConstantInt::getAllOnesValue(Ty);

2219

2220

2222 return X;

2223

2225

2226

2227

2230 return Y;

2231

2232

2233

2236 return ConstantInt::getAllOnesValue(Ty);

2237

2238

2239

2240

2241

2244 return Y;

2245

2246

2247

2248

2249

2252 return X;

2253

2254

2255

2256

2257

2260 return ConstantInt::getAllOnesValue(Ty);

2261

2262

2263

2264

2265

2270 return NotA;

2271

2272

2273

2277 return NotA;

2278

2279

2280

2285 return NotAB;

2286

2287

2288

2292 return NotAB;

2293

2294 return nullptr;

2295}

2296

2297

2298

2300 unsigned MaxRecurse) {

2302 return C;

2303

2304

2305 if (isa(Op1))

2306 return Op1;

2307

2308

2309

2310

2313

2314

2315

2317 return Op0;

2318

2320 return R;

2322 return R;

2323

2325 return V;

2326

2327

2328

2329

2330

2339 C->ule(X->getType()->getScalarSizeInBits())) {

2340 return ConstantInt::getAllOnesValue(X->getType());

2341 }

2342 }

2343

2344

2345

2346

2347

2348

2352 return Op0;

2356 return Op1;

2357

2358

2359

2363 return Op0;

2367 return Op1;

2368

2371 return V;

2374 return V;

2375

2377 return V;

2378

2379

2380

2381

2383 return Op1;

2385 return Op0;

2386

2387

2390 return V;

2391

2392

2394 Instruction::And, Q, MaxRecurse))

2395 return V;

2396

2397 if (isa(Op0) || isa(Op1)) {

2399

2401 return Op1;

2403 return Op0;

2404 }

2405

2406

2407

2410 return V;

2411 }

2412

2413

2415 const APInt *C1, *C2;

2418 if (*C1 == ~*C2) {

2419

2420

2421

2422

2424 if (C2->isMask() &&

2426

2428 return A;

2429 }

2430

2432

2434 return B;

2435 }

2436 }

2437 }

2438

2439

2440

2441 if (isa(Op0) || isa(Op1))

2443 return V;

2444

2445

2449

2451 if (std::optional Implied =

2453

2454 if (*Implied == false)

2455 return Op0;

2456

2457 if (*Implied == true)

2459 }

2460 if (std::optional Implied =

2462

2463 if (*Implied == false)

2464 return Op1;

2465

2466 if (*Implied == true)

2468 }

2469 }

2470

2472 return V;

2473

2474 return nullptr;

2475}

2476

2478 return ::simplifyOrInst(Op0, Op1, Q, RecursionLimit);

2479}

2480

2481

2482

2484 unsigned MaxRecurse) {

2486 return C;

2487

2488

2489 if (isa(Op1))

2490 return Op1;

2491

2492

2494 return Op1;

2495

2496

2498 return Op0;

2499

2500

2501 if (Op0 == Op1)

2503

2504

2507

2510

2513 return A;

2514

2515

2516

2517

2522 return NotA;

2523

2524 return nullptr;

2525 };

2526 if (Value *R = foldAndOrNot(Op0, Op1))

2527 return R;

2528 if (Value *R = foldAndOrNot(Op1, Op0))

2529 return R;

2530

2532 return V;

2533

2534

2537 return V;

2538

2539

2540

2541

2542

2543

2544

2545

2546

2547

2549 return V;

2550

2551

2552 {

2556 return X;

2557 }

2558

2559 return nullptr;

2560}

2561

2563 return ::simplifyXorInst(Op0, Op1, Q, RecursionLimit);

2564}

2565

2568}

2569

2570

2571

2572

2575 SelectInst *SI = dyn_cast(V);

2576 if (!SI)

2577 return nullptr;

2578 CmpInst *Cmp = dyn_cast(SI->getCondition());

2579 if (!Cmp)

2580 return nullptr;

2581 Value *CmpLHS = Cmp->getOperand(0), *CmpRHS = Cmp->getOperand(1);

2582 if (Pred == Cmp->getPredicate() && LHS == CmpLHS && RHS == CmpRHS)

2583 return Cmp;

2585 LHS == CmpRHS && RHS == CmpLHS)

2586 return Cmp;

2587 return nullptr;

2588}

2589

2590

2591

2593

2594

2595

2596

2597

2598 if (const AllocaInst *AI = dyn_cast(V))

2599 return AI->isStaticAlloca();

2600 if (const GlobalValue *GV = dyn_cast(V))

2601 return (GV->hasLocalLinkage() || GV->hasHiddenVisibility() ||

2602 GV->hasProtectedVisibility() || GV->hasGlobalUnnamedAddr()) &&

2603 !GV->isThreadLocal();

2604 if (const Argument *A = dyn_cast(V))

2605 return A->hasByValAttr();

2606 return false;

2607}

2608

2609

2610

2611

2613

2614

2615

2616

2617

2618

2619

2620

2621

2622

2623

2624

2625

2626

2627

2628

2629

2630

2631

2632

2633

2634

2635

2636

2637

2638 auto isByValArg = [](const Value *V) {

2639 const Argument *A = dyn_cast(V);

2640 return A && A->hasByValAttr();

2641 };

2642

2643

2644

2645 if (isByValArg(V1))

2646 return isa(V2) || isa(V2) || isByValArg(V2);

2647 if (isByValArg(V2))

2648 return isa(V1) || isa(V1) || isByValArg(V1);

2649

2650 return isa(V1) &&

2651 (isa(V2) || isa(V2));

2652}

2653

2654

2655

2656

2657

2658

2659

2660

2661

2662

2663

2664

2665

2666

2667

2668

2669

2670

2671

2672

2673

2674

2675

2676

2677

2678

2679

2680

2681

2687

2688

2689 switch (Pred) {

2690 default:

2691 return nullptr;

2692

2693

2696 break;

2697

2698

2699

2704

2705

2707 break;

2708 }

2709

2710

2711

2712

2713

2714

2715

2716

2717

2718

2720 unsigned IndexSize = DL.getIndexTypeSizeInBits(LHS->getType());

2721 APInt LHSOffset(IndexSize, 0), RHSOffset(IndexSize, 0);

2724

2725

2726

2730

2731

2733

2734

2735

2736

2737

2741 Opts.EvalMode = ObjectSizeOpts::Mode::Min;

2743 if (auto *I = dyn_cast(V))

2744 return I->getFunction();

2745 if (auto *A = dyn_cast(V))

2746 return A->getParent();

2747 return nullptr;

2752 APInt Dist = LHSOffset - RHSOffset;

2753 if (Dist.isNonNegative() ? Dist.ult(LHSSize) : (-Dist).ult(RHSSize))

2756 }

2757 }

2758

2759

2760

2761

2762

2763

2767

2768

2771 };

2772

2773

2774

2775

2778 };

2779

2780 if ((IsNAC(LHSUObjs) && IsAllocDisjoint(RHSUObjs)) ||

2781 (IsNAC(RHSUObjs) && IsAllocDisjoint(LHSUObjs)))

2784

2785

2786

2787

2788

2789

2795 if (MI) {

2796

2797

2798

2799

2800 struct CustomCaptureTracker : public CaptureTracker {

2801 bool Captured = false;

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

2804 if (auto *ICmp = dyn_cast(U->getUser())) {

2805

2806

2807

2808 unsigned OtherIdx = 1 - U->getOperandNo();

2809 auto *LI = dyn_cast(ICmp->getOperand(OtherIdx));

2810 if (LI && isa(LI->getPointerOperand()))

2811 return false;

2812 }

2813

2814 Captured = true;

2815 return true;

2816 }

2817 };

2818 CustomCaptureTracker Tracker;

2820 if (!Tracker.Captured)

2823 }

2824 }

2825

2826

2827 return nullptr;

2828}

2829

2830

2836 return nullptr;

2837

2838

2839

2840

2841

2842 auto ExtractNotLHS = [](Value *V) -> Value * {

2845 return X;

2846 return nullptr;

2847 };

2848

2850 switch (Pred) {

2854 return LHS;

2855

2859 if (Value *X = ExtractNotLHS(LHS))

2860 return X;

2861 break;

2862

2866

2870

2871 default:

2872 break;

2873 }

2875 switch (Pred) {

2879 return LHS;

2880

2884 if (Value *X = ExtractNotLHS(LHS))

2885 return X;

2886 break;

2887

2891

2895

2896 default:

2897 break;

2898 }

2899 }

2900

2901 switch (Pred) {

2902 default:

2903 break;

2904 case ICmpInst::ICMP_UGE:

2907 break;

2908 case ICmpInst::ICMP_SGE:

2909

2910

2911

2912

2913

2914

2915

2918 break;

2919 case ICmpInst::ICMP_ULE:

2922 break;

2923 case ICmpInst::ICMP_SLE:

2924

2927 break;

2928 }

2929

2930 return nullptr;

2931}

2932

2933

2937 return nullptr;

2938

2940 switch (Pred) {

2941 default:

2943 case ICmpInst::ICMP_ULT:

2945 case ICmpInst::ICMP_UGE:

2947 case ICmpInst::ICMP_EQ:

2948 case ICmpInst::ICMP_ULE:

2951 break;

2952 case ICmpInst::ICMP_NE:

2953 case ICmpInst::ICMP_UGT:

2956 break;

2957 case ICmpInst::ICMP_SLT: {

2963 break;

2964 }

2965 case ICmpInst::ICMP_SLE: {

2971 break;

2972 }

2973 case ICmpInst::ICMP_SGE: {

2979 break;

2980 }

2981 case ICmpInst::ICMP_SGT: {

2987 break;

2988 }

2989 }

2990

2991 return nullptr;

2992}

2993

2997

3001 return nullptr;

3002

3003

3004

3005

3006

3008 bool TrueIfSigned;

3011 }

3012

3013

3019

3023 if (RHS_CR.contains(LHS_CR))

3027 }

3028

3029

3030

3031 const APInt *MulC;

3034 *MulC != 0 && C->urem(*MulC) != 0) ||

3036 *MulC != 0 && C->srem(*MulC) != 0)))

3037 return ConstantInt::get(ITy, Pred == ICmpInst::ICMP_NE);

3038

3039 return nullptr;

3040}

3041

3043

3044

3047 if (!Res.insert(V).second)

3048 return;

3049

3050

3051 if (++Depth > 1)

3052 return;

3053

3054 auto *I = dyn_cast(V);

3055 if (I)

3056 return;

3057

3064 }

3065 } else {

3067 switch (I->getOpcode()) {

3068 case Instruction::And:

3071 break;

3072 case Instruction::URem:

3073 case Instruction::UDiv:

3074 case Instruction::LShr:

3076 break;

3077 case Instruction::Call:

3078 if (match(I, m_IntrinsicIntrinsic::usub\_sat(m_Value(X))))

3080 break;

3081 default:

3082 break;

3083 }

3084 }

3085}

3086

3089 if (Pred != ICmpInst::ICMP_UGE && Pred != ICmpInst::ICMP_ULT)

3090 return nullptr;

3091

3092

3093

3098 for (Value *GV : GreaterValues)

3099 if (LowerValues.contains(GV))

3101 Pred == ICmpInst::ICMP_UGE);

3102 return nullptr;

3103}

3104

3107 unsigned MaxRecurse) {

3109

3111

3113 if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) {

3117 return Pred == ICmpInst::ICMP_SLT ? getTrue(ITy) : getFalse(ITy);

3119 return Pred == ICmpInst::ICMP_SLT ? getFalse(ITy) : getTrue(ITy);

3120 }

3121 }

3122

3123

3125 switch (Pred) {

3126 default:

3127 break;

3128 case ICmpInst::ICMP_SGT:

3129 case ICmpInst::ICMP_SGE: {

3132 break;

3133 [[fallthrough]];

3134 }

3135 case ICmpInst::ICMP_EQ:

3136 case ICmpInst::ICMP_UGT:

3137 case ICmpInst::ICMP_UGE:

3139 case ICmpInst::ICMP_SLT:

3140 case ICmpInst::ICMP_SLE: {

3143 break;

3144 [[fallthrough]];

3145 }

3146 case ICmpInst::ICMP_NE:

3147 case ICmpInst::ICMP_ULT:

3148 case ICmpInst::ICMP_ULE:

3150 }

3151 }

3152

3153

3154

3155

3156

3157

3158

3159

3160

3161

3162

3167 switch (Pred) {

3168 default:

3169 break;

3170 case ICmpInst::ICMP_EQ:

3171 case ICmpInst::ICMP_UGE:

3172 case ICmpInst::ICMP_UGT:

3174 case ICmpInst::ICMP_NE:

3175 case ICmpInst::ICMP_ULT:

3176 case ICmpInst::ICMP_ULE:

3178 }

3179 }

3180 }

3181

3182

3183

3184

3185

3186

3187

3188

3189

3190

3191 const APInt *C1, *C2;

3193 C1->ule(*C2)) ||

3198 if (Pred == ICmpInst::ICMP_UGT)

3200 if (Pred == ICmpInst::ICMP_ULE)

3202 }

3203

3204

3205

3208 return (Pred == ICmpInst::ICMP_EQ) ? getFalse(ITy) : getTrue(ITy);

3209

3210 return nullptr;

3211}

3212

3213

3214

3215

3216

3217

3218

3219

3220

3221

3222

3223

3224

3227

3229 return false;

3230

3231

3235 return false;

3236

3238 const APInt *C1, *C2;

3241 return false;

3242

3245}

3246

3247

3248

3249

3252 unsigned MaxRecurse) {

3255 if (MaxRecurse && (LBO || RBO)) {

3256

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

3258

3259 bool NoLHSWrapProblem = false, NoRHSWrapProblem = false;

3260 if (LBO && LBO->getOpcode() == Instruction::Add) {

3263 NoLHSWrapProblem =

3269 }

3270 if (RBO && RBO->getOpcode() == Instruction::Add) {

3273 NoRHSWrapProblem =

3279 }

3280

3281

3282 if ((A == RHS || B == RHS) && NoLHSWrapProblem)

3285 MaxRecurse - 1))

3286 return V;

3287

3288

3289 if ((C == LHS || D == LHS) && NoRHSWrapProblem)

3292 C == LHS ? D : C, Q, MaxRecurse - 1))

3293 return V;

3294

3295

3296 bool CanSimplify = (NoLHSWrapProblem && NoRHSWrapProblem) ||

3298 if (A && C && (A == C || A == D || B == C || B == D) && CanSimplify) {

3299

3301 if (A == C) {

3302

3303 Y = B;

3304 Z = D;

3305 } else if (A == D) {

3306

3307 Y = B;

3308 Z = C;

3309 } else if (B == C) {

3310

3311 Y = A;

3312 Z = D;

3313 } else {

3315

3316 Y = A;

3317 Z = C;

3318 }

3320 return V;

3321 }

3322 }

3323

3324 if (LBO)

3326 return V;

3327

3328 if (RBO)

3330 ICmpInst::getSwappedPredicate(Pred), RBO, LHS, Q, MaxRecurse))

3331 return V;

3332

3333

3337 if (C->isStrictlyPositive()) {

3338 if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_NE)

3340 if (Pred == ICmpInst::ICMP_SGE || Pred == ICmpInst::ICMP_EQ)

3342 }

3343 if (C->isNonNegative()) {

3344 if (Pred == ICmpInst::ICMP_SLE)

3346 if (Pred == ICmpInst::ICMP_SGT)

3348 }

3349 }

3350 }

3351

3352

3353

3354

3358

3359

3360

3361

3362

3363

3364

3365

3369 if (Pred == ICmpInst::ICMP_EQ)

3371 if (Pred == ICmpInst::ICMP_NE)

3373 }

3374 }

3375

3376

3377

3378

3380 if (Pred == ICmpInst::ICMP_UGT)

3382 if (Pred == ICmpInst::ICMP_ULE)

3384 }

3385

3386 if (!MaxRecurse || !LBO || !RBO || LBO->getOpcode() != RBO->getOpcode())

3387 return nullptr;

3388

3391 default:

3392 break;

3393 case Instruction::Shl: {

3396 if (!NUW || (ICmpInst::isSigned(Pred) && !NSW) ||

3398 break;

3400 RBO->getOperand(1), Q, MaxRecurse - 1))

3401 return V;

3402 break;

3403 }

3404

3405

3406

3407

3408

3409 case Instruction::And:

3410 case Instruction::Or: {

3411 const APInt *C1, *C2;

3417 Pred = ICmpInst::getSwappedPredicate(Pred);

3418 }

3420 if (Pred == ICmpInst::ICMP_ULE)

3422 if (Pred == ICmpInst::ICMP_UGT)

3425 if (Pred == ICmpInst::ICMP_SLE)

3427 if (Pred == ICmpInst::ICMP_SGT)

3429 }

3430 }

3431 }

3432 break;

3433 }

3434 }

3435 }

3436

3439 default:

3440 break;

3441 case Instruction::UDiv:

3442 case Instruction::LShr:

3443 if (ICmpInst::isSigned(Pred) || !Q.IIQ.isExact(LBO) ||

3445 break;

3447 RBO->getOperand(0), Q, MaxRecurse - 1))

3448 return V;

3449 break;

3450 case Instruction::SDiv:

3453 break;

3455 RBO->getOperand(0), Q, MaxRecurse - 1))

3456 return V;

3457 break;

3458 case Instruction::AShr:

3460 break;

3462 RBO->getOperand(0), Q, MaxRecurse - 1))

3463 return V;

3464 break;

3465 case Instruction::Shl: {

3468 if (!NUW && !NSW)

3469 break;

3470 if (!NSW && ICmpInst::isSigned(Pred))

3471 break;

3473 RBO->getOperand(0), Q, MaxRecurse - 1))

3474 return V;

3475 break;

3476 }

3477 }

3478 }

3479 return nullptr;

3480}

3481

3482

3483

3486 unsigned MaxRecurse) {

3490 CmpInst::Predicate EqP;

3491

3492

3494 if (A != RHS)

3497

3498 P = Pred;

3501 if (A != LHS)

3504

3508 if (A != RHS)

3511

3512

3516 if (A != LHS)

3519

3520

3521 P = Pred;

3522 }

3524

3525 switch (P) {

3526 default:

3527 break;

3530

3531

3533 return V;

3535 return V;

3536

3537 if (MaxRecurse)

3539 return V;

3540 break;

3544

3545

3547 return V;

3549 return V;

3550

3551 if (MaxRecurse)

3553 return V;

3554 break;

3555 }

3557

3560

3562 }

3563 }

3564

3565

3568 if (A != RHS)

3571

3572 P = Pred;

3575 if (A != LHS)

3578

3582 if (A != RHS)

3585

3586

3590 if (A != LHS)

3593

3594

3595 P = Pred;

3596 }

3598

3599 switch (P) {

3600 default:

3601 break;

3604

3605

3607 return V;

3609 return V;

3610

3611 if (MaxRecurse)

3613 return V;

3614 break;

3618

3619

3621 return V;

3623 return V;

3624

3625 if (MaxRecurse)

3627 return V;

3628 break;

3629 }

3634 }

3635 }

3636

3637

3638

3642 Pred = ICmpInst::getSwappedPredicate(Pred);

3643 }

3644

3648 (A == C || A == D || B == C || B == D)) {

3649

3652

3657 (A == C || A == D || B == C || B == D)) {

3658

3661

3664 }

3665

3666 return nullptr;

3667}

3668

3672

3673 if (!Q.AC || !Q.CxtI)

3674 return nullptr;

3675

3676 for (Value *AssumeBaseOp : {LHS, RHS}) {

3678 if (!AssumeVH)

3679 continue;

3680

3681 CallInst *Assume = cast(AssumeVH);

3683 Assume->getArgOperand(0), Predicate, LHS, RHS, Q.DL))

3686 }

3687 }

3688

3689 return nullptr;

3690}

3691

3694 auto *II = dyn_cast(LHS);

3695 if (II)

3696 return nullptr;

3697

3698 switch (II->getIntrinsicID()) {

3699 case Intrinsic::uadd_sat:

3700

3703 if (Pred == ICmpInst::ICMP_UGE)

3705 if (Pred == ICmpInst::ICMP_ULT)

3707 }

3708 return nullptr;

3709 case Intrinsic::usub_sat:

3710

3713 if (Pred == ICmpInst::ICMP_ULE)

3715 if (Pred == ICmpInst::ICMP_UGT)

3717 }

3718 return nullptr;

3719 default:

3720 return nullptr;

3721 }

3722}

3723

3724

3727 if (Instruction *I = dyn_cast(V))

3730

3731 if (const Argument *A = dyn_cast(V))

3732 return A->getRange();

3733 else if (const CallBase *CB = dyn_cast(V))

3734 return CB->getRange();

3735

3736 return std::nullopt;

3737}

3738

3739

3740

3744

3745 if (Constant *CLHS = dyn_cast(LHS)) {

3746 if (Constant *CRHS = dyn_cast(RHS))

3748

3749

3752 }

3753 assert(!isa(LHS) && "Unexpected icmp undef,%X");

3754

3756

3757

3758 if (isa(RHS))

3760

3761

3762

3763

3766

3767

3768

3771

3773 return V;

3774

3775

3776

3778 return V;

3779

3781 return V;

3782

3783

3784

3785 if (std::optional RhsCr = getRange(RHS, Q.IIQ))

3786 if (std::optional LhsCr = getRange(LHS, Q.IIQ)) {

3787 if (LhsCr->icmp(Pred, *RhsCr))

3789

3792 }

3793

3794

3795 if (isa(LHS) && (isa(RHS) || isa(RHS))) {

3800

3801

3802

3803 if (MaxRecurse && isa(LI) &&

3805 if (Constant *RHSC = dyn_cast(RHS)) {

3806

3809 Q, MaxRecurse - 1))

3810 return V;

3811 } else if (PtrToIntInst *RI = dyn_cast(RHS)) {

3812 if (RI->getOperand(0)->getType() == SrcTy)

3813

3815 MaxRecurse - 1))

3816 return V;

3817 }

3818 }

3819

3820 if (isa(LHS)) {

3821

3822

3823 if (ZExtInst *RI = dyn_cast(RHS)) {

3824 if (MaxRecurse && SrcTy == RI->getOperand(0)->getType())

3825

3828 RI->getOperand(0), Q, MaxRecurse - 1))

3829 return V;

3830 }

3831

3832 else if (SExtInst *RI = dyn_cast(RHS)) {

3833 if (SrcOp == RI->getOperand(0)) {

3834 if (Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_SGE)

3836 if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SLT)

3838 }

3839 }

3840

3841

3845

3846

3847

3850 assert(Trunc && "Constant-fold of ImmConstant should not fail");

3853 assert(RExt && "Constant-fold of ImmConstant should not fail");

3856 assert(AnyEq && "Constant-fold of ImmConstant should not fail");

3857

3858

3859

3860

3863 SrcOp, Trunc, Q, MaxRecurse - 1))

3864 return V;

3865

3866

3867

3869 switch (Pred) {

3870 default:

3872

3873 case ICmpInst::ICMP_EQ:

3874 case ICmpInst::ICMP_UGT:

3875 case ICmpInst::ICMP_UGE:

3877

3878 case ICmpInst::ICMP_NE:

3879 case ICmpInst::ICMP_ULT:

3880 case ICmpInst::ICMP_ULE:

3882

3883

3884

3885 case ICmpInst::ICMP_SGT:

3886 case ICmpInst::ICMP_SGE:

3889 Q.DL);

3890 case ICmpInst::ICMP_SLT:

3891 case ICmpInst::ICMP_SLE:

3894 Q.DL);

3895 }

3896 }

3897 }

3898 }

3899

3900 if (isa(LHS)) {

3901

3902

3903 if (SExtInst *RI = dyn_cast(RHS)) {

3904 if (MaxRecurse && SrcTy == RI->getOperand(0)->getType())

3905

3907 MaxRecurse - 1))

3908 return V;

3909 }

3910

3911 else if (ZExtInst *RI = dyn_cast(RHS)) {

3912 if (SrcOp == RI->getOperand(0)) {

3913 if (Pred == ICmpInst::ICMP_UGE || Pred == ICmpInst::ICMP_SLE)

3915 if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SGT)

3917 }

3918 }

3919

3920

3923

3924

3925

3928 assert(Trunc && "Constant-fold of ImmConstant should not fail");

3931 assert(RExt && "Constant-fold of ImmConstant should not fail");

3934 assert(AnyEq && "Constant-fold of ImmConstant should not fail");

3935

3936

3937

3941 return V;

3942

3943

3944

3946 switch (Pred) {

3947 default:

3949 case ICmpInst::ICMP_EQ:

3951 case ICmpInst::ICMP_NE:

3953

3954

3955

3956 case ICmpInst::ICMP_SGT:

3957 case ICmpInst::ICMP_SGE:

3960 Q.DL);

3961 case ICmpInst::ICMP_SLT:

3962 case ICmpInst::ICMP_SLE:

3965 Q.DL);

3966

3967

3968

3969 case ICmpInst::ICMP_UGT:

3970 case ICmpInst::ICMP_UGE:

3971

3972 if (MaxRecurse)

3975 MaxRecurse - 1))

3976 return V;

3977 break;

3978 case ICmpInst::ICMP_ULT:

3979 case ICmpInst::ICMP_ULE:

3980

3981 if (MaxRecurse)

3984 MaxRecurse - 1))

3985 return V;

3986 break;

3987 }

3988 }

3989 }

3990 }

3991 }

3992

3993

3994

3995

3998 return Pred == ICmpInst::ICMP_NE ? getTrue(ITy) : getFalse(ITy);

3999 }

4000

4002 return V;

4003

4005 return V;

4006

4008 return V;

4010 ICmpInst::getSwappedPredicate(Pred), RHS, LHS))

4011 return V;

4012

4014 return V;

4016 ICmpInst::getSwappedPredicate(Pred), RHS, LHS))

4017 return V;

4018

4020 return V;

4021

4022 if (std::optional Res =

4025

4026

4027

4030 return C;

4031 if (auto *CLHS = dyn_cast(LHS))

4032 if (auto *CRHS = dyn_cast(RHS))

4033 if (CLHS->getPointerOperandType() == CRHS->getPointerOperandType() &&

4037 CRHS->getPointerOperand(), Q))

4038 return C;

4039

4040

4041

4042 if (isa(LHS) || isa(RHS))

4044 return V;

4045

4046

4047

4048 if (isa(LHS) || isa(RHS))

4050 return V;

4051

4052 return nullptr;

4053}

4054

4058}

4059

4060

4061

4064 unsigned MaxRecurse) {

4066

4067 if (Constant *CLHS = dyn_cast(LHS)) {

4068 if (Constant *CRHS = dyn_cast(RHS))

4071

4072

4075 }

4076

4077

4079 if (Pred == FCmpInst::FCMP_FALSE)

4081 if (Pred == FCmpInst::FCMP_TRUE)

4083

4084

4085

4086 if (isa(LHS) || isa(RHS))

4088

4089

4090

4092

4093

4095 }

4096

4097

4103 }

4104

4105

4106

4107

4108

4109 if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO) {

4114

4117 return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD);

4118

4121 }

4122

4125 std::optional FullKnownClassLHS;

4126

4127

4128

4129 auto computeLHSClass = [=, &FullKnownClassLHS](FPClassTest InterestedFlags =

4131 if (FullKnownClassLHS)

4132 return *FullKnownClassLHS;

4134 };

4135

4136 if (C && Q.CxtI) {

4137

4138

4139

4140

4141

4144 if (ClassVal) {

4145 FullKnownClassLHS = computeLHSClass();

4146 if ((FullKnownClassLHS->KnownFPClasses & ClassTest) == fcNone)

4148 if ((FullKnownClassLHS->KnownFPClasses & ~ClassTest) == fcNone)

4150 }

4151 }

4152

4153

4154 if (C) {

4155

4156

4157 if (C->isNaN())

4159

4160

4161

4162

4163 if (C->isNegative() && C->isNegZero()) {

4165

4166

4167

4168 switch (Pred) {

4169 case FCmpInst::FCMP_UGE:

4170 case FCmpInst::FCMP_UGT:

4171 case FCmpInst::FCMP_UNE: {

4172 KnownFPClass KnownClass = computeLHSClass(Interested);

4173

4174

4177 break;

4178 }

4179 case FCmpInst::FCMP_OEQ:

4180 case FCmpInst::FCMP_OLE:

4181 case FCmpInst::FCMP_OLT: {

4182 KnownFPClass KnownClass = computeLHSClass(Interested);

4183

4184

4187 break;

4188 }

4189 default:

4190 break;

4191 }

4192 }

4193

4196 *C2 < *C) ||

4198 *C2 > *C)) {

4199 bool IsMaxNum =

4200 cast(LHS)->getIntrinsicID() == Intrinsic::maxnum;

4201

4202

4203 switch (Pred) {

4204 case FCmpInst::FCMP_OEQ:

4205 case FCmpInst::FCMP_UEQ:

4206

4207

4209 case FCmpInst::FCMP_ONE:

4210 case FCmpInst::FCMP_UNE:

4211

4212

4214 case FCmpInst::FCMP_OGE:

4215 case FCmpInst::FCMP_UGE:

4216 case FCmpInst::FCMP_OGT:

4217 case FCmpInst::FCMP_UGT:

4218

4219

4220

4221

4222 return ConstantInt::get(RetTy, IsMaxNum);

4223 case FCmpInst::FCMP_OLE:

4224 case FCmpInst::FCMP_ULE:

4225 case FCmpInst::FCMP_OLT:

4226 case FCmpInst::FCMP_ULT:

4227

4228

4229

4230

4231 return ConstantInt::get(RetTy, !IsMaxNum);

4232 default:

4233

4235 }

4236 }

4237 }

4238

4239

4240

4242 switch (Pred) {

4243 case FCmpInst::FCMP_OGE:

4244 case FCmpInst::FCMP_ULT: {

4247 Interested |= fcNan;

4248

4249 KnownFPClass Known = computeLHSClass(Interested);

4250

4251

4252

4256 break;

4257 }

4258 case FCmpInst::FCMP_UGE:

4259 case FCmpInst::FCMP_OLT: {

4261 KnownFPClass Known = computeLHSClass(Interested);

4262

4263

4264

4267 break;

4268 }

4269 default:

4270 break;

4271 }

4272 }

4273

4274

4275

4276 if (isa(LHS) || isa(RHS))

4278 return V;

4279

4280

4281

4282 if (isa(LHS) || isa(RHS))

4284 return V;

4285

4286 return nullptr;

4287}

4288

4292}

4293

4295 ArrayRef<std::pair<Value *, Value *>> Ops,

4297 bool AllowRefinement,

4299 unsigned MaxRecurse) {

4301 "If AllowRefinement=false then CanUseUndef=false");

4302 for (const auto &OpAndRepOp : Ops) {

4303

4304 if (isa(OpAndRepOp.first))

4305 return nullptr;

4306

4307

4308 if (V == OpAndRepOp.first)

4309 return OpAndRepOp.second;

4310 }

4311

4312 if (!MaxRecurse--)

4313 return nullptr;

4314

4315 auto *I = dyn_cast(V);

4316 if (I)

4317 return nullptr;

4318

4319

4320

4321 if (isa(I))

4322 return nullptr;

4323

4324

4325 if (match(I, m_IntrinsicIntrinsic::is\_constant()))

4326 return nullptr;

4327

4328

4329 if (isa(I))

4330 return nullptr;

4331

4332 for (const auto &OpAndRepOp : Ops) {

4333

4334

4335 if (OpAndRepOp.first->getType()->isVectorTy() &&

4337 return nullptr;

4338 }

4339

4340

4342 bool AnyReplaced = false;

4343 for (Value *InstOp : I->operands()) {

4345 InstOp, Ops, Q, AllowRefinement, DropFlags, MaxRecurse)) {

4347 AnyReplaced = InstOp != NewInstOp;

4348 } else {

4350 }

4351

4352

4353

4355 return nullptr;

4356 }

4357

4358 if (!AnyReplaced)

4359 return nullptr;

4360

4361 if (!AllowRefinement) {

4362

4363

4364

4365

4366 if (auto *BO = dyn_cast(I)) {

4367 unsigned Opcode = BO->getOpcode();

4368

4369

4370 if (!BO->getType()->isFPOrFPVectorTy()) {

4372 return NewOps[1];

4374 true))

4375 return NewOps[0];

4376 }

4377

4378

4379 if ((Opcode == Instruction::And || Opcode == Instruction::Or) &&

4380 NewOps[0] == NewOps[1]) {

4381

4382 if (auto *PDI = dyn_cast(BO)) {

4383 if (PDI->isDisjoint()) {

4384 if (!DropFlags)

4385 return nullptr;

4387 }

4388 }

4389 return NewOps[0];

4390 }

4391

4392

4393

4394

4395 if ((Opcode == Instruction::Sub || Opcode == Instruction::Xor) &&

4396 NewOps[0] == NewOps[1] &&

4397 any_of(Ops, [=](const auto &Rep) { return NewOps[0] == Rep.second; }))

4399

4400

4401

4402

4403

4404

4405

4406

4408 if ((NewOps[0] == Absorber || NewOps[1] == Absorber) &&

4410 [=](const auto &Rep) { return impliesPoison(BO, Rep.first); }))

4411 return Absorber;

4412 }

4413

4414 if (isa(I)) {

4415

4416

4418 return NewOps[0];

4419 }

4420 } else {

4421

4422

4423

4424

4425

4426

4427

4428

4429

4430 auto PreventSelfSimplify = [V](Value *Simplified) {

4431 return Simplified != V ? Simplified : nullptr;

4432 };

4433

4434 return PreventSelfSimplify(

4436 }

4437

4438

4439

4441 for (Value *NewOp : NewOps) {

4442 if (Constant *ConstOp = dyn_cast(NewOp))

4444 else

4445 return nullptr;

4446 }

4447

4448

4449

4450

4451

4452

4453

4454

4455

4456

4457 if (!AllowRefinement) {

4459

4460 if (auto *II = dyn_cast(I);

4461 II && II->getIntrinsicID() == Intrinsic::abs) {

4462 if (!ConstOps[0]->isNotMinSignedValue())

4463 return nullptr;

4464 } else

4465 return nullptr;

4466 }

4468 false);

4469 if (DropFlags && Res && I->hasPoisonGeneratingAnnotations())

4471 return Res;

4472 }

4473

4475 false);

4476}

4477

4480 bool AllowRefinement,

4482 unsigned MaxRecurse) {

4484 DropFlags, MaxRecurse);

4485}

4486

4489 bool AllowRefinement,

4491

4492

4493 if (!AllowRefinement)

4494 return ::simplifyWithOpReplaced(V, Op, RepOp, Q.getWithoutUndef(),

4496 return ::simplifyWithOpReplaced(V, Op, RepOp, Q, AllowRefinement, DropFlags,

4498}

4499

4500

4501

4503 const APInt *Y, bool TrueWhenUnset) {

4505

4506

4507

4509 *Y == ~*C)

4510 return TrueWhenUnset ? FalseVal : TrueVal;

4511

4512

4513

4515 *Y == ~*C)

4516 return TrueWhenUnset ? FalseVal : TrueVal;

4517

4518 if (Y->isPowerOf2()) {

4519

4520

4522 *Y == *C) {

4523

4524 if (TrueWhenUnset && cast(TrueVal)->isDisjoint())

4525 return nullptr;

4526 return TrueWhenUnset ? TrueVal : FalseVal;

4527 }

4528

4529

4530

4532 *Y == *C) {

4533

4534 if (!TrueWhenUnset && cast(FalseVal)->isDisjoint())

4535 return nullptr;

4536 return TrueWhenUnset ? TrueVal : FalseVal;

4537 }

4538 }

4539

4540 return nullptr;

4541}

4542

4546

4547 if (CmpRHS == TVal || CmpRHS == FVal) {

4549 Pred = ICmpInst::getSwappedPredicate(Pred);

4550 }

4551

4552

4553 if (CmpLHS == FVal) {

4555 Pred = ICmpInst::getInversePredicate(Pred);

4556 }

4557

4558

4559

4560 Value *X = CmpLHS, *Y = CmpRHS;

4561 bool PeekedThroughSelectShuffle = false;

4562 auto *Shuf = dyn_cast(FVal);

4563 if (Shuf && Shuf->isSelect()) {

4564 if (Shuf->getOperand(0) == Y)

4565 FVal = Shuf->getOperand(1);

4566 else if (Shuf->getOperand(1) == Y)

4567 FVal = Shuf->getOperand(0);

4568 else

4569 return nullptr;

4570 PeekedThroughSelectShuffle = true;

4571 }

4572

4573

4574 auto *MMI = dyn_cast(FVal);

4575 if (!MMI || TVal != X ||

4577 return nullptr;

4578

4579

4580

4581

4582

4583

4584

4585

4586

4587

4590 return MMI;

4591

4592

4593 if (PeekedThroughSelectShuffle)

4594 return nullptr;

4595

4596

4598 return MMI;

4599

4600

4602 return X;

4603

4604

4605

4606

4607

4610 return X;

4611

4612 return nullptr;

4613}

4614

4615

4616

4619 Value *FalseVal) {

4622 Res->Pred == ICmpInst::ICMP_EQ);

4623

4624 return nullptr;

4625}

4626

4627

4628

4630 ArrayRef<std::pair<Value *, Value *>> Replacements, Value *TrueVal,

4632 Value *SimplifiedFalseVal =

4634 false,

4635 nullptr, MaxRecurse);

4636 if (!SimplifiedFalseVal)

4637 SimplifiedFalseVal = FalseVal;

4638

4639 Value *SimplifiedTrueVal =

4641 true,

4642 nullptr, MaxRecurse);

4643 if (!SimplifiedTrueVal)

4644 SimplifiedTrueVal = TrueVal;

4645

4646 if (SimplifiedFalseVal == SimplifiedTrueVal)

4647 return FalseVal;

4648

4649 return nullptr;

4650}

4651

4652

4653

4655 Value *FalseVal,

4657 unsigned MaxRecurse) {

4659 Value *CmpLHS, *CmpRHS;

4661 return nullptr;

4662

4664 return V;

4665

4666

4667 if (Pred == ICmpInst::ICMP_NE) {

4668 Pred = ICmpInst::ICMP_EQ;

4670 }

4671

4672

4673

4674

4675 if (TrueVal->getType()->isIntOrIntVectorTy()) {

4679 X, Y)

4683 X->getType()->getScalarSizeInBits());

4685 return X;

4686 }

4687 }

4688

4689 if (Pred == ICmpInst::ICMP_EQ && match(CmpRHS, m_Zero())) {

4694 true))

4695 return V;

4696

4697

4701

4702

4703 if (match(TrueVal, isFsh) && FalseVal == X && CmpLHS == ShAmt)

4704 return X;

4705

4706

4707

4708

4709

4710

4711 auto isRotate =

4714

4715

4716 if (match(FalseVal, isRotate) && TrueVal == X && CmpLHS == ShAmt &&

4717 Pred == ICmpInst::ICMP_EQ)

4718 return FalseVal;

4719

4720

4721

4722 if (match(TrueVal, m_IntrinsicIntrinsic::abs(m_Specific(CmpLHS))) &&

4724 return FalseVal;

4725 if (match(TrueVal,

4726 m_Neg(m_IntrinsicIntrinsic::abs(m_Specific(CmpLHS)))) &&

4727 match(FalseVal, m_IntrinsicIntrinsic::abs(m_Specific(CmpLHS))))

4728 return FalseVal;

4729 }

4730

4731

4734 return V;

4735

4736

4737

4738

4739 if (Pred == ICmpInst::ICMP_EQ) {

4741 FalseVal, Q, MaxRecurse))

4742 return V;

4744 FalseVal, Q, MaxRecurse))

4745 return V;

4746

4749

4752

4754 {{X, CmpRHS}, {Y, CmpRHS}}, TrueVal, FalseVal, Q, MaxRecurse))

4755 return V;

4756 }

4757

4758

4761

4763 {{X, CmpRHS}, {Y, CmpRHS}}, TrueVal, FalseVal, Q, MaxRecurse))

4764 return V;

4765 }

4766 }

4767

4768 return nullptr;

4769}

4770

4771

4772

4775 unsigned MaxRecurse) {

4777 Value *CmpLHS, *CmpRHS;

4779 return nullptr;

4781

4782 bool IsEquiv = I->isEquivalence();

4783 if (I->isEquivalence(true)) {

4785 Pred = FCmpInst::getInversePredicate(Pred);

4786 IsEquiv = true;

4787 }

4788

4789

4790

4791 if (IsEquiv) {

4793 MaxRecurse))

4794 return V;

4796 MaxRecurse))

4797 return V;

4798 }

4799

4800

4801 if (CmpLHS == F && CmpRHS == T)

4803

4804 if (CmpLHS != T || CmpRHS != F)

4805 return nullptr;

4806

4807

4809

4810 if (Pred == FCmpInst::FCMP_OEQ)

4811 return F;

4812

4813

4814 if (Pred == FCmpInst::FCMP_UNE)

4815 return T;

4816 }

4817

4818 return nullptr;

4819}

4820

4821

4822

4825 if (auto *CondC = dyn_cast(Cond)) {

4826 if (auto *TrueC = dyn_cast(TrueVal))

4827 if (auto *FalseC = dyn_cast(FalseVal))

4829 return C;

4830

4831

4832 if (isa(CondC))

4834

4835

4837 return isa(FalseVal) ? FalseVal : TrueVal;

4838

4839

4840

4841

4842

4844 return TrueVal;

4846 return FalseVal;

4847 }

4848

4849 assert(Cond->getType()->isIntOrIntVectorTy(1) &&

4850 "Select must have bool or bool vector condition");

4851 assert(TrueVal->getType() == FalseVal->getType() &&

4852 "Select must have same types for true/false ops");

4853

4854 if (Cond->getType() == TrueVal->getType()) {

4855

4857 return Cond;

4858

4859

4861 return FalseVal;

4862

4863

4865 return TrueVal;

4866

4867

4871

4872

4874

4877

4880

4881

4883 return TrueVal;

4884

4886 return Cond;

4887

4888

4892 return X;

4895 return X;

4896 }

4897

4898

4900

4903

4906

4907

4909 return FalseVal;

4910

4912 return Cond;

4913 }

4914 }

4915

4916

4917 if (TrueVal == FalseVal)

4918 return TrueVal;

4919

4920 if (Cond == TrueVal) {

4921

4923 return Cond;

4924

4927 }

4928 if (Cond == FalseVal) {

4929

4931 return Cond;

4932

4935 }

4936

4937

4938

4939

4940

4941

4942 if (isa(TrueVal) ||

4944 return FalseVal;

4945

4946

4947 if (isa(FalseVal) ||

4949 return TrueVal;

4950

4951

4953 if (isa(TrueVal->getType()) &&

4956 unsigned NumElts =

4957 cast(TrueC->getType())->getNumElements();

4959 for (unsigned i = 0; i != NumElts; ++i) {

4960

4963 if (!TEltC || !FEltC)

4964 break;

4965

4966

4967

4968 if (TEltC == FEltC)

4970 else if (isa(TEltC) ||

4973 else if (isa(FEltC) ||

4976 else

4977 break;

4978 }

4979 if (NewC.size() == NumElts)

4981 }

4982

4985 return V;

4986

4988 return V;

4989

4991 if (Imp)

4992 return *Imp ? TrueVal : FalseVal;

4993

4994 return nullptr;

4995}

4996

4999 return ::simplifySelectInst(Cond, TrueVal, FalseVal, Q, RecursionLimit);

5000}

5001

5002

5003

5007

5008 unsigned AS =

5009 cast(Ptr->getType()->getScalarType())->getAddressSpace();

5010

5011

5012 if (Indices.empty())

5013 return Ptr;

5014

5015

5017 Type *GEPTy = Ptr->getType();

5019 for (Value *Op : Indices) {

5020

5021

5022 if (VectorType *VT = dyn_cast(Op->getType())) {

5023 GEPTy = VectorType::get(GEPTy, VT->getElementCount());

5024 break;

5025 }

5026 }

5027 }

5028

5029

5030 if (Ptr->getType() == GEPTy &&

5031 all_of(Indices, [](const auto *V) { return match(V, m_Zero()); }))

5032 return Ptr;

5033

5034

5035

5036 if (isa(Ptr) ||

5037 any_of(Indices, [](const auto *V) { return isa(V); }))

5039

5040

5043

5044 bool IsScalableVec =

5046 return isa(V->getType());

5047 });

5048

5049 if (Indices.size() == 1) {

5050 Type *Ty = SrcTy;

5051 if (!IsScalableVec && Ty->isSized()) {

5055

5056 if (TyAllocSize == 0 && Ptr->getType() == GEPTy)

5057 return Ptr;

5058

5059

5060

5061 if (Indices[0]->getType()->getScalarSizeInBits() ==

5063 auto CanSimplify = [GEPTy, &P, Ptr]() -> bool {

5064 return P->getType() == GEPTy &&

5066 };

5067

5068 if (TyAllocSize == 1 &&

5069 match(Indices[0],

5071 CanSimplify())

5072 return P;

5073

5074

5075

5079 TyAllocSize == 1ULL << C && CanSimplify())

5080 return P;

5081

5082

5083

5087 CanSimplify())

5088 return P;

5089 }

5090 }

5091 }

5092

5095 [](Value *Idx) { return match(Idx, m_Zero()); })) {

5096 unsigned IdxWidth =

5099 APInt BasePtrOffset(IdxWidth, 0);

5100 Value *StrippedBasePtr =

5101 Ptr->stripAndAccumulateInBoundsConstantOffsets(Q.DL, BasePtrOffset);

5102

5103

5104

5105

5106

5107

5110 !BasePtrOffset.isZero()) {

5111 auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset);

5113 }

5114

5117 !BasePtrOffset.isOne()) {

5118 auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset - 1);

5120 }

5121 }

5122 }

5123

5124

5125 if (!isa(Ptr) ||

5126 all\_of(Indices, [](Value *V) { return isa(V); }))

5127 return nullptr;

5128

5131 Indices);

5132

5133 auto *CE =

5136}

5137

5140 return ::simplifyGEPInst(SrcTy, Ptr, Indices, NW, Q, RecursionLimit);

5141}

5142

5143

5144

5148 if (Constant *CAgg = dyn_cast(Agg))

5149 if (Constant *CVal = dyn_cast(Val))

5151

5152

5153

5154 if (isa(Val) ||

5156 return Agg;

5157

5158

5160 if (EV->getAggregateOperand()->getType() == Agg->getType() &&

5161 EV->getIndices() == Idxs) {

5162

5163

5164 if (isa(Agg) ||

5167 return EV->getAggregateOperand();

5168

5169

5170 if (Agg == EV->getAggregateOperand())

5171 return Agg;

5172 }

5173

5174 return nullptr;

5175}

5176

5180 return ::simplifyInsertValueInst(Agg, Val, Idxs, Q, RecursionLimit);

5181}

5182

5185

5186 auto *VecC = dyn_cast(Vec);

5187 auto *ValC = dyn_cast(Val);

5188 auto *IdxC = dyn_cast(Idx);

5189 if (VecC && ValC && IdxC)

5191

5192

5193 if (auto *CI = dyn_cast(Idx)) {

5194 if (isa(Vec->getType()) &&

5195 CI->uge(cast(Vec->getType())->getNumElements()))

5197 }

5198

5199

5202

5203

5204

5205 if (isa(Val) ||

5207 return Vec;

5208

5209

5210 if (VecC && ValC && VecC->getSplatValue() == ValC)

5211 return Vec;

5212

5213

5214

5215

5217 return Vec;

5218

5219 return nullptr;

5220}

5221

5222

5223

5226 if (auto *CAgg = dyn_cast(Agg))

5228

5229

5230 unsigned NumIdxs = Idxs.size();

5231 for (auto *IVI = dyn_cast(Agg); IVI != nullptr;

5232 IVI = dyn_cast(IVI->getAggregateOperand())) {

5234 unsigned NumInsertValueIdxs = InsertValueIdxs.size();

5235 unsigned NumCommonIdxs = std::min(NumInsertValueIdxs, NumIdxs);

5236 if (InsertValueIdxs.slice(0, NumCommonIdxs) ==

5237 Idxs.slice(0, NumCommonIdxs)) {

5238 if (NumIdxs == NumInsertValueIdxs)

5239 return IVI->getInsertedValueOperand();

5240 break;

5241 }

5242 }

5243

5244 return nullptr;

5245}

5246

5249 return ::simplifyExtractValueInst(Agg, Idxs, Q, RecursionLimit);

5250}

5251

5252

5253

5256 auto *VecVTy = cast(Vec->getType());

5257 if (auto *CVec = dyn_cast(Vec)) {

5258 if (auto *CIdx = dyn_cast(Idx))

5260

5263 }

5264

5265

5266

5269

5270

5271

5272 if (auto *IdxC = dyn_cast(Idx)) {

5273

5274 unsigned MinNumElts = VecVTy->getElementCount().getKnownMinValue();

5275 if (isa(VecVTy) && IdxC->getValue().uge(MinNumElts))

5277

5278 if (IdxC->getValue().ult(MinNumElts))

5282 return Elt;

5283 } else {

5284

5285

5286

5287

5288 auto *IE = dyn_cast(Vec);

5289 if (IE && IE->getOperand(2) == Idx)

5290 return IE->getOperand(1);

5291

5292

5295 }

5296 return nullptr;

5297}

5298

5301 return ::simplifyExtractElementInst(Vec, Idx, Q, RecursionLimit);

5302}

5303

5304

5307

5308

5309

5310

5311

5312

5313 Value *CommonValue = nullptr;

5314 bool HasPoisonInput = false;

5315 bool HasUndefInput = false;

5317

5319 continue;

5320 if (isa(Incoming)) {

5321 HasPoisonInput = true;

5322 continue;

5323 }

5325

5326 HasUndefInput = true;

5327 continue;

5328 }

5329 if (CommonValue && Incoming != CommonValue)

5330 return nullptr;

5332 }

5333

5334

5335

5336 if (!CommonValue)

5339

5340 if (HasPoisonInput || HasUndefInput) {

5341

5342

5343

5345 return nullptr;

5346

5347

5348 if (HasUndefInput &&

5350 return nullptr;

5351 return CommonValue;

5352 }

5353

5354 return CommonValue;

5355}

5356

5359 if (auto *C = dyn_cast(Op))

5361

5362 if (auto *CI = dyn_cast(Op)) {

5363 auto *Src = CI->getOperand(0);

5364 Type *SrcTy = Src->getType();

5365 Type *MidTy = CI->getType();

5366 Type *DstTy = Ty;

5367 if (Src->getType() == Ty) {

5370 Type *SrcIntPtrTy =

5372 Type *MidIntPtrTy =

5374 Type *DstIntPtrTy =

5377 SrcIntPtrTy, MidIntPtrTy,

5378 DstIntPtrTy) == Instruction::BitCast)

5379 return Src;

5380 }

5381 }

5382

5383

5384 if (CastOpc == Instruction::BitCast)

5385 if (Op->getType() == Ty)

5386 return Op;

5387

5388

5390 if (CastOpc == Instruction::PtrToInt &&

5394 return X;

5395

5396 return nullptr;

5397}

5398

5401 return ::simplifyCastInst(CastOpc, Op, Ty, Q, RecursionLimit);

5402}

5403

5404

5405

5406

5408 int MaskVal, Value *RootVec,

5409 unsigned MaxRecurse) {

5410 if (!MaxRecurse--)

5411 return nullptr;

5412

5413

5414

5415 if (MaskVal == -1)

5416 return nullptr;

5417

5418

5419 int InVecNumElts = cast(Op0->getType())->getNumElements();

5420 int RootElt = MaskVal;

5421 Value *SourceOp = Op0;

5422 if (MaskVal >= InVecNumElts) {

5423 RootElt = MaskVal - InVecNumElts;

5424 SourceOp = Op1;

5425 }

5426

5427

5428

5429 if (auto *SourceShuf = dyn_cast(SourceOp)) {

5431 DestElt, SourceShuf->getOperand(0), SourceShuf->getOperand(1),

5432 SourceShuf->getMaskValue(RootElt), RootVec, MaxRecurse);

5433 }

5434

5435

5436

5437 if (!RootVec)

5438 RootVec = SourceOp;

5439

5440

5441 if (RootVec != SourceOp)

5442 return nullptr;

5443

5444

5445

5446 if (RootElt != DestElt)

5447 return nullptr;

5448

5449 return RootVec;

5450}

5451

5455 unsigned MaxRecurse) {

5458

5459 auto *InVecTy = cast(Op0->getType());

5460 unsigned MaskNumElts = Mask.size();

5461 ElementCount InVecEltCount = InVecTy->getElementCount();

5462

5463 bool Scalable = InVecEltCount.isScalable();

5464

5466 Indices.assign(Mask.begin(), Mask.end());

5467

5468

5469

5470 if (!Scalable) {

5471 bool MaskSelects0 = false, MaskSelects1 = false;

5473 for (unsigned i = 0; i != MaskNumElts; ++i) {

5474 if (Indices[i] == -1)

5475 continue;

5476 if ((unsigned)Indices[i] < InVecNumElts)

5477 MaskSelects0 = true;

5478 else

5479 MaskSelects1 = true;

5480 }

5481 if (!MaskSelects0)

5483 if (!MaskSelects1)

5485 }

5486

5487 auto *Op0Const = dyn_cast(Op0);

5488 auto *Op1Const = dyn_cast(Op1);

5489

5490

5491

5492

5493 if (Op0Const && Op1Const)

5495

5496

5497

5498

5499 if (!Scalable && Op0Const && !Op1Const) {

5503 }

5504

5505

5506

5507

5508

5509

5510

5515

5517 if (all_of(Indices, [InsertIndex](int MaskElt) {

5518 return MaskElt == InsertIndex || MaskElt == -1;

5519 })) {

5520 assert(isa(Op1) && "Expected undef operand 1 for splat");

5521

5522

5524 for (unsigned i = 0; i != MaskNumElts; ++i)

5525 if (Indices[i] == -1)

5528 }

5529 }

5530

5531

5532

5533 if (auto *OpShuf = dyn_cast(Op0))

5535 all_equal(OpShuf->getShuffleMask()))

5536 return Op0;

5537

5538

5539

5540 if (Scalable)

5541 return nullptr;

5542

5543

5544

5545

5547 return nullptr;

5548

5549

5550

5551

5552

5553 Value *RootVec = nullptr;

5554 for (unsigned i = 0; i != MaskNumElts; ++i) {

5555

5556

5557 RootVec =

5559

5560

5561 if (!RootVec || RootVec->getType() != RetTy)

5562 return nullptr;

5563 }

5564 return RootVec;

5565}

5566

5567

5571 return ::simplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit);

5572}

5573

5576 if (auto *C = dyn_cast(Op))

5578 return nullptr;

5579}

5580

5581

5582

5586 return C;

5587

5589

5591 return X;

5592

5593 return nullptr;

5594}

5595

5599}

5600

5601

5602

5604 Type *Ty = In->getType();

5605 if (auto *VecTy = dyn_cast(Ty)) {

5606 unsigned NumElts = VecTy->getNumElements();

5608 for (unsigned i = 0; i != NumElts; ++i) {

5609 Constant *EltC = In->getAggregateElement(i);

5610

5611

5612 if (EltC && isa(EltC))

5613 NewC[i] = EltC;

5614 else if (EltC && EltC->isNaN())

5615 NewC[i] = ConstantFP::get(

5616 EltC->getType(), cast(EltC)->getValue().makeQuiet());

5617 else

5619 }

5621 }

5622

5623

5624

5625 if (!In->isNaN())

5627

5628

5629

5630 if (isa(Ty)) {

5631 auto *Splat = In->getSplatValue();

5633 "Found a scalable-vector NaN but not a splat");

5635 }

5636

5637

5638

5639 return ConstantFP::get(Ty, cast(In)->getValue().makeQuiet());

5640}

5641

5642

5643

5644

5649

5650

5653

5654 for (Value *V : Ops) {

5658

5659

5660

5661

5662 if (FMF.noNaNs() && (IsNan || IsUndef))

5664 if (FMF.noInfs() && (IsInf || IsUndef))

5666

5668

5669

5670

5671

5672 if (IsUndef)

5674 if (IsNan)

5677 if (IsNan)

5679 }

5680 }

5681 return nullptr;

5682}

5683

5684

5685

5690 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {

5693 return C;

5694

5696 return C;

5697

5698

5699

5700

5701

5702

5707 return Op0;

5708

5709

5713 return Op0;

5714

5716 return nullptr;

5717

5719

5721 return Op1;

5722

5723

5724

5725

5726

5727

5728

5729

5733

5737 }

5738

5739

5740

5745 return X;

5746

5747 return nullptr;

5748}

5749

5750

5751

5756 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {

5759 return C;

5760

5762 return C;

5763

5764

5769 return Op0;

5770

5771

5775 return Op0;

5776

5777

5778

5782 return X;

5783

5784

5785

5790 return X;

5791

5793 return nullptr;

5794

5796

5797 if (Op0 == Op1)

5799

5800

5802 return Op0;

5803

5804

5806 return foldConstant(Instruction::FNeg, Op1, Q);

5807 }

5808

5809

5810

5814 return X;

5815

5816 return nullptr;

5817}

5818

5824 return C;

5825

5827 return nullptr;

5828

5829

5832

5833

5835 return Op0;

5836

5838

5841

5845

5846 if (Known.SignBit == false)

5847 return Op1;

5848

5849 if (Known.SignBit == true)

5850 return foldConstant(Instruction::FNeg, Op1, Q);

5851 }

5852 }

5853

5854

5855

5856

5857

5861 return X;

5862

5863 return nullptr;

5864}

5865

5866

5871 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {

5874 return C;

5875

5876

5877 return simplifyFMAFMul(Op0, Op1, FMF, Q, MaxRecurse, ExBehavior, Rounding);

5878}

5879

5884 return ::simplifyFAddInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,

5885 Rounding);

5886}

5887

5892 return ::simplifyFSubInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,

5893 Rounding);

5894}

5895

5900 return ::simplifyFMulInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,

5901 Rounding);

5902}

5903

5908 return ::simplifyFMAFMul(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,

5909 Rounding);

5910}

5911

5916 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {

5919 return C;

5920

5922 return C;

5923

5925 return nullptr;

5926

5927

5929 return Op0;

5930

5931

5932

5933

5936

5938

5939

5940 if (Op0 == Op1)

5941 return ConstantFP::get(Op0->getType(), 1.0);

5942

5943

5946 return X;

5947

5948

5949

5950

5953 return ConstantFP::get(Op0->getType(), -1.0);

5954

5955

5958 }

5959

5960 return nullptr;

5961}

5962

5967 return ::simplifyFDivInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,

5968 Rounding);

5969}

5970

5975 RoundingMode Rounding = RoundingMode::NearestTiesToEven) {

5978 return C;

5979

5981 return C;

5982

5984 return nullptr;

5985

5986

5987

5988

5990

5993

5996 }

5997

5998 return nullptr;

5999}

6000

6005 return ::simplifyFRemInst(Op0, Op1, FMF, Q, RecursionLimit, ExBehavior,

6006 Rounding);

6007}

6008

6009

6010

6011

6012

6014 unsigned MaxRecurse) {

6015 switch (Opcode) {

6016 case Instruction::FNeg:

6018 default:

6020 }

6021}

6022

6023

6024

6025

6028 unsigned MaxRecurse) {

6029 switch (Opcode) {

6030 case Instruction::FNeg:

6032 default:

6034 }

6035}

6036

6039}

6040

6043 return ::simplifyFPUnOp(Opcode, Op, FMF, Q, RecursionLimit);

6044}

6045

6046

6047

6050 switch (Opcode) {

6051 case Instruction::Add:

6053 MaxRecurse);

6054 case Instruction::Sub:

6056 MaxRecurse);

6057 case Instruction::Mul:

6059 MaxRecurse);

6060 case Instruction::SDiv:

6062 case Instruction::UDiv:

6064 case Instruction::SRem:

6066 case Instruction::URem:

6068 case Instruction::Shl:

6070 MaxRecurse);

6071 case Instruction::LShr:

6073 case Instruction::AShr:

6075 case Instruction::And:

6077 case Instruction::Or:

6079 case Instruction::Xor:

6081 case Instruction::FAdd:

6083 case Instruction::FSub:

6085 case Instruction::FMul:

6087 case Instruction::FDiv:

6089 case Instruction::FRem:

6091 default:

6093 }

6094}

6095

6096

6097

6098

6101 unsigned MaxRecurse) {

6102 switch (Opcode) {

6103 case Instruction::FAdd:

6105 case Instruction::FSub:

6107 case Instruction::FMul:

6109 case Instruction::FDiv:

6111 default:

6113 }

6114}

6115

6119}

6120

6124}

6125

6126

6132}

6133

6137}

6138

6140 switch (ID) {

6141 default:

6142 return false;

6143

6144

6145 case Intrinsic::fabs:

6146 case Intrinsic:🤣

6147 case Intrinsic::ceil:

6148 case Intrinsic::trunc:

6149 case Intrinsic::rint:

6150 case Intrinsic::nearbyint:

6151 case Intrinsic::round:

6152 case Intrinsic::roundeven:

6153 case Intrinsic::canonicalize:

6154 case Intrinsic::arithmetic_fence:

6155 return true;

6156 }

6157}

6158

6159

6160

6162 switch (ID) {

6163 default:

6164 return false;

6165

6166 case Intrinsic:🤣

6167 case Intrinsic::ceil:

6168 case Intrinsic::trunc:

6169 case Intrinsic::rint:

6170 case Intrinsic::nearbyint:

6171 case Intrinsic::round:

6172 case Intrinsic::roundeven:

6173 return true;

6174 }

6175}

6176

6180 APInt PtrOffset;

6182 return nullptr;

6183

6185

6186 auto *OffsetConstInt = dyn_cast(Offset);

6187 if (!OffsetConstInt || OffsetConstInt->getBitWidth() > 64)

6188 return nullptr;

6189

6191 DL.getIndexTypeSizeInBits(Ptr->getType()));

6192 if (OffsetInt.srem(4) != 0)

6193 return nullptr;

6194

6197 if (!Loaded)

6198 return nullptr;

6199

6200 auto *LoadedCE = dyn_cast(Loaded);

6201 if (!LoadedCE)

6202 return nullptr;

6203

6204 if (LoadedCE->getOpcode() == Instruction::Trunc) {

6205 LoadedCE = dyn_cast(LoadedCE->getOperand(0));

6206 if (!LoadedCE)

6207 return nullptr;

6208 }

6209

6210 if (LoadedCE->getOpcode() != Instruction::Sub)

6211 return nullptr;

6212

6213 auto *LoadedLHS = dyn_cast(LoadedCE->getOperand(0));

6214 if (!LoadedLHS || LoadedLHS->getOpcode() != Instruction::PtrToInt)

6215 return nullptr;

6216 auto *LoadedLHSPtr = LoadedLHS->getOperand(0);

6217

6220 APInt LoadedRHSOffset;

6222 DL) ||

6223 PtrSym != LoadedRHSSym || PtrOffset != LoadedRHSOffset)

6224 return nullptr;

6225

6226 return LoadedLHSPtr;

6227}

6228

6229

6231 bool IsStrict) {

6232

6233

6234 if (isa(Op0) || isa(Op1))

6235 return Op0;

6236

6237

6240

6241 if (!IsStrict) {

6242

6243

6244

6246 return Op0;

6247 }

6248

6251

6252

6253

6254

6255

6256

6257 if (C && (C->isZero() || C->isInfinity()))

6258 return Op0;

6259

6260

6261

6262 if (IsStrict)

6263 return nullptr;

6264

6265

6266 if (C && C->isNaN())

6267 return ConstantFP::get(Op0->getType(), C->makeQuiet());

6268

6269

6270

6271

6272

6274 return Op0;

6275

6276 return nullptr;

6277}

6278

6282

6285 if (auto *II = dyn_cast(Op0))

6286 if (II->getIntrinsicID() == IID)

6287 return II;

6288

6290

6291

6292

6293

6294

6295 auto *II = dyn_cast(Op0);

6298 return Op0;

6299 }

6300

6302 switch (IID) {

6303 case Intrinsic::fabs:

6305 return Op0;

6306 break;

6307 case Intrinsic::bswap:

6308

6310 return X;

6311 break;

6312 case Intrinsic::bitreverse:

6313

6315 return X;

6316 break;

6317 case Intrinsic::ctpop: {

6318

6320 Q.DT))

6321 return ConstantInt::get(Op0->getType(), 1);

6322

6323

6326 Q))

6327 return Op0;

6328 break;

6329 }

6330 case Intrinsic::exp:

6331

6332 if (Call->hasAllowReassoc() &&

6333 match(Op0, m_IntrinsicIntrinsic::log(m_Value(X))))

6334 return X;

6335 break;

6336 case Intrinsic::exp2:

6337

6338 if (Call->hasAllowReassoc() &&

6339 match(Op0, m_IntrinsicIntrinsic::log2(m_Value(X))))

6340 return X;

6341 break;

6342 case Intrinsic::exp10:

6343

6344 if (Call->hasAllowReassoc() &&

6345 match(Op0, m_IntrinsicIntrinsic::log10(m_Value(X))))

6346 return X;

6347 break;

6348 case Intrinsic:🪵

6349

6350 if (Call->hasAllowReassoc() &&

6351 match(Op0, m_IntrinsicIntrinsic::exp(m_Value(X))))

6352 return X;

6353 break;

6354 case Intrinsic::log2:

6355

6356 if (Call->hasAllowReassoc() &&

6357 (match(Op0, m_IntrinsicIntrinsic::exp2(m_Value(X))) ||

6360 return X;

6361 break;

6362 case Intrinsic::log10:

6363

6364

6365 if (Call->hasAllowReassoc() &&

6366 (match(Op0, m_IntrinsicIntrinsic::exp10(m_Value(X))) ||

6369 return X;

6370 break;

6371 case Intrinsic::vector_reverse:

6372

6374 return X;

6375

6377 return Op0;

6378 break;

6379 case Intrinsic::frexp: {

6380

6381 if (match(Op0, m_ExtractValue<0>(m_Value(X)))) {

6382 if (match(X, m_IntrinsicIntrinsic::frexp(m_Value())))

6383 return X;

6384 }

6385

6386 break;

6387 }

6388 default:

6389 break;

6390 }

6391

6392 return nullptr;

6393}

6394

6395

6396

6397

6401 return nullptr;

6402

6403 auto *MM0 = dyn_cast(Op0);

6404 if (!MM0)

6405 return nullptr;

6407

6408 if (Op1 == X || Op1 == Y ||

6410

6411 if (IID0 == IID)

6412 return MM0;

6413

6415 return Op1;

6416 }

6417 return nullptr;

6418}

6419

6420

6421

6422

6425 assert((IID == Intrinsic::maxnum || IID == Intrinsic::minnum ||

6426 IID == Intrinsic::maximum || IID == Intrinsic::minimum) &&

6427 "Unsupported intrinsic");

6428

6429 auto *M0 = dyn_cast(Op0);

6430

6431

6432

6433 if (M0 || M0->getIntrinsicID() != IID)

6434 return nullptr;

6435 Value *X0 = M0->getOperand(0);

6436 Value *Y0 = M0->getOperand(1);

6437

6438

6439

6440

6441

6442

6443 if (X0 == Op1 || Y0 == Op1)

6444 return M0;

6445

6446 auto *M1 = dyn_cast(Op1);

6447 if (M1)

6448 return nullptr;

6449 Value *X1 = M1->getOperand(0);

6450 Value *Y1 = M1->getOperand(1);

6452

6453

6454

6455

6456

6457

6458 if ((X0 == X1 && Y0 == Y1) || (X0 == Y1 && Y0 == X1))

6460 return M0;

6461

6462 return nullptr;

6463}

6464

6469 unsigned BitWidth = ReturnType->getScalarSizeInBits();

6470 switch (IID) {

6471 case Intrinsic::abs:

6472

6473

6474

6476 return Op0;

6477 break;

6478

6479 case Intrinsic::cttz: {

6482 return X;

6483 break;

6484 }

6485 case Intrinsic::ctlz: {

6488 return X;

6491 break;

6492 }

6493 case Intrinsic::ptrmask: {

6494 if (isa(Op0) || isa(Op1))

6496

6497

6498

6501

6504 "Invalid mask width");

6505

6506

6508 return Op0;

6509

6510

6511

6512

6514 return Op0;

6515

6519

6520

6521 APInt IrrelevantPtrBits =

6522 PtrKnown.Zero.zextOrTrunc(C->getType()->getScalarSizeInBits());

6524 Instruction::Or, C, ConstantInt::get(C->getType(), IrrelevantPtrBits),

6525 Q.DL);

6526 if (C != nullptr && C->isAllOnesValue())

6527 return Op0;

6528 }

6529 break;

6530 }

6531 case Intrinsic::smax:

6532 case Intrinsic::smin:

6533 case Intrinsic::umax:

6534 case Intrinsic::umin: {

6535

6536 if (Op0 == Op1)

6537 return Op0;

6538

6539

6542

6543

6545 return ConstantInt::get(

6547

6550

6551

6553 return ConstantInt::get(ReturnType, *C);

6554

6555

6556

6557

6560 return Op0;

6561

6562

6563

6564 auto *MinMax0 = dyn_cast(Op0);

6565 if (MinMax0 && MinMax0->getIntrinsicID() == IID) {

6566

6567 Value *M00 = MinMax0->getOperand(0), *M01 = MinMax0->getOperand(1);

6568 const APInt *InnerC;

6571 ICmpInst::getNonStrictPredicate(

6573 return Op0;

6574 }

6575 }

6576

6578 return V;

6580 return V;

6581

6585 return Op0;

6587 return Op1;

6588

6589 break;

6590 }

6591 case Intrinsic::scmp:

6592 case Intrinsic::ucmp: {

6593

6594

6597

6599 IID == Intrinsic::scmp ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;

6601 return ConstantInt::get(ReturnType, 1);

6602

6604 IID == Intrinsic::scmp ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;

6607

6608 break;

6609 }

6610 case Intrinsic::usub_with_overflow:

6611 case Intrinsic::ssub_with_overflow:

6612

6613

6614

6617 break;

6618 case Intrinsic::uadd_with_overflow:

6619 case Intrinsic::sadd_with_overflow:

6620

6621

6624 cast(ReturnType),

6627 }

6628 break;

6629 case Intrinsic::umul_with_overflow:

6630 case Intrinsic::smul_with_overflow:

6631

6632

6635

6636

6639 break;

6640 case Intrinsic::uadd_sat:

6641

6642

6645 [[fallthrough]];

6646 case Intrinsic::sadd_sat:

6647

6648

6649

6650

6653

6654

6656 return Op0;

6657

6659 return Op1;

6660 break;

6661 case Intrinsic::usub_sat:

6662

6665 [[fallthrough]];

6666 case Intrinsic::ssub_sat:

6667

6670

6672 return Op0;

6673 break;

6674 case Intrinsic::load_relative:

6675 if (auto *C0 = dyn_cast(Op0))

6676 if (auto *C1 = dyn_cast(Op1))

6678 break;

6679 case Intrinsic::powi:

6680 if (auto *Power = dyn_cast(Op1)) {

6681

6682 if (Power->isZero())

6683 return ConstantFP::get(Op0->getType(), 1.0);

6684

6685 if (Power->isOne())

6686 return Op0;

6687 }

6688 break;

6689 case Intrinsic::ldexp:

6691 case Intrinsic::copysign:

6692

6693 if (Op0 == Op1)

6694 return Op0;

6695

6696

6699 return Op1;

6700 break;

6701 case Intrinsic::is_fpclass: {

6702 if (isa(Op0))

6704

6705 uint64_t Mask = cast(Op1)->getZExtValue();

6706

6708 return ConstantInt::get(ReturnType, true);

6710 return ConstantInt::get(ReturnType, false);

6713 break;

6714 }

6715 case Intrinsic::maxnum:

6716 case Intrinsic::minnum:

6717 case Intrinsic::maximum:

6718 case Intrinsic::minimum: {

6719

6720 if (Op0 == Op1)

6721 return Op0;

6722

6723

6724 if (isa(Op0))

6726

6727

6729 return Op0;

6730

6731 bool PropagateNaN = IID == Intrinsic::minimum || IID == Intrinsic::maximum;

6732 bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum;

6733

6734

6735

6736

6737

6739 return PropagateNaN ? propagateNaN(cast(Op1)) : Op0;

6740

6741

6742

6745 (C->isInfinity() || (Call && Call->hasNoInfs() && C->isLargest()))) {

6746

6747

6748

6749

6750 if (C->isNegative() == IsMin &&

6751 (!PropagateNaN || (Call && Call->hasNoNaNs())))

6752 return ConstantFP::get(ReturnType, *C);

6753

6754

6755

6756

6757

6758 if (C->isNegative() != IsMin &&

6759 (PropagateNaN || (Call && Call->hasNoNaNs())))

6760 return Op0;

6761 }

6762

6763

6764

6766 return V;

6768 return V;

6769

6770 break;

6771 }

6772 case Intrinsic::vector_extract: {

6773

6774 unsigned IdxN = cast(Op1)->getZExtValue();

6778 IdxN == 0 && X->getType() == ReturnType)

6779 return X;

6780

6781 break;

6782 }

6783 default:

6784 break;

6785 }

6786

6787 return nullptr;

6788}

6789

6793

6794 assert(Call->arg_size() == Args.size());

6795 unsigned NumOperands = Args.size();

6796 Function *F = cast(Callee);

6798

6799

6800

6801 if (!NumOperands) {

6802 switch (IID) {

6803 case Intrinsic::vscale: {

6807 return ConstantInt::get(RetTy, C->getZExtValue());

6808 return nullptr;

6809 }

6810 default:

6811 return nullptr;

6812 }

6813 }

6814

6815 if (NumOperands == 1)

6817

6818 if (NumOperands == 2)

6820 Call);

6821

6822

6823 switch (IID) {

6824 case Intrinsic::masked_load:

6825 case Intrinsic::masked_gather: {

6826 Value *MaskArg = Args[2];

6827 Value *PassthruArg = Args[3];

6828

6830 return PassthruArg;

6831 return nullptr;

6832 }

6833 case Intrinsic::fshl:

6834 case Intrinsic::fshr: {

6835 Value *Op0 = Args[0], *Op1 = Args[1], *ShAmtArg = Args[2];

6836

6837

6840

6841

6843 return Args[IID == Intrinsic::fshl ? 0 : 1];

6844

6845 const APInt *ShAmtC;

6847

6850 return Args[IID == Intrinsic::fshl ? 0 : 1];

6851 }

6852

6853

6855 return ConstantInt::getNullValue(F->getReturnType());

6856

6857

6859 return ConstantInt::getAllOnesValue(F->getReturnType());

6860

6861 return nullptr;

6862 }

6863 case Intrinsic::experimental_constrained_fma: {

6864 auto *FPI = cast(Call);

6865 if (Value *V = simplifyFPOp(Args, {}, Q, *FPI->getExceptionBehavior(),

6866 *FPI->getRoundingMode()))

6867 return V;

6868 return nullptr;

6869 }

6870 case Intrinsic::fma:

6871 case Intrinsic::fmuladd: {

6873 RoundingMode::NearestTiesToEven))

6874 return V;

6875 return nullptr;

6876 }

6877 case Intrinsic::smul_fix:

6878 case Intrinsic::smul_fix_sat: {

6879 Value *Op0 = Args[0];

6880 Value *Op1 = Args[1];

6881 Value *Op2 = Args[2];

6882 Type *ReturnType = F->getReturnType();

6883

6884

6885

6886

6887 if (isa(Op0))

6889

6890

6893

6894

6897

6898

6899 APInt ScaledOne =

6901 cast(Op2)->getZExtValue());

6903 return Op0;

6904

6905 return nullptr;

6906 }

6907 case Intrinsic::vector_insert: {

6908 Value *Vec = Args[0];

6909 Value *SubVec = Args[1];

6911 Type *ReturnType = F->getReturnType();

6912

6913

6914

6915 unsigned IdxN = cast(Idx)->getZExtValue();

6917 if (match(SubVec,

6918 m_IntrinsicIntrinsic::vector\_extract(m_Value(X), m_Zero())) &&

6919 (Q.isUndefValue(Vec) || Vec == X) && IdxN == 0 &&

6920 X->getType() == ReturnType)

6921 return X;

6922

6923 return nullptr;

6924 }

6925 case Intrinsic::experimental_constrained_fadd: {

6926 auto *FPI = cast(Call);

6927 return simplifyFAddInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,

6928 *FPI->getExceptionBehavior(),

6929 *FPI->getRoundingMode());

6930 }

6931 case Intrinsic::experimental_constrained_fsub: {

6932 auto *FPI = cast(Call);

6933 return simplifyFSubInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,

6934 *FPI->getExceptionBehavior(),

6935 *FPI->getRoundingMode());

6936 }

6937 case Intrinsic::experimental_constrained_fmul: {

6938 auto *FPI = cast(Call);

6939 return simplifyFMulInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,

6940 *FPI->getExceptionBehavior(),

6941 *FPI->getRoundingMode());

6942 }

6943 case Intrinsic::experimental_constrained_fdiv: {

6944 auto *FPI = cast(Call);

6945 return simplifyFDivInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,

6946 *FPI->getExceptionBehavior(),

6947 *FPI->getRoundingMode());

6948 }

6949 case Intrinsic::experimental_constrained_frem: {

6950 auto *FPI = cast(Call);

6951 return simplifyFRemInst(Args[0], Args[1], FPI->getFastMathFlags(), Q,

6952 *FPI->getExceptionBehavior(),

6953 *FPI->getRoundingMode());

6954 }

6955 case Intrinsic::experimental_constrained_ldexp:

6956 return simplifyLdexp(Args[0], Args[1], Q, true);

6957 case Intrinsic::experimental_gc_relocate: {

6961

6962

6963 if (isa(DerivedPtr) || isa(BasePtr)) {

6965 }

6966

6967 if (auto *PT = dyn_cast(GCR.getType())) {

6968

6969

6970

6971 if (isa(DerivedPtr)) {

6972

6974 }

6975 }

6976 return nullptr;

6977 }

6978 default:

6979 return nullptr;

6980 }

6981}

6982

6986 auto *F = dyn_cast(Callee);

6988 return nullptr;

6989

6991 ConstantArgs.reserve(Args.size());

6992 for (Value *Arg : Args) {

6993 Constant *C = dyn_cast(Arg);

6994 if (C) {

6995 if (isa(Arg))

6996 continue;

6997 return nullptr;

6998 }

7000 }

7001

7003}

7004

7007

7008 assert(Call->arg_size() == Args.size());

7009

7010

7011

7012 if (Call->isMustTailCall())

7013 return nullptr;

7014

7015

7016

7017 if (isa(Callee) || isa(Callee))

7019

7021 return V;

7022

7023 auto *F = dyn_cast(Callee);

7024 if (F && F->isIntrinsic())

7026 return Ret;

7027

7028 return nullptr;

7029}

7030

7032 assert(isa(Call));

7035 return V;

7037 return Ret;

7038 return nullptr;

7039}

7040

7041

7043

7045 return Op0;

7046

7047 return nullptr;

7048}

7049

7051 return ::simplifyFreezeInst(Op0, Q);

7052}

7053

7057 return nullptr;

7058

7059 if (auto *PtrOpC = dyn_cast(PtrOp))

7061

7062

7063

7065 if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())

7066 return nullptr;

7067

7068

7069

7072 return C;

7073

7074

7075

7078 Q.DL, Offset, true,

7079 true);

7080 if (PtrOp == GV) {

7081

7084 Q.DL);

7085 }

7086

7087 return nullptr;

7088}

7089

7090

7091

7092

7096 unsigned MaxRecurse) {

7097 assert(I->getFunction() && "instruction should be inserted in a function");

7099 "context instruction should be in the same function");

7100

7102

7103 switch (I->getOpcode()) {

7104 default:

7105 if (llvm::all_of(NewOps, [](Value *V) { return isa(V); })) {

7108 [](Value *V) { return cast(V); });

7110 }

7111 return nullptr;

7112 case Instruction::FNeg:

7113 return simplifyFNegInst(NewOps[0], I->getFastMathFlags(), Q, MaxRecurse);

7114 case Instruction::FAdd:

7115 return simplifyFAddInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,

7116 MaxRecurse);

7117 case Instruction::Add:

7121 case Instruction::FSub:

7122 return simplifyFSubInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,

7123 MaxRecurse);

7124 case Instruction::Sub:

7128 case Instruction::FMul:

7129 return simplifyFMulInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,

7130 MaxRecurse);

7131 case Instruction::Mul:

7135 case Instruction::SDiv:

7137 Q.IIQ.isExact(cast(I)), Q,

7138 MaxRecurse);

7139 case Instruction::UDiv:

7141 Q.IIQ.isExact(cast(I)), Q,

7142 MaxRecurse);

7143 case Instruction::FDiv:

7144 return simplifyFDivInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,

7145 MaxRecurse);

7146 case Instruction::SRem:

7147 return simplifySRemInst(NewOps[0], NewOps[1], Q, MaxRecurse);

7148 case Instruction::URem:

7149 return simplifyURemInst(NewOps[0], NewOps[1], Q, MaxRecurse);

7150 case Instruction::FRem:

7151 return simplifyFRemInst(NewOps[0], NewOps[1], I->getFastMathFlags(), Q,

7152 MaxRecurse);

7153 case Instruction::Shl:

7157 case Instruction::LShr:

7159 Q.IIQ.isExact(cast(I)), Q,

7160 MaxRecurse);

7161 case Instruction::AShr:

7163 Q.IIQ.isExact(cast(I)), Q,

7164 MaxRecurse);

7165 case Instruction::And:

7166 return simplifyAndInst(NewOps[0], NewOps[1], Q, MaxRecurse);

7167 case Instruction::Or:

7168 return simplifyOrInst(NewOps[0], NewOps[1], Q, MaxRecurse);

7169 case Instruction::Xor:

7170 return simplifyXorInst(NewOps[0], NewOps[1], Q, MaxRecurse);

7171 case Instruction::ICmp:

7172 return simplifyICmpInst(cast(I)->getCmpPredicate(), NewOps[0],

7173 NewOps[1], Q, MaxRecurse);

7174 case Instruction::FCmp:

7175 return simplifyFCmpInst(cast(I)->getPredicate(), NewOps[0],

7176 NewOps[1], I->getFastMathFlags(), Q, MaxRecurse);

7177 case Instruction::Select:

7178 return simplifySelectInst(NewOps[0], NewOps[1], NewOps[2], Q, MaxRecurse);

7179 case Instruction::GetElementPtr: {

7180 auto *GEPI = cast(I);

7181 return simplifyGEPInst(GEPI->getSourceElementType(), NewOps[0],

7182 ArrayRef(NewOps).slice(1), GEPI->getNoWrapFlags(), Q,

7183 MaxRecurse);

7184 }

7185 case Instruction::InsertValue: {

7188 MaxRecurse);

7189 }

7190 case Instruction::InsertElement:

7192 case Instruction::ExtractValue: {

7193 auto *EVI = cast(I);

7195 MaxRecurse);

7196 }

7197 case Instruction::ExtractElement:

7199 case Instruction::ShuffleVector: {

7200 auto *SVI = cast(I);

7202 SVI->getShuffleMask(), SVI->getType(), Q,

7203 MaxRecurse);

7204 }

7205 case Instruction::PHI:

7207 case Instruction::Call:

7209 cast(I), NewOps.back(),

7210 NewOps.drop_back(1 + cast(I)->getNumTotalBundleOperands()), Q);

7211 case Instruction::Freeze:

7213#define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc:

7214#include "llvm/IR/Instruction.def"

7215#undef HANDLE_CAST_INST

7217 MaxRecurse);

7218 case Instruction::Alloca:

7219

7220 return nullptr;

7221 case Instruction::Load:

7223 }

7224}

7225

7229 assert(NewOps.size() == I->getNumOperands() &&

7230 "Number of operands should match the instruction!");

7231 return ::simplifyInstructionWithOperands(I, NewOps, SQ, RecursionLimit);

7232}

7233

7237

7238

7239

7240

7242}

7243

7244

7245

7246

7247

7248

7249

7250

7251

7252

7253

7254

7255

7256

7261 bool Simplified = false;

7264

7265

7266

7267 if (SimpleV) {

7268 for (User *U : I->users())

7269 if (U != I)

7270 Worklist.insert(cast(U));

7271

7272

7273 I->replaceAllUsesWith(SimpleV);

7274

7275 if (I->isEHPad() && I->isTerminator() && I->mayHaveSideEffects())

7276 I->eraseFromParent();

7277 } else {

7279 }

7280

7281

7282 for (unsigned Idx = 0; Idx != Worklist.size(); ++Idx) {

7283 I = Worklist[Idx];

7284

7285

7287 if (!SimpleV) {

7288 if (UnsimplifiedUsers)

7289 UnsimplifiedUsers->insert(I);

7290 continue;

7291 }

7292

7293 Simplified = true;

7294

7295

7296

7297

7298 for (User *U : I->users())

7299 Worklist.insert(cast(U));

7300

7301

7302 I->replaceAllUsesWith(SimpleV);

7303

7304 if (I->isEHPad() && I->isTerminator() && I->mayHaveSideEffects())

7305 I->eraseFromParent();

7306 }

7307 return Simplified;

7308}

7309

7314 assert(I != SimpleV && "replaceAndRecursivelySimplify(X,X) is not valid!");

7315 assert(SimpleV && "Must provide a simplified value.");

7317 UnsimplifiedUsers);

7318}

7319

7320namespace llvm {

7323 auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;

7325 auto *TLI = TLIWP ? &TLIWP->getTLI(F) : nullptr;

7328 return {F.getDataLayout(), TLI, DT, AC};

7329}

7330

7333 return {DL, &AR.TLI, &AR.DT, &AR.AC};

7334}

7335

7336template <class T, class... TArgs>

7339 auto *DT = AM.template getCachedResult(F);

7340 auto *TLI = AM.template getCachedResult(F);

7341 auto *AC = AM.template getCachedResult(F);

7342 return {F.getDataLayout(), TLI, DT, AC};

7343}

7346

7349 return false;

7350

7352}

7353

7354}

7355

7356void InstSimplifyFolder::anchor() {}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

static Value * simplifyFreezeInst(Value *Op0, const SimplifyQuery &Q)

Given operands for a Freeze, see if we can fold the result.

static Value * simplifyCmpSelFalseCase(CmpPredicate Pred, Value *LHS, Value *RHS, Value *Cond, const SimplifyQuery &Q, unsigned MaxRecurse)

Simplify comparison with false branch of select.

static Value * simplifyCmpSelCase(CmpPredicate Pred, Value *LHS, Value *RHS, Value *Cond, const SimplifyQuery &Q, unsigned MaxRecurse, Constant *TrueOrFalse)

Simplify comparison with true or false branch of select: sel = select i1 cond, i32 tv,...

static Value * simplifySelectWithFakeICmpEq(Value *CmpLHS, Value *CmpRHS, CmpPredicate Pred, Value *TrueVal, Value *FalseVal)

An alternative way to test if a bit is set or not uses sgt/slt instead of eq/ne.

static Value * simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an LShr, see if we can fold the result.

static Value * simplifyUDivInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for a UDiv, see if we can fold the result.

static Value * simplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef< int > Mask, Type *RetTy, const SimplifyQuery &Q, unsigned MaxRecurse)

static Value * foldMinMaxSharedOp(Intrinsic::ID IID, Value *Op0, Value *Op1)

Given a min/max intrinsic, see if it can be removed based on having an operand that is another min/ma...

static Value * simplifySubInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for a Sub, see if we can fold the result.

static Value * simplifyFCmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an FCmpInst, see if we can fold the result.

static Value * expandCommutativeBinOp(Instruction::BinaryOps Opcode, Value *L, Value *R, Instruction::BinaryOps OpcodeToExpand, const SimplifyQuery &Q, unsigned MaxRecurse)

Try to simplify binops of form "A op (B op' C)" or the commuted variant by distributing op over op'.

static Constant * foldOrCommuteConstant(Instruction::BinaryOps Opcode, Value *&Op0, Value *&Op1, const SimplifyQuery &Q)

static bool haveNonOverlappingStorage(const Value *V1, const Value *V2)

Return true if V1 and V2 are each the base of some distict storage region [V, object_size(V)] which d...

static Constant * foldConstant(Instruction::UnaryOps Opcode, Value *&Op, const SimplifyQuery &Q)

static Value * handleOtherCmpSelSimplifications(Value *TCmp, Value *FCmp, Value *Cond, const SimplifyQuery &Q, unsigned MaxRecurse)

We know comparison with both branches of select can be simplified, but they are not equal.

static Value * threadCmpOverPHI(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

In the case of a comparison with a PHI instruction, try to simplify the comparison by seeing whether ...

static Constant * propagateNaN(Constant *In)

Try to propagate existing NaN values when possible.

static Value * simplifyICmpOfBools(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Fold an icmp when its operands have i1 scalar type.

static Value * simplifyICmpWithBinOpOnLHS(CmpPredicate Pred, BinaryOperator *LBO, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

static Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an AShr, see if we can fold the result.

static Value * simplifyRelativeLoad(Constant *Ptr, Constant *Offset, const DataLayout &DL)

static Value * simplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)

These are simplifications common to SDiv and UDiv.

static Value * simplifyPHINode(PHINode *PN, ArrayRef< Value * > IncomingValues, const SimplifyQuery &Q)

See if we can fold the given phi. If not, returns null.

static Value * simplifyExtractValueInst(Value *Agg, ArrayRef< unsigned > Idxs, const SimplifyQuery &, unsigned)

Given operands for an ExtractValueInst, see if we can fold the result.

static Value * simplifySelectInst(Value *, Value *, Value *, const SimplifyQuery &, unsigned)

Given operands for a SelectInst, see if we can fold the result.

static Value * simplifyAddInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an Add, see if we can fold the result.

static Value * simplifyUnOp(unsigned, Value *, const SimplifyQuery &, unsigned)

Given the operand for a UnaryOperator, see if we can fold the result.

static bool isSameCompare(Value *V, CmpPredicate Pred, Value *LHS, Value *RHS)

isSameCompare - Is V equivalent to the comparison "LHS Pred RHS"?

static Value * simplifyAndCommutative(Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)

static Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &SQ, unsigned MaxRecurse)

See if we can compute a simplified version of this instruction.

static bool isIdempotent(Intrinsic::ID ID)

static std::optional< ConstantRange > getRange(Value *V, const InstrInfoQuery &IIQ)

Helper method to get range from metadata or attribute.

static Value * simplifyAndOrOfICmpsWithCtpop(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd)

Try to simplify and/or of icmp with ctpop intrinsic.

static Value * simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp, ICmpInst *UnsignedICmp, bool IsAnd, const SimplifyQuery &Q)

Commuted variants are assumed to be handled by calling this function again with the parameters swappe...

static Value * tryConstantFoldCall(CallBase *Call, Value *Callee, ArrayRef< Value * > Args, const SimplifyQuery &Q)

static Value * simplifyWithOpsReplaced(Value *V, ArrayRef< std::pair< Value *, Value * > > Ops, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags, unsigned MaxRecurse)

static Value * simplifyICmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an ICmpInst, see if we can fold the result.

static Value * simplifyExtractElementInst(Value *Vec, Value *Idx, const SimplifyQuery &Q, unsigned)

Given operands for an ExtractElementInst, see if we can fold the result.

static Value * simplifyAndOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1, const InstrInfoQuery &IIQ)

static Value * simplifyICmpWithMinMax(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

simplify integer comparisons where at least one operand of the compare matches an integer min/max idi...

static Value * simplifyCmpSelTrueCase(CmpPredicate Pred, Value *LHS, Value *RHS, Value *Cond, const SimplifyQuery &Q, unsigned MaxRecurse)

Simplify comparison with true branch of select.

static Value * simplifyIntrinsic(CallBase *Call, Value *Callee, ArrayRef< Value * > Args, const SimplifyQuery &Q)

static void getUnsignedMonotonicValues(SmallPtrSetImpl< Value * > &Res, Value *V, MonotonicType Type, unsigned Depth=0)

Get values V_i such that V uge V_i (GreaterEq) or V ule V_i (LowerEq).

static bool isPoisonShift(Value *Amount, const SimplifyQuery &Q)

Returns true if a shift by Amount always yields poison.

static APInt stripAndComputeConstantOffsets(const DataLayout &DL, Value *&V, bool AllowNonInbounds=false)

Compute the base pointer and cumulative constant offsets for V.

static Value * simplifyCmpInst(CmpPredicate, Value *, Value *, const SimplifyQuery &, unsigned)

Given operands for a CmpInst, see if we can fold the result.

static Value * simplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse, fp::ExceptionBehavior ExBehavior, RoundingMode Rounding)

static Value * simplifyRightShift(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an LShr or AShr, see if we can fold the result.

static Value * simplifyICmpWithIntrinsicOnLHS(CmpPredicate Pred, Value *LHS, Value *RHS)

static Value * simplifySDivInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an SDiv, see if we can fold the result.

static Value * simplifyByDomEq(unsigned Opcode, Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)

Test if there is a dominating equivalence condition for the two operands.

static Value * simplifyFPUnOp(unsigned, Value *, const FastMathFlags &, const SimplifyQuery &, unsigned)

Given the operand for a UnaryOperator, see if we can fold the result.

static Value * simplifyICmpWithBinOp(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

TODO: A large part of this logic is duplicated in InstCombine's foldICmpBinOp().

static Value * simplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

Given operands for an FAdd, see if we can fold the result.

static Value * simplifyOrOfICmps(ICmpInst *Op0, ICmpInst *Op1, const SimplifyQuery &Q)

static Value * expandBinOp(Instruction::BinaryOps Opcode, Value *V, Value *OtherOp, Instruction::BinaryOps OpcodeToExpand, const SimplifyQuery &Q, unsigned MaxRecurse)

Try to simplify a binary operator of form "V op OtherOp" where V is "(B0 opex B1)" by distributing 'o...

static Value * simplifyICmpWithZero(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Try hard to fold icmp with zero RHS because this is a common case.

static Value * simplifyICmpWithConstant(CmpPredicate Pred, Value *LHS, Value *RHS, const InstrInfoQuery &IIQ)

static Value * simplifySelectWithFCmp(Value *Cond, Value *T, Value *F, const SimplifyQuery &Q, unsigned MaxRecurse)

Try to simplify a select instruction when its condition operand is a floating-point comparison.

static Constant * getFalse(Type *Ty)

For a boolean type or a vector of boolean type, return false or a vector with every element false.

static Value * simplifyDivRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)

Check for common or similar folds of integer division or integer remainder.

static bool removesFPFraction(Intrinsic::ID ID)

Return true if the intrinsic rounds a floating-point value to an integral floating-point value (not a...

static Value * simplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

static Value * simplifyOrOfICmpsWithAdd(ICmpInst *Op0, ICmpInst *Op1, const InstrInfoQuery &IIQ)

static Value * simplifySelectWithEquivalence(ArrayRef< std::pair< Value *, Value * > > Replacements, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q, unsigned MaxRecurse)

Try to simplify a select instruction when its condition operand is an integer equality or floating-po...

static Value * simplifyMulInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for a Mul, see if we can fold the result.

static Value * simplifyFNegInst(Value *Op, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse)

Given the operand for an FNeg, see if we can fold the result.

static Value * simplifyOrInst(Value *, Value *, const SimplifyQuery &, unsigned)

Given operands for an Or, see if we can fold the result.

static bool trySimplifyICmpWithAdds(CmpPredicate Pred, Value *LHS, Value *RHS, const InstrInfoQuery &IIQ)

static Value * simplifySelectBitTest(Value *TrueVal, Value *FalseVal, Value *X, const APInt *Y, bool TrueWhenUnset)

Try to simplify a select instruction when its condition operand is an integer comparison where one op...

static Value * simplifyAssociativeBinOp(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

Generic simplifications for associative binary operations.

static Value * simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an Shl, see if we can fold the result.

static Value * threadBinOpOverPHI(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

In the case of a binary operation with an operand that is a PHI instruction, try to simplify the bino...

static Value * simplifyCmpSelOfMaxMin(Value *CmpLHS, Value *CmpRHS, CmpPredicate Pred, Value *TVal, Value *FVal)

static Value * simplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

static Value * simplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

Given operands for an FSub, see if we can fold the result.

static Value * simplifyXorInst(Value *, Value *, const SimplifyQuery &, unsigned)

Given operands for a Xor, see if we can fold the result.

static Value * simplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for a URem, see if we can fold the result.

static Constant * simplifyFPOp(ArrayRef< Value * > Ops, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior, RoundingMode Rounding)

Perform folds that are common to any floating-point operation.

static Value * threadCmpOverSelect(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

In the case of a comparison with a select instruction, try to simplify the comparison by seeing wheth...

static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI, const DominatorTree *DT, AssumptionCache *AC, SmallSetVector< Instruction *, 8 > *UnsimplifiedUsers=nullptr)

Implementation of recursive simplification through an instruction's uses.

static bool isAllocDisjoint(const Value *V)

Return true if the underlying object (storage) must be disjoint from storage returned by any noalias ...

static Constant * getTrue(Type *Ty)

For a boolean type or a vector of boolean type, return true or a vector with every element true.

static Value * simplifyGEPInst(Type *, Value *, ArrayRef< Value * >, GEPNoWrapFlags, const SimplifyQuery &, unsigned)

Given operands for an GetElementPtrInst, see if we can fold the result.

static bool isDivZero(Value *X, Value *Y, const SimplifyQuery &Q, unsigned MaxRecurse, bool IsSigned)

Return true if we can simplify X / Y to 0.

static Value * simplifyLdexp(Value *Op0, Value *Op1, const SimplifyQuery &Q, bool IsStrict)

static Value * simplifyLogicOfAddSub(Value *Op0, Value *Op1, Instruction::BinaryOps Opcode)

Given a bitwise logic op, check if the operands are add/sub with a common source value and inverted c...

static Value * simplifyOrLogic(Value *X, Value *Y)

static Type * getCompareTy(Value *Op)

static Value * simplifyCastInst(unsigned, Value *, Type *, const SimplifyQuery &, unsigned)

static Value * simplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1, const SimplifyQuery &Q)

static Value * simplifyBinOp(unsigned, Value *, Value *, const SimplifyQuery &, unsigned)

Given operands for a BinaryOperator, see if we can fold the result.

static bool isICmpTrue(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

Given a predicate and two operands, return true if the comparison is true.

static Value * simplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q, unsigned)

Given operands for an InsertValueInst, see if we can fold the result.

static Value * simplifyAndInst(Value *, Value *, const SimplifyQuery &, unsigned)

Given operands for an And, see if we can fold the result.

static Value * foldIdentityShuffles(int DestElt, Value *Op0, Value *Op1, int MaskVal, Value *RootVec, unsigned MaxRecurse)

For the given destination element of a shuffle, peek through shuffles to match a root vector source o...

static Value * simplifyAndOrOfFCmps(const SimplifyQuery &Q, FCmpInst *LHS, FCmpInst *RHS, bool IsAnd)

static Value * extractEquivalentCondition(Value *V, CmpPredicate Pred, Value *LHS, Value *RHS)

Rummage around inside V looking for something equivalent to the comparison "LHS Pred RHS".

static Value * simplifyAndOrOfCmps(const SimplifyQuery &Q, Value *Op0, Value *Op1, bool IsAnd)

static Value * simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags, unsigned MaxRecurse)

static Value * threadBinOpOverSelect(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q, unsigned MaxRecurse)

In the case of a binary operation with a select instruction as an operand, try to simplify the binop ...

static Value * simplifyICmpUsingMonotonicValues(CmpPredicate Pred, Value *LHS, Value *RHS)

static Constant * computePointerDifference(const DataLayout &DL, Value *LHS, Value *RHS)

Compute the constant difference between two pointer values.

static Value * simplifySRemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an SRem, see if we can fold the result.

static Value * simplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF, const SimplifyQuery &Q, unsigned MaxRecurse, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

Given the operands for an FMul, see if we can fold the result.

static Value * simplifyAndOrOfICmpsWithConstants(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd)

Test if a pair of compares with a shared operand and 2 constants has an empty set intersection,...

static Value * simplifyAndOrWithICmpEq(unsigned Opcode, Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)

static Value * simplifyICmpWithDominatingAssume(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)

static Value * simplifyShift(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, bool IsNSW, const SimplifyQuery &Q, unsigned MaxRecurse)

Given operands for an Shl, LShr or AShr, see if we can fold the result.

static Constant * computePointerICmp(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)

static Value * simplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, const SimplifyQuery &Q, unsigned MaxRecurse)

These are simplifications common to SRem and URem.

static bool valueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT)

Does the given value dominate the specified phi node?

static Value * simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q, unsigned MaxRecurse)

Try to simplify a select instruction when its condition operand is an integer comparison.

static Value * foldMinimumMaximumSharedOp(Intrinsic::ID IID, Value *Op0, Value *Op1)

Given a min/max intrinsic, see if it can be removed based on having an operand that is another min/ma...

static Value * simplifyUnaryIntrinsic(Function *F, Value *Op0, const SimplifyQuery &Q, const CallBase *Call)

This header provides classes for managing per-loop analyses.

uint64_t IntrinsicInst * II

static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")

const SmallVectorImpl< MachineOperand > & Cond

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

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 SymbolRef::Type getType(const Symbol *Sym)

static const uint32_t IV[8]

Class for arbitrary precision integers.

APInt zextOrTrunc(unsigned width) const

Zero extend or truncate to width.

unsigned getActiveBits() const

Compute the number of active bits in the value.

bool isZero() const

Determine if this value is zero, i.e. all bits are clear.

APInt urem(const APInt &RHS) const

Unsigned remainder operation.

void setSignBit()

Set the sign bit to 1.

unsigned getBitWidth() const

Return the number of bits in the APInt.

bool ult(const APInt &RHS) const

Unsigned less than comparison.

bool intersects(const APInt &RHS) const

This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...

unsigned countr_zero() const

Count the number of trailing zero bits.

bool isNonPositive() const

Determine if this APInt Value is non-positive (<= 0).

APInt sextOrTrunc(unsigned width) const

Sign extend or truncate to width.

bool isStrictlyPositive() const

Determine if this APInt Value is positive.

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.

bool getBoolValue() const

Convert APInt to a boolean value.

APInt srem(const APInt &RHS) const

Function for signed remainder operation.

bool isMask(unsigned numBits) const

bool isMaxSignedValue() const

Determine if this is the largest signed value.

bool isNonNegative() const

Determine if this APInt Value is non-negative (>= 0)

bool ule(const APInt &RHS) const

Unsigned less or equal comparison.

bool isSubsetOf(const APInt &RHS) const

This operation checks that all bits set in this APInt are also set in RHS.

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.

bool isSignBitSet() const

Determine if sign bit of this APInt is set.

bool slt(const APInt &RHS) const

Signed less than comparison.

static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)

Constructs an APInt value that has the top hiBitsSet bits set.

static APInt getZero(unsigned numBits)

Get the '0' value for the specified bit-width.

bool isOne() const

Determine if this is a value of 1.

static APInt getOneBitSet(unsigned numBits, unsigned BitNo)

Return an APInt with exactly one bit set in the result.

bool uge(const APInt &RHS) const

Unsigned greater or equal comparison.

an instruction to allocate memory on the stack

A container for analyses that lazily runs them and caches their results.

This class represents an incoming formal argument to a Function.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

const T & back() const

back - Get the last element.

size_t size() const

size - Get the array size.

ArrayRef< T > drop_back(size_t N=1) const

Drop the last N elements of the array.

bool empty() const

empty - Check if the array is empty.

ArrayRef< T > slice(size_t N, size_t M) const

slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.

An immutable pass that tracks lazily created AssumptionCache objects.

AssumptionCache & getAssumptionCache(Function &F)

Get the cached assumptions for a function.

A cache of @llvm.assume calls within a function.

MutableArrayRef< ResultElem > assumptionsFor(const Value *V)

Access the list of assumptions which affect this value.

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

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

This class represents a function call, abstracting a target machine's calling convention.

static unsigned isEliminableCastPair(Instruction::CastOps firstOpcode, Instruction::CastOps secondOpcode, Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy, Type *DstIntPtrTy)

Determine how a pair of casts can be eliminated, if they can be at all.

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.

bool isFalseWhenEqual() const

This is just a convenience.

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ ICMP_SLT

signed less than

@ ICMP_SLE

signed less or equal

@ ICMP_UGE

unsigned greater or equal

@ ICMP_UGT

unsigned greater than

@ ICMP_SGT

signed greater than

@ ICMP_ULT

unsigned less than

@ ICMP_SGE

signed greater or equal

@ ICMP_ULE

unsigned less or equal

@ 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.

bool isFPPredicate() const

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 isUnordered(Predicate predicate)

Determine if the predicate is an unordered operation.

bool isIntPredicate() const

An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...

static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)

static Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)

static Constant * getBinOpAbsorber(unsigned Opcode, Type *Ty, bool AllowLHSConstant=false)

Return the absorbing element for the given binary operation, i.e.

static Constant * getNot(Constant *C)

static Constant * getInsertElement(Constant *Vec, Constant *Elt, Constant *Idx, Type *OnlyIfReducedTy=nullptr)

static Constant * getShuffleVector(Constant *V1, Constant *V2, ArrayRef< int > Mask, Type *OnlyIfReducedTy=nullptr)

static bool isSupportedGetElementPtr(const Type *SrcElemTy)

Whether creating a constant expression for this getelementptr type is supported.

static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)

Getelementptr form.

static Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)

Return the identity constant for a binary opcode.

static Constant * getZero(Type *Ty, bool Negative=false)

static Constant * getNegativeZero(Type *Ty)

static Constant * getNaN(Type *Ty, bool Negative=false, uint64_t Payload=0)

This is the shared class of boolean and integer constants.

static ConstantInt * getTrue(LLVMContext &Context)

static ConstantInt * getSigned(IntegerType *Ty, int64_t V)

Return a ConstantInt with the specified value for the specified type.

static ConstantInt * getFalse(LLVMContext &Context)

uint64_t getZExtValue() const

Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...

static ConstantInt * getBool(LLVMContext &Context, bool V)

static ConstantPointerNull * get(PointerType *T)

Static factory methods - Return objects of the specified value.

This class represents a range of values.

const APInt * getSingleElement() const

If this set contains a single element, return it, otherwise return null.

bool isFullSet() const

Return true if this set contains all of the elements possible for this data-type.

bool isEmptySet() const

Return true if this set contains no members.

static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)

Produce the exact range such that all values in the returned range satisfy the given predicate with a...

ConstantRange inverse() const

Return a new range that is the logical not of the current set.

bool contains(const APInt &Val) const

Return true if the specified value is in the set.

static Constant * get(StructType *T, ArrayRef< Constant * > V)

static Constant * getSplat(ElementCount EC, Constant *Elt)

Return a ConstantVector with the specified constant in each element.

static Constant * get(ArrayRef< Constant * > V)

This is an important base class in LLVM.

static Constant * getAllOnesValue(Type *Ty)

bool isAllOnesValue() const

Return true if this is the value that would be returned by getAllOnesValue.

static Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

bool isNaN() const

Return true if this is a floating-point NaN constant or a vector floating-point constant with all NaN...

Constant * getAggregateElement(unsigned Elt) const

For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...

bool isNullValue() const

Return true if this is the value that would be returned by getNullValue.

This class represents an Operation in the Expression.

A parsed version of the target data layout string in and methods for querying it.

unsigned getPointerSizeInBits(unsigned AS=0) const

Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...

IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const

Returns an integer type with size at least as big as that of a pointer in the given address space.

unsigned getIndexTypeSizeInBits(Type *Ty) const

Layout size of the index used in GEP calculation.

IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const

Returns the type of a GEP index in AddressSpace.

TypeSize getTypeAllocSize(Type *Ty) const

Returns the offset in bytes between successive objects of the specified type, including alignment pad...

unsigned getIndexSizeInBits(unsigned AS) const

Size in bits of index used for address calculation in getelementptr.

TypeSize getTypeSizeInBits(Type *Ty) const

Size examples:

Legacy analysis pass which computes a DominatorTree.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

bool dominates(const BasicBlock *BB, const Use &U) const

Return true if the (end of the) basic block BB dominates the use U.

This instruction compares its operands according to the predicate given to the constructor.

Convenience struct for specifying and reasoning about fast-math flags.

bool noSignedZeros() const

bool allowReassoc() const

Flag queries.

Represents calls to the gc.relocate intrinsic.

Value * getBasePtr() const

Value * getDerivedPtr() const

Represents flags for the getelementptr instruction/expression.

static Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)

Returns the result type of a getelementptr with the given source element type and indexes.

This instruction compares its operands according to the predicate given to the constructor.

static bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)

Return result of LHS Pred RHS comparison.

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.

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.

This instruction inserts a struct field of array element value into an aggregate value.

bool hasNoSignedZeros() const LLVM_READONLY

Determine whether the no-signed-zeros flag is set.

bool isAssociative() const LLVM_READONLY

Return true if the instruction is associative:

bool isCommutative() const LLVM_READONLY

Return true if the instruction is commutative:

const Function * getFunction() const

Return the function this instruction belongs to.

An instruction for reading from memory.

bool isVolatile() const

Return true if this is a load from a volatile memory location.

static APInt getSaturationPoint(Intrinsic::ID ID, unsigned numBits)

Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values, so there is a certain thre...

ICmpInst::Predicate getPredicate() const

Returns the comparison predicate underlying the intrinsic.

op_range incoming_values()

BasicBlock * getIncomingBlock(unsigned i) const

Return incoming basic block number i.

Value * getIncomingValue(unsigned i) const

Return incoming value number x.

unsigned getNumIncomingValues() const

Return the number of incoming edges.

Pass interface - Implemented by all 'passes'.

static PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

This class represents a cast from a pointer to an integer.

This class represents a sign extension of integer types.

This class represents the LLVM 'select' instruction.

size_type size() const

Determine the number of elements in the SetVector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

static void commuteShuffleMask(MutableArrayRef< int > Mask, unsigned InVecNumElts)

Change values in a shuffle permute mask assuming the two vector operands of length InVecNumElts have ...

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

bool contains(ConstPtrType Ptr) const

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

A SetVector that performs no allocations if smaller than a certain size.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void assign(size_type NumElts, ValueParamT Elt)

void reserve(size_type N)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

TargetLibraryInfo & getTLI(const Function &F)

Provides information about what library functions are available for the current target.

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.

unsigned getScalarSizeInBits() const LLVM_READONLY

If this is a vector type, return the getPrimitiveSizeInBits value for the element type.

bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const

Return true if it makes sense to take the size of this type.

bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const

Return true if this is a type whose size is a known multiple of vscale.

LLVMContext & getContext() const

Return the LLVMContext in which this type was uniqued.

bool isPtrOrPtrVectorTy() const

Return true if this is a pointer type or a vector of pointer types.

static IntegerType * getInt32Ty(LLVMContext &C)

TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

Return the basic size of this type if it is a primitive type.

static UndefValue * get(Type *T)

Static factory methods - Return an 'undef' object of the specified type.

A Use represents the edge between a Value definition and its users.

Value * getOperand(unsigned i) const

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const

Accumulate the constant offset this value has compared to a base pointer.

LLVMContext & getContext() const

All values hold a context through their type.

This class represents zero extension of integer types.

constexpr bool isScalable() const

Returns whether the quantity is scaled by a runtime quantity (vscale).

constexpr ScalarTy getKnownMinValue() const

Returns the minimum value this quantity can represent.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ C

The default llvm calling convention, compatible with C.

cst_pred_ty< is_all_ones > m_AllOnes()

Match an integer or vector with all bits set.

class_match< PoisonValue > m_Poison()

Match an arbitrary poison constant.

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)

PtrAdd_match< PointerOpTy, OffsetOpTy > m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp)

Matches GEP with i8 source element type.

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.

CmpClass_match< LHS, RHS, FCmpInst > m_FCmp(CmpPredicate &Pred, const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::FMul, true > m_c_FMul(const LHS &L, const RHS &R)

Matches FMul with LHS and RHS in either order.

cst_pred_ty< is_sign_mask > m_SignMask()

Match an integer or vector with only the sign bit(s) set.

BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)

cstfp_pred_ty< is_inf > m_Inf()

Match a positive or negative infinity FP constant.

m_Intrinsic_Ty< Opnd0 >::Ty m_BitReverse(const Opnd0 &Op0)

BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)

cst_pred_ty< is_power2 > m_Power2()

Match an integer or vector power-of-2.

BinaryOp_match< cstfp_pred_ty< is_any_zero_fp >, RHS, Instruction::FSub > m_FNegNSZ(const RHS &X)

Match 'fneg X' as 'fsub +-0.0, X'.

BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)

class_match< Constant > m_Constant()

Match an arbitrary Constant and ignore it.

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)

specific_intval< false > m_SpecificInt(const APInt &V)

Match a specific integer value or vector with all elements equal to the value.

bool match(Val *V, const Pattern &P)

BinOpPred_match< LHS, RHS, is_idiv_op > m_IDiv(const LHS &L, const RHS &R)

Matches integer division operations.

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.

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.

TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)

Matches ExtractElementInst.

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.

ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)

Matches SelectInst.

cstfp_pred_ty< is_neg_zero_fp > m_NegZeroFP()

Match a floating-point negative zero.

specific_fpval m_SpecificFP(double V)

Match a specific floating point value or vector with all elements equal to the value.

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::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()...

cst_pred_ty< is_zero_int > m_ZeroInt()

Match an integer 0 or a vector with all elements equal to 0.

apint_match m_APIntAllowPoison(const APInt *&Res)

Match APInt while allowing poison in splat vector constants.

BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)

Matches a 'Neg' as 'sub 0, V'.

match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()

Match an arbitrary immediate Constant and ignore it.

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)

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.

specific_fpval m_FPOne()

Match a float 1.0 or vector with all elements equal to 1.0.

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.

apfloat_match m_APFloatAllowPoison(const APFloat *&Res)

Match APFloat while allowing poison in splat vector constants.

CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)

m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)

match_combine_or< match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty, true > >, match_combine_or< MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty, true >, MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty, true > > > m_c_MaxOrMin(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)

OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWSub(const LHS &L, const RHS &R)

MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)

apint_match m_APInt(const APInt *&Res)

Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.

class_match< Value > m_Value()

Match an arbitrary value and ignore it.

OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)

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)

Exact_match< T > m_Exact(const T &SubPattern)

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::FAdd, true > m_c_FAdd(const LHS &L, const RHS &R)

Matches FAdd with LHS and RHS in either order.

LogicalOp_match< LHS, RHS, Instruction::And, true > m_c_LogicalAnd(const LHS &L, const RHS &R)

Matches L && R with LHS and RHS in either order.

BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)

m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)

apfloat_match m_APFloat(const APFloat *&Res)

Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...

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)

m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)

BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)

auto m_Undef()

Match an arbitrary undef constant.

cstfp_pred_ty< is_nan > m_NaN()

Match an arbitrary NaN constant.

BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)

Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.

BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)

m_Intrinsic_Ty< Opnd0 >::Ty m_BSwap(const Opnd0 &Op0)

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.

LogicalOp_match< LHS, RHS, Instruction::Or, true > m_c_LogicalOr(const LHS &L, const RHS &R)

Matches L || R with LHS and RHS in either order.

ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)

Matches InsertElementInst.

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.

OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap > m_NSWMul(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)

MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)

match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)

Combine two pattern matchers matching L || R.

ExceptionBehavior

Exception behavior used for floating point operations.

@ ebStrict

This corresponds to "fpexcept.strict".

@ ebIgnore

This corresponds to "fpexcept.ignore".

This is an optimization pass for GlobalISel generic memory operations.

Intrinsic::ID getInverseMinMaxIntrinsic(Intrinsic::ID MinMaxID)

Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)

Given operands for a AShr, fold the result or return nulll.

unsigned Log2_32_Ceil(uint32_t Value)

Return the ceil log base 2 of the specified value, 32 if the value is zero.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

Value * simplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

Given operands for an FMul, fold the result or return null.

Value * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, GEPNoWrapFlags NW, const SimplifyQuery &Q)

Given operands for a GetElementPtrInst, fold the result or return null.

bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr, bool AllowEphemerals=false)

Return true if it is valid to use the assumptions provided by an assume intrinsic,...

bool canCreatePoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)

Constant * ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2)

Attempt to constant fold a select instruction with the specified operands.

Value * simplifyFreezeInst(Value *Op, const SimplifyQuery &Q)

Given an operand for a Freeze, see if we can fold the result.

Constant * ConstantFoldFPInstOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL, const Instruction *I, bool AllowNonDeterministic=true)

Attempt to constant fold a floating point binary operation with the specified operands,...

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.

bool canConstantFoldCallTo(const CallBase *Call, const Function *F)

canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.

APInt getMinMaxLimit(SelectPatternFlavor SPF, unsigned BitWidth)

Return the minimum or maximum constant value for the specified integer min/max flavor and type.

Value * simplifySDivInst(Value *LHS, Value *RHS, bool IsExact, const SimplifyQuery &Q)

Given operands for an SDiv, fold the result or return null.

Value * simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q)

Given operand for a UnaryOperator, fold the result or return null.

bool isDefaultFPEnvironment(fp::ExceptionBehavior EB, RoundingMode RM)

Returns true if the exception handling behavior and rounding mode match what is used in the default f...

Value * simplifyMulInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for a Mul, fold the result or return null.

bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, APInt &Offset, const DataLayout &DL, DSOLocalEquivalent **DSOEquiv=nullptr)

If this constant is a constant offset from a global, return the global and the constant.

Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)

Like simplifyInstruction but the operands of I are replaced with NewOps.

const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)

This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....

Value * simplifyCall(CallBase *Call, Value *Callee, ArrayRef< Value * > Args, const SimplifyQuery &Q)

Given a callsite, callee, and arguments, fold the result or return null.

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.

bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)

Return true if the given value is known to have exactly one bit set when defined.

bool canRoundingModeBe(RoundingMode RM, RoundingMode QRM)

Returns true if the rounding mode RM may be QRM at compile time or at run time.

bool isNoAliasCall(const Value *V)

Return true if this pointer is returned by a noalias function.

Value * simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)

Given operands for an FCmpInst, fold the result or return null.

Value * getSplatValue(const Value *V)

Get splat value if the input is a splat vector or return nullptr.

Constant * ConstantFoldGetElementPtr(Type *Ty, Constant *C, std::optional< ConstantRange > InRange, ArrayRef< Value * > Idxs)

CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)

Return the canonical comparison predicate for the specified minimum/maximum flavor.

Value * simplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef< int > Mask, Type *RetTy, const SimplifyQuery &Q)

Given operands for a ShuffleVectorInst, fold the result or return null.

Constant * ConstantFoldCall(const CallBase *Call, Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)

ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...

Value * simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an Or, fold the result or return null.

Value * simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an Xor, fold the result or return null.

ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)

Parse out a conservative ConstantRange from !range metadata.

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.

Constant * ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef< unsigned > Idxs)

Attempt to constant fold an extractvalue instruction with the specified operands and indices.

bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI)

Tests if a value is a call or invoke to a library function that allocates memory (either malloc,...

bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if 'V & Mask' is known to be zero.

Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)

Given operands for a CastInst, fold the result or return null.

Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)

See if we can compute a simplified version of this instruction.

unsigned M1(unsigned Val)

Value * simplifySubInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for a Sub, fold the result or return null.

Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for an Add, fold the result or return null.

Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)

ConstantFoldConstant - Fold the constant using the specified DataLayout.

OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)

Wrapper function around std::transform to apply a function to a range and store the result elsewhere.

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})

Compute the size of the object pointed by Ptr.

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

Constant * ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty, const DataLayout &DL)

If C is a uniform value where all bits are the same (either all zero, all ones, all undef or all pois...

SelectPatternFlavor getInverseMinMaxFlavor(SelectPatternFlavor SPF)

Return the inverse minimum/maximum flavor of the specified flavor.

bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, SmallSetVector< Instruction *, 8 > *UnsimplifiedUsers=nullptr)

Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.

Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)

Attempt to constant fold a unary operation with the specified operand.

SelectPatternFlavor

Specific patterns of select instructions we can match.

Value * simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for a Shl, fold the result or return null.

Value * simplifyFNegInst(Value *Op, FastMathFlags FMF, const SimplifyQuery &Q)

Given operand for an FNeg, fold the result or return null.

Value * simplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

Given operands for an FSub, fold the result or return null.

bool impliesPoison(const Value *ValAssumedPoison, const Value *V)

Return true if V is poison given that ValAssumedPoison is already poison.

Value * simplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

Given operands for an FRem, fold the result or return null.

Value * simplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

Given operands for an FAdd, fold the result or return null.

FPClassTest

Floating-point class tests, supported by 'is_fpclass' intrinsic.

bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=0)

PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...

Value * simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)

Given operands for a LShr, fold the result or return null.

bool NullPointerIsDefined(const Function *F, unsigned AS=0)

Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...

Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an ICmpInst, fold the result or return null.

ConstantRange getVScaleRange(const Function *F, unsigned BitWidth)

Determine the possible constant range of vscale with the given bit width, based on the vscale_range f...

Constant * ConstantFoldInstOperands(Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)

ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.

Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)

Attempt to constant fold a cast with the specified operand.

Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an And, fold the result or return null.

Value * simplifyExtractValueInst(Value *Agg, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)

Given operands for an ExtractValueInst, fold the result or return null.

bool isNotCrossLaneOperation(const Instruction *I)

Return true if the instruction doesn't potentially cross vector lanes.

Value * simplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)

Given operands for an InsertValueInst, fold the result or return null.

Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)

Attempt to constant fold a binary operation with the specified operands.

Value * simplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

Given operands for an FDiv, fold the result or return null.

bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)

Return true if the given value is known to be non-zero when defined.

constexpr int PoisonMaskElem

Value * simplifyLoadInst(LoadInst *LI, Value *PtrOp, const SimplifyQuery &Q)

Given a load instruction and its pointer operand, fold the result or return null.

Value * simplifyFMAFMul(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q, fp::ExceptionBehavior ExBehavior=fp::ebIgnore, RoundingMode Rounding=RoundingMode::NearestTiesToEven)

Given operands for the multiplication of a FMA, fold the result or return null.

Value * simplifyConstrainedFPCall(CallBase *Call, const SimplifyQuery &Q)

Given a constrained FP intrinsic call, tries to compute its simplified version.

Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for a BinaryOperator, fold the result or return null.

bool isKnownNonEqual(const Value *V1, const Value *V2, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)

Return true if the given values are known to be non-equal when defined.

@ Or

Bitwise or logical OR of integers.

std::optional< DecomposedBitTest > decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate Pred, bool LookThroughTrunc=true, bool AllowNonZeroC=false)

Decompose an icmp into the form ((X & Mask) pred C) if possible.

Value * findScalarElement(Value *V, unsigned EltNo)

Given a vector and an element number, see if the scalar value is already around as a register,...

void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)

Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...

Value * simplifyUDivInst(Value *LHS, Value *RHS, bool IsExact, const SimplifyQuery &Q)

Given operands for a UDiv, fold the result or return null.

DWARFExpression::Operation Op

Value * simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType, Value *Op0, Value *Op1, const SimplifyQuery &Q, const CallBase *Call)

Given operands for a BinaryIntrinsic, fold the result or return null.

RoundingMode

Rounding mode.

bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)

Return true if this function can prove that V does not have undef bits and is never poison.

unsigned M0(unsigned Val)

Value * simplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx, const SimplifyQuery &Q)

Given operands for an InsertElement, fold the result or return null.

constexpr unsigned BitWidth

SelectPatternResult matchDecomposedSelectPattern(CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)

Determine the pattern that a select with the given compare as its predicate and given values as its t...

Value * simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, const SimplifyQuery &Q, bool AllowRefinement, SmallVectorImpl< Instruction * > *DropFlags=nullptr)

See if V simplifies when its operand Op is replaced with RepOp.

bool maskIsAllZeroOrUndef(Value *Mask)

Given a mask vector of i1, Return true if all of the elements of this predicate mask are known to be ...

std::pair< Value *, FPClassTest > fcmpToClassTest(CmpInst::Predicate Pred, const Function &F, Value *LHS, Value *RHS, bool LookThroughSrc=true)

Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...

Value * simplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an SRem, fold the result or return null.

void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=6)

This method is similar to getUnderlyingObject except that it can look through phi and select instruct...

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

std::optional< bool > computeKnownFPSignBit(const Value *V, unsigned Depth, const SimplifyQuery &SQ)

Return false if we can prove that the specified FP value's sign bit is 0.

unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)

Return the number of times the sign bit of the register is replicated into the other bits.

bool cannotBeNegativeZero(const Value *V, unsigned Depth, const SimplifyQuery &SQ)

Return true if we can prove that the specified FP value is never equal to -0.0.

bool all_equal(std::initializer_list< T > Values)

Returns true if all Values in the initializer lists are equal or the list.

Constant * ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, ArrayRef< unsigned > Idxs)

ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue instruction with the spe...

Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)

Return the value that a load from C with offset Offset would produce if it is constant and determinab...

std::optional< bool > isImpliedByDomCondition(const Value *Cond, const Instruction *ContextI, const DataLayout &DL)

Return the boolean condition value in the context of the given instruction if it is known based on do...

Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for a CmpInst, fold the result or return null.

bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)

Returns true if V cannot be poison, but may be undef.

KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, unsigned Depth, const SimplifyQuery &SQ)

Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.

bool isKnownNegation(const Value *X, const Value *Y, bool NeedNSW=false, bool AllowPoison=true)

Return true if the two given values are negation.

Constant * ConstantFoldIntegerCast(Constant *C, Type *DestTy, bool IsSigned, const DataLayout &DL)

Constant fold a zext, sext or trunc, depending on IsSigned and whether the DestTy is wider or narrowe...

const SimplifyQuery getBestSimplifyQuery(Pass &, Function &)

bool isCheckForZeroAndMulWithOverflow(Value *Op0, Value *Op1, bool IsAnd, Use *&Y)

Match one of the patterns up to the select/logic op: Op0 = icmp ne i4 X, 0 Agg = call { i4,...

bool canIgnoreSNaN(fp::ExceptionBehavior EB, FastMathFlags FMF)

Returns true if the possibility of a signaling NaN can be safely ignored.

Value * simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for a URem, fold the result or return null.

Value * simplifyExtractElementInst(Value *Vec, Value *Idx, const SimplifyQuery &Q)

Given operands for an ExtractElementInst, fold the result or return null.

Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)

Given operands for a SelectInst, fold the result or return null.

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.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

This callback is used in conjunction with PointerMayBeCaptured.

virtual void tooManyUses()=0

tooManyUses - The depth of traversal has breached a limit.

virtual bool captured(const Use *U)=0

captured - Information about the pointer was captured by the user of use U.

Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...

InstrInfoQuery provides an interface to query additional information for instructions like metadata o...

bool isExact(const BinaryOperator *Op) const

MDNode * getMetadata(const Instruction *I, unsigned KindID) const

bool hasNoSignedWrap(const InstT *Op) const

bool hasNoUnsignedWrap(const InstT *Op) const

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.

bool hasConflict() const

Returns true if there is conflicting information.

unsigned getBitWidth() const

Get the bit width of this value.

unsigned countMaxActiveBits() const

Returns the maximum number of bits needed to represent all possible unsigned values with these known ...

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 isNegative() const

Returns true if this value is known to be negative.

static KnownBits shl(const KnownBits &LHS, const KnownBits &RHS, bool NUW=false, bool NSW=false, bool ShAmtNonZero=false)

Compute known bits for shl(LHS, RHS).

bool isKnownAlwaysNaN() const

Return true if it's known this must always be a nan.

static constexpr FPClassTest OrderedLessThanZeroMask

std::optional< bool > SignBit

std::nullopt if the sign bit is unknown, true if the sign bit is definitely set or false if the sign ...

bool isKnownNeverNaN() const

Return true if it's known this can never be a nan.

bool isKnownNever(FPClassTest Mask) const

Return true if it's known this can never be one of the mask entries.

bool cannotBeOrderedLessThanZero() const

Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...

The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...

Various options to control the behavior of getObjectSize.

bool NullIsUnknownSize

If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.

Mode EvalMode

How we want to evaluate this object's size.

SelectPatternFlavor Flavor

static bool isMinOrMax(SelectPatternFlavor SPF)

When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?

bool CanUseUndef

Controls whether simplifications are allowed to constrain the range of possible values for uses of un...

SimplifyQuery getWithInstruction(const Instruction *I) const

bool isUndefValue(Value *V) const

If CanUseUndef is true, returns whether V is undef.

const TargetLibraryInfo * TLI

SimplifyQuery getWithoutUndef() const