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

44#include "llvm/IR/IntrinsicsAArch64.h"

50#include

51#include

52using namespace llvm;

54

55#define DEBUG_TYPE "instsimplify"

56

58

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

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

61

63 unsigned);

68 unsigned);

77 unsigned);

79 unsigned);

87 unsigned MaxRecurse);

88

89

90

92

93

94

96

97

100 if (!Cmp)

101 return false;

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

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

105 return true;

107 CRHS == LHS;

108}

109

110

111

112

113

114

117 unsigned MaxRecurse, Constant *TrueOrFalse) {

119 if (SimplifiedCmp == Cond) {

120

121 return TrueOrFalse;

123

124

125 return TrueOrFalse;

126 }

127 return SimplifiedCmp;

128}

129

130

133 unsigned MaxRecurse) {

136}

137

138

141 unsigned MaxRecurse) {

144}

145

146

147

151 unsigned MaxRecurse) {

152

153

154

155

156

157

160 return V;

161

162

165 return V;

166

167

171 return V;

172 return nullptr;

173}

174

175

178 if (I)

179

180 return true;

181

182

183 if (DT)

185

186

187

190 return true;

191

192 return false;

193}

194

195

196

197

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

203 return nullptr;

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

207 if (!L)

208 return nullptr;

211 if (!R)

212 return nullptr;

213

214

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

217 ++NumExpand;

218 return B;

219 }

220

221

223 if (!S)

224 return nullptr;

225

226 ++NumExpand;

227 return S;

228}

229

230

231

236 unsigned MaxRecurse) {

237

238 if (!MaxRecurse--)

239 return nullptr;

240

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

242 return V;

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

244 return V;

245 return nullptr;

246}

247

248

249

253 unsigned MaxRecurse) {

255

256

257 if (!MaxRecurse--)

258 return nullptr;

259

262

263

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

268

269

271

272

273 if (V == B)

274 return LHS;

275

277 ++NumReassoc;

278 return W;

279 }

280 }

281 }

282

283

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

288

289

291

292

293 if (V == B)

294 return RHS;

295

297 ++NumReassoc;

298 return W;

299 }

300 }

301 }

302

303

305 return nullptr;

306

307

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

312

313

315

316

317 if (V == A)

318 return LHS;

319

321 ++NumReassoc;

322 return W;

323 }

324 }

325 }

326

327

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

332

333

335

336

337 if (V == C)

338 return RHS;

339

341 ++NumReassoc;

342 return W;

343 }

344 }

345 }

346

347 return nullptr;

348}

349

350

351

352

353

356 unsigned MaxRecurse) {

357

358 if (!MaxRecurse--)

359 return nullptr;

360

364 } else {

367 }

368

369

375 } else {

378 }

379

380

381

382 if (TV == FV)

383 return TV;

384

385

387 return FV;

389 return TV;

390

391

392

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

394 return SI;

395

396

397

398

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

400

401

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

404 !Simplified->hasPoisonGeneratingFlags()) {

405

406

407

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

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

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

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

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

413 return Simplified;

414 if (Simplified->isCommutative() &&

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

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

417 return Simplified;

418 }

419 }

420

421 return nullptr;

422}

423

424

425

426

427

428

429

430

431

432

435

436 if (!MaxRecurse--)

437 return nullptr;

438

439

443 }

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

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

449

450

451

453 if (!TCmp)

454 return nullptr;

455

456

458 if (!FCmp)

459 return nullptr;

460

461

462

463 if (TCmp == FCmp)

464 return TCmp;

465

466

467

468 if (Cond->getType()->isVectorTy() == RHS->getType()->isVectorTy())

470

471 return nullptr;

472}

473

474

475

476

477

480 unsigned MaxRecurse) {

481

482 if (!MaxRecurse--)

483 return nullptr;

484

488

490 return nullptr;

491 } else {

494

496 return nullptr;

497 }

498

499

500 Value *CommonValue = nullptr;

502

504 continue;

511

512

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

514 return nullptr;

515 CommonValue = V;

516 }

517

518 return CommonValue;

519}

520

521

522

523

524

527

528 if (!MaxRecurse--)

529 return nullptr;

530

531

535 }

538

539

541 return nullptr;

542

543

544 Value *CommonValue = nullptr;

548

550 continue;

551

552

553

555 MaxRecurse);

556

557

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

559 return nullptr;

560 CommonValue = V;

561 }

562

563 return CommonValue;

564}

565

571 switch (Opcode) {

572 default:

573 break;

574 case Instruction::FAdd:

575 case Instruction::FSub:

576 case Instruction::FMul:

577 case Instruction::FDiv:

578 case Instruction::FRem:

579 if (Q.CxtI != nullptr)

581 }

583 }

584

585

588 }

589 return nullptr;

590}

591

592

593

597 return C;

598

599

601 return Op1;

602

603

605 return Op1;

606

607

609 return Op0;

610

611

614

615

616

617

621 return Y;

622

623

627

628

629

630

633 return Y;

634

635

637 return Op1;

638

639

642 return V;

643

644

647 return V;

648

649

650

651

652

653

654

655

656

657

658 return nullptr;

659}

660

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

664}

665

666

667

668

669

670

671

672

673

674

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

677

679 V = V->stripAndAccumulateConstantOffsets(DL, Offset,

680 true);

681

682

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

684}

685

686

687

692

693

694

696 return nullptr;

697

698

699

700

701

702 Constant *Res = ConstantInt::get(LHS->getContext(), LHSOffset - RHSOffset);

705 return Res;

706}

707

708

709

710

711

714

716 return nullptr;

717

718 std::optional Imp =

720 if (Imp && *Imp) {

722 switch (Opcode) {

723 case Instruction::Sub:

724 case Instruction::Xor:

725 case Instruction::URem:

726 case Instruction::SRem:

728

729 case Instruction::SDiv:

730 case Instruction::UDiv:

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

732

733 case Instruction::And:

734 case Instruction::Or:

735

736 return Op1;

737 default:

738 break;

739 }

740 }

741 return nullptr;

742}

743

744

745

749 return C;

750

751

752

755

756

757

760

761

763 return Op0;

764

765

766 if (Op0 == Op1)

768

769

771

772 if (IsNUW)

774

777

778

779 if (IsNSW)

781

782

783 return Op1;

784 }

785 }

786

787

788

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

791

793

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

795

796 ++NumReassoc;

797 return W;

798 }

799

801

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

803

804 ++NumReassoc;

805 return W;

806 }

807 }

808

809

810

811 X = Op0;

813

815

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

817

818 ++NumReassoc;

819 return W;

820 }

821

823

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

825

826 ++NumReassoc;

827 return W;

828 }

829 }

830

831

832

833 Z = Op0;

835

837

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

839

840 ++NumReassoc;

841 return W;

842 }

843

844

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

848

850

852 Q, MaxRecurse - 1))

853

854 return W;

855

856

861 Q.DL);

862 }

863

864

867 return V;

868

869

870

871

872

873

874

875

876

877

879 return V;

880

881

882 if (IsNUW) {

886 return X;

887 }

888

889 return nullptr;

890}

891

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

895}

896

897

898

902 return C;

903

904

906 return Op1;

907

908

909

912

913

915 return Op0;

916

917

923 return X;

924

926

927

928 if (IsNSW)

930

931

932 if (MaxRecurse)

934 return V;

935 }

936

937

940 return V;

941

942

944 Instruction::Add, Q, MaxRecurse))

945 return V;

946

947

948

952 return V;

953

954

955

959 return V;

960

961 return nullptr;

962}

963

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

967}

968

969

970

971

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

977}

978

979

980

982 unsigned MaxRecurse, bool IsSigned) {

983

984 if (!MaxRecurse--)

985 return false;

986

987 if (IsSigned) {

988

990 return true;

991

992

993

994

995

996

997

998

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

1002

1003

1004

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

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

1009 return true;

1010 }

1012

1013

1014

1015 if (C->isMinSignedValue())

1017

1018

1019

1020

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

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

1025 return true;

1026 }

1027 return false;

1028 }

1029

1030

1031

1032

1033

1034

1037 return true;

1038

1039

1040

1042}

1043

1044

1045

1048 unsigned MaxRecurse) {

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

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

1051

1053

1054

1055

1058

1059

1060

1061

1064

1065

1066

1068 return Op0;

1069

1070

1071

1074

1075

1076

1079

1080

1081

1082 if (Op0 == Op1)

1084

1086

1087

1088

1089

1090

1093

1094

1095

1096

1097

1098

1101

1102

1103

1104

1108

1109

1115 }

1116 }

1117

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

1120

1122 return V;

1123

1124

1125

1128 return V;

1129

1130

1131

1134 return V;

1135

1136 return nullptr;

1137}

1138

1139

1142 unsigned MaxRecurse) {

1144 return C;

1145

1147 return V;

1148

1149 const APInt *DivC;

1151

1152

1153

1158 }

1159

1160

1161

1162

1165 (Opcode == Instruction::UDiv

1168 return X;

1169 }

1170

1171 return nullptr;

1172}

1173

1174

1178 return C;

1179

1181 return V;

1182

1183

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

1187 (Opcode == Instruction::URem &&

1190

1191 const APInt *C0;

1193

1194

1195 if (Opcode == Instruction::SRem

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

1199 })))

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

1203 }))))

1205 }

1206 }

1207 return nullptr;

1208}

1209

1210

1211

1214

1217

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

1219}

1220

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

1224}

1225

1226

1227

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

1231}

1232

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

1236}

1237

1238

1239

1241 unsigned MaxRecurse) {

1242

1243

1247

1248

1251

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

1253}

1254

1258

1259

1260

1262 unsigned MaxRecurse) {

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

1264}

1265

1269

1270

1273 if (C)

1274 return false;

1275

1276

1278 return true;

1279

1280

1281

1282 const APInt *AmountC;

1284 return true;

1285

1286

1287

1289 for (unsigned I = 0,

1291 I != E; ++I)

1293 return false;

1294 return true;

1295 }

1296

1297 return false;

1298}

1299

1300

1301

1304 unsigned MaxRecurse) {

1306 return C;

1307

1308

1310 return Op0;

1311

1312

1315

1316

1317

1318

1322 return Op0;

1323

1324

1327

1328

1329

1332 return V;

1333

1334

1335

1338 return V;

1339

1340

1341

1345

1346

1347

1350 return Op0;

1351

1352

1353 if (IsNSW) {

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

1357

1362

1365 }

1366

1367 return nullptr;

1368}

1369

1370

1371

1373 Value *Op1, bool IsExact,

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

1377 return V;

1378

1379

1380 if (Op0 == Op1)

1382

1383

1384

1387

1388

1389

1390 if (IsExact) {

1392 if (Op0Known.One[0])

1393 return Op0;

1394 }

1395

1396 return nullptr;

1397}

1398

1399

1400

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

1405 return V;

1406

1408

1409

1412

1413

1417 return X;

1418

1419

1421 return Op0;

1422

1423

1424

1425

1426

1427

1428 if (IsNSW && IsNUW &&

1431

1432 return nullptr;

1433}

1434

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

1438}

1439

1440

1441

1445 MaxRecurse))

1446 return V;

1447

1448

1451 return X;

1452

1453

1454

1455

1456

1457

1459 const APInt *ShRAmt, *ShLAmt;

1462 *ShRAmt == *ShLAmt) {

1465 if (ShRAmt->uge(EffWidthY))

1466 return X;

1467 }

1468

1469 return nullptr;

1470}

1471

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

1475}

1476

1477

1478

1482 MaxRecurse))

1483 return V;

1484

1485

1486

1487

1491

1492

1495 return X;

1496

1497

1500 return Op0;

1501

1502 return nullptr;

1503}

1504

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

1508}

1509

1510

1511

1513 ICmpInst *UnsignedICmp, bool IsAnd,

1516

1520 return nullptr;

1521

1523

1525

1527 if (match(UnsignedICmp,

1530

1535

1540

1541

1542

1545 return IsAnd ? UnsignedICmp : ZeroICmp;

1546

1547

1548

1551 return IsAnd ? ZeroICmp : UnsignedICmp;

1552 }

1553

1554

1555

1556

1557 if (match(UnsignedICmp,

1561 return UnsignedICmp;

1564 return UnsignedICmp;

1565 }

1566 }

1567

1570 ;

1571 else if (match(UnsignedICmp,

1575 else

1576 return nullptr;

1577

1578

1579

1582 return IsAnd ? ZeroICmp : UnsignedICmp;

1583

1584

1585

1588 return IsAnd ? UnsignedICmp : ZeroICmp;

1589

1590

1591

1592

1593

1594

1595

1596

1598 return IsAnd ? UnsignedICmp : ZeroICmp;

1599

1600

1601

1603 return IsAnd ? ZeroICmp : UnsignedICmp;

1604

1605

1607 IsAnd)

1609

1610

1612 !IsAnd)

1614

1615 return nullptr;

1616}

1617

1618

1619

1620

1622 bool IsAnd) {

1623

1625 return nullptr;

1626

1627 const APInt *C0, *C1;

1630 return nullptr;

1631

1634

1635

1636

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

1639

1640

1641

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

1644

1645

1646

1647

1648

1649

1650 if (Range0.contains(Range1))

1651 return IsAnd ? Cmp1 : Cmp0;

1652 if (Range1.contains(Range0))

1653 return IsAnd ? Cmp0 : Cmp1;

1654

1655 return nullptr;

1656}

1657

1660

1662 const APInt *C0, *C1;

1665 return nullptr;

1666

1668 return nullptr;

1669

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

1672 return nullptr;

1673

1677

1678 const APInt Delta = *C1 - *C0;

1680 if (Delta == 2) {

1685 }

1686 if (Delta == 1) {

1691 }

1692 }

1694 if (Delta == 2)

1697 if (Delta == 1)

1700 }

1701

1702 return nullptr;

1703}

1704

1705

1707 bool IsAnd) {

1714 return nullptr;

1715

1716

1718 return Cmp1;

1719

1721 return Cmp1;

1722

1723 return nullptr;

1724}

1725

1729 return X;

1731 return X;

1732

1734 return X;

1735

1737 return X;

1739 return X;

1740

1742 return X;

1744 return X;

1745

1746 return nullptr;

1747}

1748

1751

1753 const APInt *C0, *C1;

1756 return nullptr;

1757

1759 return nullptr;

1760

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

1763 return nullptr;

1764

1768

1769 const APInt Delta = *C1 - *C0;

1771 if (Delta == 2) {

1776 }

1777 if (Delta == 1) {

1782 }

1783 }

1785 if (Delta == 2)

1788 if (Delta == 1)

1791 }

1792

1793 return nullptr;

1794}

1795

1799 return X;

1801 return X;

1802

1804 return X;

1805

1807 return X;

1809 return X;

1810

1812 return X;

1814 return X;

1815

1816 return nullptr;

1817}

1818

1819

1820

1821

1823 bool IsAnd) {

1824

1826 return nullptr;

1827

1831 return nullptr;

1832

1837

1838 if (!Range0 || !Range1)

1839 return nullptr;

1840

1841

1842

1843 if (Range0->intersectWith(*Range1).isEmptySet())

1845

1846

1847

1848

1849

1850

1851 if (Range0->contains(*Range1))

1852 return Cmp1;

1853 if (Range1->contains(*Range0))

1854 return Cmp0;

1855

1856 return nullptr;

1857}

1858

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

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

1864 return nullptr;

1865

1871

1872

1873

1874

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

1880 }

1881

1886

1887

1888

1889

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

1895 }

1896

1898 return V;

1899

1900 return nullptr;

1901}

1902

1904 Value *Op1, bool IsAnd) {

1905

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

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

1910 Op0 = Cast0->getOperand(0);

1911 Op1 = Cast1->getOperand(0);

1912 }

1913

1914 Value *V = nullptr;

1917 if (ICmp0 && ICmp1)

1920

1923 if (FCmp0 && FCmp1)

1925

1926 if (!V)

1927 return nullptr;

1928 if (!Cast0)

1929 return V;

1930

1931

1932

1935 Q.DL);

1936

1937 return nullptr;

1938}

1939

1942 bool AllowRefinement,

1944 unsigned MaxRecurse);

1945

1948 unsigned MaxRecurse) {

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

1950 "Must be and/or");

1955 return nullptr;

1956

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

1959

1960

1961

1962

1963 if (Pred ==

1965 if (Res == Absorber)

1966 return Absorber;

1968 return Op0;

1969 return nullptr;

1970 }

1971

1972

1973

1974

1975 if (Res == Absorber)

1976 return Op1;

1977 return nullptr;

1978 };

1979

1980

1981

1982

1984 true,

1985 nullptr, MaxRecurse))

1986 return Simplify(Res);

1988 true,

1989 nullptr, MaxRecurse))

1990 return Simplify(Res);

1991

1992 return nullptr;

1993}

1994

1995

1996

2008

2009

2010

2014 }

2015 }

2016 return nullptr;

2017}

2018

2019

2022 unsigned MaxRecurse) {

2023

2026

2027

2029 return Op1;

2030

2031

2035 return X;

2036

2037

2038

2039

2041 return Op1;

2042

2043

2046 return Op1;

2047

2048

2049

2053

2054

2055

2056 const APInt *Shift1, *Shift2;

2060 Shift1->uge(*Shift2))

2062

2065 return V;

2066

2067 return nullptr;

2068}

2069

2070

2071

2073 unsigned MaxRecurse) {

2075 return C;

2076

2077

2079 return Op1;

2080

2081

2084

2085

2086 if (Op0 == Op1)

2087 return Op0;

2088

2089

2092

2093

2095 return Op0;

2096

2098 return Res;

2100 return Res;

2101

2103 return V;

2104

2105

2106 const APInt *Mask;

2107 const APInt *ShAmt;

2110

2111

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

2114 return Op0;

2115

2116

2117

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

2120 return Op0;

2121 }

2122

2123

2124 const APInt *PowerC;

2129 Q.DT)) {

2131

2134 }

2135

2137 return V;

2138

2139

2142 return V;

2143

2144

2146 Instruction::Or, Q, MaxRecurse))

2147 return V;

2148

2149

2151 Instruction::Xor, Q, MaxRecurse))

2152 return V;

2153

2156

2158 return Op1;

2160 return Op0;

2161 }

2162

2163

2164

2167 return V;

2168 }

2169

2170

2171

2175 return V;

2176

2177

2178

2179

2180

2181

2182

2183

2184

2185

2186

2187 Value *XShifted;

2196 if (EffWidthY <= ShftCnt) {

2201

2202

2204 return Y;

2206 return XShifted;

2207 }

2208 }

2209

2210

2211

2218

2219 const APInt *C1;

2221

2225

2228

2229 if (*Implied == true)

2230 return Op0;

2231

2232 if (*Implied == false)

2234 }

2236

2237 if (*Implied)

2238 return Op1;

2239

2240 if (!*Implied)

2242 }

2243 }

2244

2246 return V;

2247

2248 return nullptr;

2249}

2250

2254

2255

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

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

2259

2260

2263

2264

2267

2268

2270 return X;

2271

2273

2274

2275

2278 return Y;

2279

2280

2281

2285

2286

2287

2288

2289

2292 return Y;

2293

2294

2295

2296

2297

2300 return X;

2301

2302

2303

2304

2305

2309

2310

2311

2312

2313

2318 return NotA;

2319

2320

2321

2325 return NotA;

2326

2327

2328

2333 return NotAB;

2334

2335

2336

2340 return NotAB;

2341

2342 return nullptr;

2343}

2344

2345

2346

2348 unsigned MaxRecurse) {

2350 return C;

2351

2352

2354 return Op1;

2355

2356

2357

2358

2361

2362

2363

2365 return Op0;

2366

2368 return R;

2370 return R;

2371

2373 return V;

2374

2375

2376

2377

2378

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

2389 }

2390 }

2391

2392

2393

2394

2395

2396

2400 return Op0;

2404 return Op1;

2405

2406

2407

2411 return Op0;

2415 return Op1;

2416

2419 return V;

2422 return V;

2423

2425 return V;

2426

2427

2428

2429

2431 return Op1;

2433 return Op0;

2434

2435

2438 return V;

2439

2440

2442 Instruction::And, Q, MaxRecurse))

2443 return V;

2444

2447

2449 return Op1;

2451 return Op0;

2452 }

2453

2454

2455

2458 return V;

2459 }

2460

2461

2463 const APInt *C1, *C2;

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

2467

2468

2469

2470

2472 if (C2->isMask() &&

2474

2476 return A;

2477 }

2478

2480

2482 return B;

2483 }

2484 }

2485 }

2486

2487

2488

2491 return V;

2492

2493

2497

2499 if (std::optional Implied =

2501

2502 if (*Implied == false)

2503 return Op0;

2504

2505 if (*Implied == true)

2507 }

2508 if (std::optional Implied =

2510

2511 if (*Implied == false)

2512 return Op1;

2513

2514 if (*Implied == true)

2516 }

2517 }

2518

2520 return V;

2521

2522 return nullptr;

2523}

2524

2528

2529

2530

2532 unsigned MaxRecurse) {

2534 return C;

2535

2536

2538 return Op1;

2539

2540

2542 return Op1;

2543

2544

2546 return Op0;

2547

2548

2549 if (Op0 == Op1)

2551

2552

2555

2558

2561 return A;

2562

2563

2564

2565

2570 return NotA;

2571

2572 return nullptr;

2573 };

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

2575 return R;

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

2577 return R;

2578

2580 return V;

2581

2582

2585 return V;

2586

2587

2588

2589

2590

2591

2592

2593

2594

2595

2597 return V;

2598

2599

2600 {

2604 return X;

2605 }

2606

2607 return nullptr;

2608}

2609

2613

2617

2618

2619

2620

2624 if (SI)

2625 return nullptr;

2627 if (!Cmp)

2628 return nullptr;

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

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

2631 return Cmp;

2633 LHS == CmpRHS && RHS == CmpLHS)

2634 return Cmp;

2635 return nullptr;

2636}

2637

2638

2639

2641

2642

2643

2644

2645

2647 return AI->isStaticAlloca();

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

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

2651 !GV->isThreadLocal();

2653 return A->hasByValAttr();

2654 return false;

2655}

2656

2657

2658

2659

2661

2662

2663

2664

2665

2666

2667

2668

2669

2670

2671

2672

2673

2674

2675

2676

2677

2678

2679

2680

2681

2682

2683

2684

2685

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

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

2689 };

2690

2691

2692

2693 if (isByValArg(V1))

2695 if (isByValArg(V2))

2697

2700}

2701

2702

2703

2704

2705

2706

2707

2708

2709

2710

2711

2712

2713

2714

2715

2716

2717

2718

2719

2720

2721

2722

2723

2724

2725

2726

2727

2728

2729

2732 assert(LHS->getType() == RHS->getType() && "Must have same types");

2735

2736

2737

2739 return nullptr;

2740

2741

2742

2744

2745

2746

2747

2748

2749

2750

2751

2752

2753

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

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

2757 LHS = LHS->stripAndAccumulateConstantOffsets(DL, LHSOffset, AllowNonInbounds);

2758 RHS = RHS->stripAndAccumulateConstantOffsets(DL, RHSOffset, AllowNonInbounds);

2759

2760

2761

2765

2766

2768

2769

2770

2771

2772

2779 return I->getFunction();

2781 return A->getParent();

2782 return nullptr;

2787 APInt Dist = LHSOffset - RHSOffset;

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

2791 }

2792 }

2793

2794

2795

2796

2797

2798

2802

2803

2806 };

2807

2808

2809

2810

2813 };

2814

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

2816 (IsNAC(RHSUObjs) && IsAllocDisjoint(LHSUObjs)))

2819

2820

2821

2822

2823

2824

2830 if (MI) {

2831

2832

2833

2834

2835 struct CustomCaptureTracker : public CaptureTracker {

2836 bool Captured = false;

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

2839

2841

2842

2843

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

2848 }

2849

2850 Captured = true;

2851 return Stop;

2852 }

2853 };

2854 CustomCaptureTracker Tracker;

2856 if (!Tracker.Captured)

2859 }

2860 }

2861

2862

2863 return nullptr;

2864}

2865

2866

2870 Type *OpTy = LHS->getType();

2872 return nullptr;

2873

2874

2875

2876

2877

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

2881 return X;

2882 return nullptr;

2883 };

2884

2886 switch (Pred) {

2890 return LHS;

2891

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

2896 return X;

2897 break;

2898

2902

2906

2907 default:

2908 break;

2909 }

2911 switch (Pred) {

2915 return LHS;

2916

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

2921 return X;

2922 break;

2923

2927

2931

2932 default:

2933 break;

2934 }

2935 }

2936

2937 switch (Pred) {

2938 default:

2939 break;

2943 break;

2945

2946

2947

2948

2949

2950

2951

2954 break;

2958 break;

2960

2963 break;

2964 }

2965

2966 return nullptr;

2967}

2968

2969

2973 return nullptr;

2974

2976 switch (Pred) {

2977 default:

2987 break;

2992 break;

2999 break;

3000 }

3007 break;

3008 }

3015 break;

3016 }

3023 break;

3024 }

3025 }

3026

3027 return nullptr;

3028}

3029

3033

3037 return nullptr;

3038

3039

3040

3041

3042

3044 bool TrueIfSigned;

3047 }

3048

3049

3055

3059 if (RHS_CR.contains(LHS_CR))

3063 }

3064

3065

3066

3067 const APInt *MulC;

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

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

3074

3077

3078 return nullptr;

3079}

3080

3082

3083

3087 unsigned Depth = 0) {

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

3089 return;

3090

3091

3092 if (++Depth > 1)

3093 return;

3094

3096 if (I)

3097 return;

3098

3105 }

3106

3112 }

3113 } else {

3115 switch (I->getOpcode()) {

3116 case Instruction::And:

3119 break;

3120 case Instruction::URem:

3121 case Instruction::UDiv:

3122 case Instruction::LShr:

3124 break;

3125 case Instruction::Call:

3128 break;

3129 default:

3130 break;

3131 }

3132 }

3133}

3134

3139 return nullptr;

3140

3141

3142

3147 for (Value *GV : GreaterValues)

3148 if (LowerValues.contains(GV))

3151 return nullptr;

3152}

3153

3156 unsigned MaxRecurse) {

3158

3160

3169 }

3170 }

3171

3172

3174 switch (Pred) {

3175 default:

3176 break;

3181 break;

3182 [[fallthrough]];

3183 }

3192 break;

3193 [[fallthrough]];

3194 }

3199 }

3200 }

3201

3202

3203

3204

3205

3206

3207

3208

3209

3210

3211

3216 switch (Pred) {

3217 default:

3218 break;

3227 }

3228 }

3229 }

3230

3231

3232

3233

3234

3235

3236

3237

3238

3239

3240 const APInt *C1, *C2;

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

3251 }

3252

3253

3254

3258

3259 return nullptr;

3260}

3261

3262

3263

3264

3265

3266

3267

3268

3269

3270

3271

3272

3273

3276

3278 return false;

3279

3280

3284 return false;

3285

3287 const APInt *C1, *C2;

3290 return false;

3291

3294}

3295

3296

3297

3298

3301 unsigned MaxRecurse) {

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

3305

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

3307

3308 bool NoLHSWrapProblem = false, NoRHSWrapProblem = false;

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

3312 NoLHSWrapProblem =

3318 }

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

3322 NoRHSWrapProblem =

3328 }

3329

3330

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

3334 MaxRecurse - 1))

3335 return V;

3336

3337

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

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

3342 return V;

3343

3344

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

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

3348

3350 if (A == C) {

3351

3352 Y = B;

3353 Z = D;

3354 } else if (A == D) {

3355

3356 Y = B;

3357 Z = C;

3358 } else if (B == C) {

3359

3360 Y = A;

3361 Z = D;

3362 } else {

3364

3365 Y = A;

3366 Z = C;

3367 }

3369 return V;

3370 }

3371 }

3372

3373 if (LBO)

3375 return V;

3376

3377 if (RBO)

3380 return V;

3381

3382

3386 if (C->isStrictlyPositive()) {

3391 }

3392 if (C->isNonNegative()) {

3397 }

3398 }

3399 }

3400

3401

3402

3403

3407

3408

3409

3410

3411

3412

3413

3414

3422 }

3423 }

3424

3425

3426

3427

3433 }

3434

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

3436 return nullptr;

3437

3440 default:

3441 break;

3442 case Instruction::Shl: {

3447 break;

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

3450 return V;

3451 break;

3452 }

3453

3454

3455

3456

3457

3458 case Instruction::And:

3459 case Instruction::Or: {

3460 const APInt *C1, *C2;

3467 }

3478 }

3479 }

3480 }

3481 break;

3482 }

3483 }

3484 }

3485

3488 default:

3489 break;

3490 case Instruction::UDiv:

3491 case Instruction::LShr:

3494 break;

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

3497 return V;

3498 break;

3499 case Instruction::SDiv:

3502 break;

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

3505 return V;

3506 break;

3507 case Instruction::AShr:

3509 break;

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

3512 return V;

3513 break;

3514 case Instruction::Shl: {

3517 if (!NUW && !NSW)

3518 break;

3520 break;

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

3523 return V;

3524 break;

3525 }

3526 }

3527 }

3528 return nullptr;

3529}

3530

3531

3532

3535 unsigned MaxRecurse) {

3539 CmpInst::Predicate EqP;

3540

3541

3543 if (A != RHS)

3546

3547 P = Pred;

3550 if (A != LHS)

3553

3557 if (A != RHS)

3560

3561

3565 if (A != LHS)

3568

3569

3570 P = Pred;

3571 }

3573

3574 switch (P) {

3575 default:

3576 break;

3579

3580

3582 return V;

3584 return V;

3585

3586 if (MaxRecurse)

3588 return V;

3589 break;

3593

3594

3596 return V;

3598 return V;

3599

3600 if (MaxRecurse)

3602 return V;

3603 break;

3604 }

3606

3609

3611 }

3612 }

3613

3614

3617 if (A != RHS)

3620

3621 P = Pred;

3624 if (A != LHS)

3627

3631 if (A != RHS)

3634

3635

3639 if (A != LHS)

3642

3643

3644 P = Pred;

3645 }

3647

3648 switch (P) {

3649 default:

3650 break;

3653

3654

3656 return V;

3658 return V;

3659

3660 if (MaxRecurse)

3662 return V;

3663 break;

3667

3668

3670 return V;

3672 return V;

3673

3674 if (MaxRecurse)

3676 return V;

3677 break;

3678 }

3683 }

3684 }

3685

3686

3687

3692 }

3693

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

3698

3701

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

3707

3710

3713 }

3714

3715 return nullptr;

3716}

3717

3721

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

3723 return nullptr;

3724

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

3727 if (!AssumeVH)

3728 continue;

3729

3735 }

3736 }

3737

3738 return nullptr;

3739}

3740

3744 if (II)

3745 return nullptr;

3746

3747 switch (II->getIntrinsicID()) {

3748 case Intrinsic::uadd_sat:

3749

3756 }

3757 return nullptr;

3758 case Intrinsic::usub_sat:

3759

3766 }

3767 return nullptr;

3768 default:

3769 return nullptr;

3770 }

3771}

3772

3773

3779

3781 return A->getRange();

3783 return CB->getRange();

3784

3785 return std::nullopt;

3786}

3787

3788

3789

3793

3797

3798

3801 }

3803

3805

3806

3809

3810

3811

3812

3815

3816

3817

3820

3822 return V;

3823

3824

3825

3827 return V;

3828

3830 return V;

3831

3832

3833

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

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

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

3838

3841 }

3842

3843

3849

3850

3851

3855

3858 Q, MaxRecurse - 1))

3859 return V;

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

3862

3864 MaxRecurse - 1))

3865 return V;

3866 }

3867 }

3868

3870

3871

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

3874

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

3878 return V;

3879 }

3880

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

3887 }

3888 }

3889

3890

3894

3895

3896

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

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

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

3906

3907

3908

3909

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

3913 return V;

3914

3915

3916

3918 switch (Pred) {

3919 default:

3921

3926

3931

3932

3933

3938 Q.DL);

3943 Q.DL);

3944 }

3945 }

3946 }

3947 }

3948

3950

3951

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

3954

3956 MaxRecurse - 1))

3957 return V;

3958 }

3959

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

3966 }

3967 }

3968

3969

3972

3973

3974

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

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

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

3984

3985

3986

3990 return V;

3991

3992

3993

3995 switch (Pred) {

3996 default:

4002

4003

4004

4009 Q.DL);

4014 Q.DL);

4015

4016

4017

4020

4021 if (MaxRecurse)

4024 MaxRecurse - 1))

4025 return V;

4026 break;

4029

4030 if (MaxRecurse)

4033 MaxRecurse - 1))

4034 return V;

4035 break;

4036 }

4037 }

4038 }

4039 }

4040 }

4041

4042

4043

4044

4048 }

4049

4051 return V;

4052

4054 return V;

4055

4057 return V;

4060 return V;

4061

4063 return V;

4066 return V;

4067

4069 return V;

4070

4071 if (std::optional Res =

4074

4075

4076

4077 if (LHS->getType()->isPointerTy())

4079 return C;

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

4086 CRHS->getPointerOperand(), Q))

4087 return C;

4088

4089

4090

4093 return V;

4094

4095

4096

4099 return V;

4100

4101 return nullptr;

4102}

4103

4106 return ::simplifyICmpInst(Predicate, LHS, RHS, Q, RecursionLimit);

4107}

4108

4109

4110

4113 unsigned MaxRecurse) {

4115

4120

4121

4124 }

4125

4126

4132

4133

4134

4137

4138

4139

4141

4142

4144 }

4145

4146

4152 }

4153

4154

4155

4156

4157

4161

4165

4168 }

4169

4170 if (std::optional Res =

4173

4176 std::optional FullKnownClassLHS;

4177

4178

4179

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

4182 if (FullKnownClassLHS)

4183 return *FullKnownClassLHS;

4185 };

4186

4187 if (C && Q.CxtI) {

4188

4189

4190

4191

4192

4195 if (ClassVal) {

4196 FullKnownClassLHS = computeLHSClass();

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

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

4201 }

4202 }

4203

4204

4205 if (C) {

4206

4207

4208 if (C->isNaN())

4210

4211

4212

4213

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

4216

4217

4218

4219 switch (Pred) {

4223 KnownFPClass KnownClass = computeLHSClass(Interested);

4224

4225

4228 break;

4229 }

4233 KnownFPClass KnownClass = computeLHSClass(Interested);

4234

4235

4238 break;

4239 }

4240 default:

4241 break;

4242 }

4243 }

4244

4247 *C2 < *C) ||

4249 *C2 > *C)) {

4250 bool IsMaxNum =

4252

4253

4254 switch (Pred) {

4257

4258

4262

4263

4269

4270

4271

4272

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

4278

4279

4280

4281

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

4283 default:

4284

4286 }

4287 }

4288 }

4289

4290

4291

4293 switch (Pred) {

4298 Interested |= fcNan;

4299

4300 KnownFPClass Known = computeLHSClass(Interested);

4301

4302

4303

4307 break;

4308 }

4312 KnownFPClass Known = computeLHSClass(Interested);

4313

4314

4315

4318 break;

4319 }

4320 default:

4321 break;

4322 }

4323 }

4324

4325

4326

4329 return V;

4330

4331

4332

4335 return V;

4336

4337 return nullptr;

4338}

4339

4342 return ::simplifyFCmpInst(Predicate, LHS, RHS, FMF, Q, RecursionLimit);

4343}

4344

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

4348 bool AllowRefinement,

4350 unsigned MaxRecurse) {

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

4353 for (const auto &OpAndRepOp : Ops) {

4354

4356 return nullptr;

4357

4358

4359 if (V == OpAndRepOp.first)

4360 return OpAndRepOp.second;

4361 }

4362

4363 if (!MaxRecurse--)

4364 return nullptr;

4365

4367 if (I)

4368 return nullptr;

4369

4370

4371

4373 return nullptr;

4374

4375

4377 return nullptr;

4378

4379

4381 return nullptr;

4382

4383 for (const auto &OpAndRepOp : Ops) {

4384

4385

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

4388 return nullptr;

4389 }

4390

4391

4393 bool AnyReplaced = false;

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

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

4398 AnyReplaced = InstOp != NewInstOp;

4399 } else {

4401 }

4402

4403

4404

4406 return nullptr;

4407 }

4408

4409 if (!AnyReplaced)

4410 return nullptr;

4411

4412 if (!AllowRefinement) {

4413

4414

4415

4416

4418 unsigned Opcode = BO->getOpcode();

4419

4420

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

4423 return NewOps[1];

4425 true))

4426 return NewOps[0];

4427 }

4428

4429

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

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

4432

4434 if (PDI->isDisjoint()) {

4435 if (!DropFlags)

4436 return nullptr;

4438 }

4439 }

4440 return NewOps[0];

4441 }

4442

4443

4444

4445

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

4447 NewOps[0] == NewOps[1] &&

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

4450

4451

4452

4453

4454

4455

4456

4457

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

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

4462 return Absorber;

4463 }

4464

4466

4467

4469 return NewOps[0];

4470 }

4471 } else {

4472

4473

4474

4475

4476

4477

4478

4479

4480

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

4482 return Simplified != V ? Simplified : nullptr;

4483 };

4484

4485 return PreventSelfSimplify(

4487 }

4488

4489

4490

4492 for (Value *NewOp : NewOps) {

4495 else

4496 return nullptr;

4497 }

4498

4499

4500

4501

4502

4503

4504

4505

4506

4507

4508 if (!AllowRefinement) {

4510

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

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

4514 return nullptr;

4515 } else

4516 return nullptr;

4517 }

4519 false);

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

4522 return Res;

4523 }

4524

4526 false);

4527}

4528

4531 bool AllowRefinement,

4533 unsigned MaxRecurse) {

4535 DropFlags, MaxRecurse);

4536}

4537

4540 bool AllowRefinement,

4542

4543

4544 if (!AllowRefinement)

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

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

4549}

4550

4551

4552

4554 const APInt *Y, bool TrueWhenUnset) {

4556

4557

4558

4560 *Y == ~*C)

4561 return TrueWhenUnset ? FalseVal : TrueVal;

4562

4563

4564

4566 *Y == ~*C)

4567 return TrueWhenUnset ? FalseVal : TrueVal;

4568

4569 if (Y->isPowerOf2()) {

4570

4571

4573 *Y == *C) {

4574

4576 return nullptr;

4577 return TrueWhenUnset ? TrueVal : FalseVal;

4578 }

4579

4580

4581

4583 *Y == *C) {

4584

4586 return nullptr;

4587 return TrueWhenUnset ? TrueVal : FalseVal;

4588 }

4589 }

4590

4591 return nullptr;

4592}

4593

4597

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

4601 }

4602

4603

4604 if (CmpLHS == FVal) {

4607 }

4608

4609

4610

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

4612 bool PeekedThroughSelectShuffle = false;

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

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

4616 FVal = Shuf->getOperand(1);

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

4618 FVal = Shuf->getOperand(0);

4619 else

4620 return nullptr;

4621 PeekedThroughSelectShuffle = true;

4622 }

4623

4624

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

4628 return nullptr;

4629

4630

4631

4632

4633

4634

4635

4636

4637

4638

4641 return MMI;

4642

4643

4644 if (PeekedThroughSelectShuffle)

4645 return nullptr;

4646

4647

4649 return MMI;

4650

4651

4653 return X;

4654

4655

4656

4657

4658

4661 return X;

4662

4663 return nullptr;

4664}

4665

4666

4667

4669 Value *FalseVal) {

4673

4674 return nullptr;

4675}

4676

4677

4678

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

4682 Value *SimplifiedFalseVal =

4684 false,

4685 nullptr, MaxRecurse);

4686 if (!SimplifiedFalseVal)

4687 SimplifiedFalseVal = FalseVal;

4688

4689 Value *SimplifiedTrueVal =

4691 true,

4692 nullptr, MaxRecurse);

4693 if (!SimplifiedTrueVal)

4694 SimplifiedTrueVal = TrueVal;

4695

4696 if (SimplifiedFalseVal == SimplifiedTrueVal)

4697 return FalseVal;

4698

4699 return nullptr;

4700}

4701

4702

4703

4705 Value *FalseVal,

4707 unsigned MaxRecurse) {

4709 Value *CmpLHS, *CmpRHS;

4711 return nullptr;

4712

4714 return V;

4715

4716

4720 }

4721

4722

4723

4724

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

4729 X, Y)

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

4735 return X;

4736 }

4737 }

4738

4744 true))

4745 return V;

4746

4747

4751

4752

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

4754 return X;

4755

4756

4757

4758

4759

4760

4761 auto isRotate =

4764

4765

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

4768 return FalseVal;

4769

4770

4771

4774 return FalseVal;

4775 if (match(TrueVal,

4778 return FalseVal;

4779 }

4780

4781

4782

4783

4788 FalseVal, Q, MaxRecurse))

4789 return V;

4793 FalseVal, Q, MaxRecurse))

4794 return V;

4795

4798

4801

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

4804 return V;

4805 }

4806

4807

4810

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

4813 return V;

4814 }

4815 }

4816

4817 return nullptr;

4818}

4819

4820

4821

4824 unsigned MaxRecurse) {

4826 Value *CmpLHS, *CmpRHS;

4828 return nullptr;

4830

4831 bool IsEquiv = I->isEquivalence();

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

4835 IsEquiv = true;

4836 }

4837

4838

4839

4840 if (IsEquiv) {

4842 MaxRecurse))

4843 return V;

4845 MaxRecurse))

4846 return V;

4847 }

4848

4849

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

4852

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

4854 return nullptr;

4855

4856

4858

4860 return F;

4861

4862

4864 return T;

4865 }

4866

4867 return nullptr;

4868}

4869

4870

4871

4872

4873

4874

4875

4876

4877

4878

4879

4880

4881

4882

4883

4884

4885

4886

4887

4888

4889

4890

4891

4892

4893

4894

4895

4896

4897

4898

4901 return false;

4903 return false;

4904

4905

4906 unsigned DiffVals = 0;

4908 for (unsigned i = 0; i < 2; i++) {

4912 DiffVals++;

4913 DiffValBB = PredBB;

4914 }

4915 }

4916 if (DiffVals != 1)

4917 return false;

4918

4919

4920

4922 auto *IdenticalSI =

4924 if (SI || !IdenticalSI)

4925 return false;

4926 if (SI->getCondition() != IdenticalSI->getCondition())

4927 return false;

4928

4930 Value *IdenticalSIOtherVal = nullptr;

4931 if (SI->getTrueValue() == IdenticalSI->getTrueValue()) {

4933 IdenticalSIOtherVal = IdenticalSI->getFalseValue();

4934 } else if (SI->getFalseValue() == IdenticalSI->getFalseValue()) {

4936 IdenticalSIOtherVal = IdenticalSI->getTrueValue();

4937 } else {

4938 return false;

4939 }

4940

4941

4942

4943 if (!SIOtherVal || IdenticalSIOtherVal != &IdenticalPN)

4944 return false;

4945 if (!(SIOtherVal->getTrueValue() == &IdenticalPN &&

4949 return false;

4950 return true;

4951}

4952

4953

4954

4961 return C;

4962

4963

4966

4967

4969 return isa(FalseVal) ? FalseVal : TrueVal;

4970

4971

4972

4973

4974

4976 return TrueVal;

4978 return FalseVal;

4979 }

4980

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

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

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

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

4985

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

4987

4989 return Cond;

4990

4991

4993 return FalseVal;

4994

4995

4997 return TrueVal;

4998

4999

5003

5004

5006

5009

5012

5013

5015 return TrueVal;

5016

5018 return Cond;

5019

5020

5024 return X;

5027 return X;

5028 }

5029

5030

5032

5035

5038

5039

5041 return FalseVal;

5042

5044 return Cond;

5045 }

5046 }

5047

5048

5049 if (TrueVal == FalseVal)

5050 return TrueVal;

5051

5052 if (Cond == TrueVal) {

5053

5055 return Cond;

5056

5059 }

5060 if (Cond == FalseVal) {

5061

5063 return Cond;

5064

5067 }

5068

5069

5070

5071

5072

5073

5076 return FalseVal;

5077

5078

5081 return TrueVal;

5082

5083

5088 unsigned NumElts =

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

5092

5095 if (!TEltC || !FEltC)

5096 break;

5097

5098

5099

5100 if (TEltC == FEltC)

5108 else

5109 break;

5110 }

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

5113 }

5114

5117 return V;

5118

5120 return V;

5121

5123 return V;

5124

5126 if (Imp)

5127 return *Imp ? TrueVal : FalseVal;

5128

5132 return FalseVal;

5134 return TrueVal;

5135 }

5136 return nullptr;

5137}

5138

5143

5144

5145

5149

5150 unsigned AS =

5152

5153

5154 if (Indices.empty())

5155 return Ptr;

5156

5157

5161 for (Value *Op : Indices) {

5162

5163

5166 break;

5167 }

5168 }

5169 }

5170

5171

5173 return Ptr;

5174

5175

5176

5179

5180

5183

5184 bool IsScalableVec =

5185 SrcTy->isScalableTy() || any_of(Indices, [](const Value *V) {

5187 });

5188

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

5190 Type *Ty = SrcTy;

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

5195

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

5197 return Ptr;

5198

5199

5200

5201

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

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

5207 };

5208

5209 if (TyAllocSize == 1 &&

5212 CanSimplify())

5213 return P;

5214

5215

5216

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

5221 return P;

5222

5223

5224

5228 CanSimplify())

5229 return P;

5230 }

5231 }

5232 }

5233

5236 unsigned IdxWidth =

5239 APInt BasePtrOffset(IdxWidth, 0);

5240 Value *StrippedBasePtr =

5242

5243

5244

5245

5246

5247

5250 !BasePtrOffset.isZero()) {

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

5253 }

5254

5257 !BasePtrOffset.isOne()) {

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

5260 }

5261 }

5262 }

5263

5264

5266 return nullptr;

5267

5270 Indices);

5271

5272 auto *CE =

5275}

5276

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

5280}

5281

5282

5283

5290

5291

5292

5295 return Agg;

5296

5297

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

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

5301

5302

5306 return EV->getAggregateOperand();

5307

5308

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

5310 return Agg;

5311 }

5312

5313 return nullptr;

5314}

5315

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

5320}

5321

5324

5328 if (VecC && ValC && IdxC)

5330

5331

5336 }

5337

5338

5341

5342

5343

5346 return Vec;

5347

5348

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

5350 return Vec;

5351

5352

5353

5354

5356 return Vec;

5357

5358 return nullptr;

5359}

5360

5361

5362

5367

5368

5369 unsigned NumIdxs = Idxs.size();

5373 unsigned NumInsertValueIdxs = InsertValueIdxs.size();

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

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

5376 Idxs.slice(0, NumCommonIdxs)) {

5377 if (NumIdxs == NumInsertValueIdxs)

5378 return IVI->getInsertedValueOperand();

5379 break;

5380 }

5381 }

5382

5383

5385 if (Idxs.size() == 1 &&

5390 if (Idxs[0] == 0)

5391 return V;

5392 assert(Idxs[0] == 1 && "invalid index");

5394 }

5395

5396 return nullptr;

5397}

5398

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

5402}

5403

5404

5405

5412

5415 }

5416

5417

5418

5421

5422

5423

5425

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

5429

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

5434 return Elt;

5435 } else {

5436

5437

5438

5439

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

5442 return IE->getOperand(1);

5443

5444

5447 }

5448 return nullptr;

5449}

5450

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

5454}

5455

5456

5459

5460

5461

5462

5463

5464

5465 Value *CommonValue = nullptr;

5466 bool HasPoisonInput = false;

5467 bool HasUndefInput = false;

5469

5471 continue;

5473 HasPoisonInput = true;

5474 continue;

5475 }

5477

5478 HasUndefInput = true;

5479 continue;

5480 }

5481 if (CommonValue && Incoming != CommonValue)

5482 return nullptr;

5484 }

5485

5486

5487

5488 if (!CommonValue)

5491

5492 if (HasPoisonInput || HasUndefInput) {

5493

5494

5495

5497 return nullptr;

5498

5499

5500 if (HasUndefInput &&

5502 return nullptr;

5503 return CommonValue;

5504 }

5505

5506 return CommonValue;

5507}

5508

5513

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

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

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

5518 Type *DstTy = Ty;

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

5520 auto FirstOp = CI->getOpcode();

5523 &Q.DL) == Instruction::BitCast)

5524 return Src;

5525 }

5526 }

5527

5528

5529 if (CastOpc == Instruction::BitCast)

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

5531 return Op;

5532

5533

5535 if ((CastOpc == Instruction::PtrToInt || CastOpc == Instruction::PtrToAddr) &&

5540 return X;

5541

5542 return nullptr;

5543}

5544

5549

5550

5551

5552

5554 int MaskVal, Value *RootVec,

5555 unsigned MaxRecurse) {

5556 if (!MaxRecurse--)

5557 return nullptr;

5558

5559

5560

5561 if (MaskVal == -1)

5562 return nullptr;

5563

5564

5566 int RootElt = MaskVal;

5567 Value *SourceOp = Op0;

5568 if (MaskVal >= InVecNumElts) {

5569 RootElt = MaskVal - InVecNumElts;

5570 SourceOp = Op1;

5571 }

5572

5573

5574

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

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

5579 }

5580

5581

5582

5583 if (!RootVec)

5584 RootVec = SourceOp;

5585

5586

5587 if (RootVec != SourceOp)

5588 return nullptr;

5589

5590

5591

5592 if (RootElt != DestElt)

5593 return nullptr;

5594

5595 return RootVec;

5596}

5597

5601 unsigned MaxRecurse) {

5604

5606 unsigned MaskNumElts = Mask.size();

5607 ElementCount InVecEltCount = InVecTy->getElementCount();

5608

5609 bool Scalable = InVecEltCount.isScalable();

5610

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

5613

5614

5615

5616 if (!Scalable) {

5617 bool MaskSelects0 = false, MaskSelects1 = false;

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

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

5621 continue;

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

5623 MaskSelects0 = true;

5624 else

5625 MaskSelects1 = true;

5626 }

5627 if (!MaskSelects0)

5629 if (!MaskSelects1)

5631 }

5632

5635

5636

5637

5638

5639 if (Op0Const && Op1Const)

5641

5642

5643

5644

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

5649 }

5650

5651

5652

5653

5654

5655

5656

5661

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

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

5665 })) {

5667

5668

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

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

5674 }

5675 }

5676

5677

5678

5680 if (Q.isUndefValue(Op1) && RetTy == InVecTy &&

5681 all_equal(OpShuf->getShuffleMask()))

5682 return Op0;

5683

5684

5685

5686 if (Scalable)

5687 return nullptr;

5688

5689

5690

5691

5693 return nullptr;

5694

5695

5696

5697

5698

5699 Value *RootVec = nullptr;

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

5701

5702

5703 RootVec =

5705

5706

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

5708 return nullptr;

5709 }

5710 return RootVec;

5711}

5712

5713

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

5718}

5719

5724 return nullptr;

5725}

5726

5727

5728

5732 return C;

5733

5735

5737 return X;

5738

5739 return nullptr;

5740}

5741

5746

5747

5748

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

5752 unsigned NumElts = VecTy->getNumElements();

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

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

5756

5757

5759 NewC[i] = EltC;

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

5761 NewC[i] = ConstantFP::get(

5763 else

5765 }

5767 }

5768

5769

5770

5771 if (!In->isNaN())

5773

5774

5775

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

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

5781 }

5782

5783

5784

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

5786}

5787

5788

5789

5790

5795

5796

5799

5804

5805

5806

5807

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

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

5812

5814

5815

5816

5817

5818 if (IsUndef)

5820 if (IsNan)

5823 if (IsNan)

5825 }

5826 }

5827 return nullptr;

5828}

5829

5830

5831

5839 return C;

5840

5842 return C;

5843

5844

5845

5846

5847

5848

5853 return Op0;

5854

5855

5859 return Op0;

5860

5862 return nullptr;

5863

5865

5867 return Op1;

5868

5869

5870

5871

5872

5873

5874

5875

5879

5883 }

5884

5885

5886

5891 return X;

5892

5893 return nullptr;

5894}

5895

5896

5897

5905 return C;

5906

5908 return C;

5909

5910

5915 return Op0;

5916

5917

5921 return Op0;

5922

5923

5924

5928 return X;

5929

5930

5931

5936 return X;

5937

5939 return nullptr;

5940

5942

5943 if (Op0 == Op1)

5945

5946

5948 return Op0;

5949

5950

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

5953 }

5954

5955

5956

5960 return X;

5961

5962 return nullptr;

5963}

5964

5970 return C;

5971

5973 return nullptr;

5974

5975

5978

5979

5981 return Op0;

5982

5984

5987

5990

5993

5994 if (Known.SignBit == false)

5995 return Op1;

5996

5997 if (Known.SignBit == true)

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

5999 }

6000 }

6001

6002

6003

6004

6005

6009 return X;

6010

6011 return nullptr;

6012}

6013

6014

6022 return C;

6023

6024

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

6026}

6027

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

6033 Rounding);

6034}

6035

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

6041 Rounding);

6042}

6043

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

6049 Rounding);

6050}

6051

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

6057 Rounding);

6058}

6059

6067 return C;

6068

6070 return C;

6071

6073 return nullptr;

6074

6075

6077 return Op0;

6078

6079

6080

6081

6084

6086

6087

6088 if (Op0 == Op1)

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

6090

6091

6094 return X;

6095

6096

6097

6098

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

6102

6103

6106 }

6107

6108 return nullptr;

6109}

6110

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

6116 Rounding);

6117}

6118

6126 return C;

6127

6129 return C;

6130

6132 return nullptr;

6133

6134

6135

6136

6138

6141

6144 }

6145

6146 return nullptr;

6147}

6148

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

6154 Rounding);

6155}

6156

6157

6158

6159

6160

6162 unsigned MaxRecurse) {

6163 switch (Opcode) {

6164 case Instruction::FNeg:

6166 default:

6168 }

6169}

6170

6171

6172

6173

6176 unsigned MaxRecurse) {

6177 switch (Opcode) {

6178 case Instruction::FNeg:

6180 default:

6182 }

6183}

6184

6188

6193

6194

6195

6198 switch (Opcode) {

6199 case Instruction::Add:

6201 MaxRecurse);

6202 case Instruction::Sub:

6204 MaxRecurse);

6205 case Instruction::Mul:

6207 MaxRecurse);

6208 case Instruction::SDiv:

6210 case Instruction::UDiv:

6212 case Instruction::SRem:

6214 case Instruction::URem:

6216 case Instruction::Shl:

6218 MaxRecurse);

6219 case Instruction::LShr:

6221 case Instruction::AShr:

6223 case Instruction::And:

6225 case Instruction::Or:

6227 case Instruction::Xor:

6229 case Instruction::FAdd:

6231 case Instruction::FSub:

6233 case Instruction::FMul:

6235 case Instruction::FDiv:

6237 case Instruction::FRem:

6239 default:

6241 }

6242}

6243

6244

6245

6246

6249 unsigned MaxRecurse) {

6250 switch (Opcode) {

6251 case Instruction::FAdd:

6253 case Instruction::FSub:

6255 case Instruction::FMul:

6257 case Instruction::FDiv:

6259 default:

6261 }

6262}

6263

6266 return ::simplifyBinOp(Opcode, LHS, RHS, Q, RecursionLimit);

6267}

6268

6271 return ::simplifyBinOp(Opcode, LHS, RHS, FMF, Q, RecursionLimit);

6272}

6273

6274

6281

6284 return ::simplifyCmpInst(Predicate, LHS, RHS, Q, RecursionLimit);

6285}

6286

6288 switch (ID) {

6289 default:

6290 return false;

6291

6292

6293 case Intrinsic::fabs:

6294 case Intrinsic:🤣

6295 case Intrinsic::ceil:

6296 case Intrinsic::trunc:

6297 case Intrinsic::rint:

6298 case Intrinsic::nearbyint:

6299 case Intrinsic::round:

6300 case Intrinsic::roundeven:

6301 case Intrinsic::canonicalize:

6302 case Intrinsic::arithmetic_fence:

6303 return true;

6304 }

6305}

6306

6307

6308

6310 switch (ID) {

6311 default:

6312 return false;

6313

6314 case Intrinsic:🤣

6315 case Intrinsic::ceil:

6316 case Intrinsic::trunc:

6317 case Intrinsic::rint:

6318 case Intrinsic::nearbyint:

6319 case Intrinsic::round:

6320 case Intrinsic::roundeven:

6321 return true;

6322 }

6323}

6324

6328 APInt PtrOffset;

6330 return nullptr;

6331

6333

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

6336 return nullptr;

6337

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

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

6341 return nullptr;

6342

6345 if (!Loaded)

6346 return nullptr;

6347

6349 if (!LoadedCE)

6350 return nullptr;

6351

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

6354 if (!LoadedCE)

6355 return nullptr;

6356 }

6357

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

6359 return nullptr;

6360

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

6363 return nullptr;

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

6365

6368 APInt LoadedRHSOffset;

6370 DL) ||

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

6372 return nullptr;

6373

6374 return LoadedLHSPtr;

6375}

6376

6377

6379 bool IsStrict) {

6380

6381

6383 return Op0;

6384

6385

6388

6389 if (!IsStrict) {

6390

6391

6392

6394 return Op0;

6395 }

6396

6399

6400

6401

6402

6403

6404

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

6406 return Op0;

6407

6408

6409

6410 if (IsStrict)

6411 return nullptr;

6412

6413

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

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

6416

6417

6418

6419

6420

6422 return Op0;

6423

6424 return nullptr;

6425}

6426

6430

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

6435 return II;

6436

6438

6439

6440

6441

6442

6446 return Op0;

6447 }

6448

6450 switch (IID) {

6451 case Intrinsic::fabs:

6453 return Op0;

6454 break;

6455 case Intrinsic::bswap:

6456

6458 return X;

6459 break;

6460 case Intrinsic::bitreverse:

6461

6463 return X;

6464 break;

6465 case Intrinsic::ctpop: {

6466

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

6469

6470

6473 Q))

6474 return Op0;

6475 break;

6476 }

6477 case Intrinsic::exp:

6478

6479 if (Call->hasAllowReassoc() &&

6481 return X;

6482 break;

6483 case Intrinsic::exp2:

6484

6485 if (Call->hasAllowReassoc() &&

6487 return X;

6488 break;

6489 case Intrinsic::exp10:

6490

6491 if (Call->hasAllowReassoc() &&

6493 return X;

6494 break;

6495 case Intrinsic:🪵

6496

6497 if (Call->hasAllowReassoc() &&

6499 return X;

6500 break;

6501 case Intrinsic::log2:

6502

6503 if (Call->hasAllowReassoc() &&

6507 return X;

6508 break;

6509 case Intrinsic::log10:

6510

6511

6512 if (Call->hasAllowReassoc() &&

6516 return X;

6517 break;

6518 case Intrinsic::vector_reverse:

6519

6521 return X;

6522

6524 return Op0;

6525 break;

6526 default:

6527 break;

6528 }

6529

6530 return nullptr;

6531}

6532

6533

6534

6535

6539 return nullptr;

6540

6542 if (!MM0)

6543 return nullptr;

6545

6546 if (Op1 == X || Op1 == Y ||

6548

6549 if (IID0 == IID)

6550 return MM0;

6551

6553 return Op1;

6554 }

6555 return nullptr;

6556}

6557

6558

6559

6560

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

6564 IID == Intrinsic::maximum || IID == Intrinsic::minimum ||

6565 IID == Intrinsic::maximumnum || IID == Intrinsic::minimumnum) &&

6566 "Unsupported intrinsic");

6567

6569

6570

6571

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

6573 return nullptr;

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

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

6576

6577

6578

6579

6580

6581

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

6583 return M0;

6584

6586 if (M1)

6587 return nullptr;

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

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

6591

6592

6593

6594

6595

6596

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

6599 return M0;

6600

6601 return nullptr;

6602}

6603

6612

6613

6614

6615

6619 Constant **OutNewConstVal) {

6620 assert(OutNewConstVal != nullptr);

6621

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

6623 bool ReturnsOtherForAllNaNs =

6624 IID == Intrinsic::minimumnum || IID == Intrinsic::maximumnum;

6625 bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum ||

6626 IID == Intrinsic::minimumnum;

6627

6628

6630 *OutNewConstVal = const_cast<Constant *>(RHSConst);

6632 }

6633

6635 if (!CFP)

6638

6639

6640

6641

6642

6643

6644

6645 if (CAPF.isNaN()) {

6646 if (PropagateNaN) {

6647 *OutNewConstVal = ConstantFP::get(CFP->getType(), CAPF.makeQuiet());

6649 } else if (ReturnsOtherForAllNaNs || !CAPF.isSignaling()) {

6651 }

6653 }

6654

6656

6657

6658

6659

6661 (ReturnsOtherForAllNaNs || (Call && Call->hasNoNaNs()))) {

6662 *OutNewConstVal = const_cast<Constant *>(RHSConst);

6664 }

6665

6666

6667

6668

6669

6670

6671

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

6675 }

6677}

6678

6683 unsigned Width = ReturnType->getPrimitiveSizeInBits();

6684

6685

6686 switch (IID) {

6687 case Intrinsic::aarch64_sve_eorv:

6688 case Intrinsic::aarch64_sve_orv:

6689 case Intrinsic::aarch64_sve_saddv:

6690 case Intrinsic::aarch64_sve_uaddv:

6691 case Intrinsic::aarch64_sve_umaxv:

6693 return ConstantInt::get(ReturnType, 0);

6694 break;

6695 case Intrinsic::aarch64_sve_andv:

6696 case Intrinsic::aarch64_sve_uminv:

6699 break;

6700 case Intrinsic::aarch64_sve_smaxv:

6703 break;

6704 case Intrinsic::aarch64_sve_sminv:

6707 break;

6708 }

6709

6710 switch (IID) {

6711 case Intrinsic::aarch64_sve_andv:

6712 case Intrinsic::aarch64_sve_orv:

6713 case Intrinsic::aarch64_sve_smaxv:

6714 case Intrinsic::aarch64_sve_sminv:

6715 case Intrinsic::aarch64_sve_umaxv:

6716 case Intrinsic::aarch64_sve_uminv:

6717

6720 assert(SplatVal->getType() == ReturnType && "Unexpected result type!");

6721 return SplatVal;

6722 }

6723 }

6724 break;

6725 case Intrinsic::aarch64_sve_eorv:

6726

6728 return ConstantInt::get(ReturnType, 0);

6729 break;

6730 }

6731

6732 return nullptr;

6733}

6734

6739 unsigned BitWidth = ReturnType->getScalarSizeInBits();

6740 switch (IID) {

6741 case Intrinsic::get_active_lane_mask: {

6744

6747 Attribute Attr = F->getFnAttribute(Attribute::VScaleRange);

6748 if (ScalableTy && Attr.isValid()) {

6750 if (!VScaleMax)

6751 break;

6752 uint64_t MaxPossibleMaskElements =

6753 (uint64_t)ScalableTy->getMinNumElements() * (*VScaleMax);

6754

6755 const APInt *Op1Val;

6757 Op1Val->uge(MaxPossibleMaskElements))

6759 }

6760 break;

6761 }

6762 case Intrinsic::abs:

6763

6764

6765

6767 return Op0;

6768 break;

6769

6770 case Intrinsic::cttz: {

6773 return X;

6774 break;

6775 }

6776 case Intrinsic::ctlz: {

6779 return X;

6782 break;

6783 }

6784 case Intrinsic::ptrmask: {

6785

6786

6789

6792 "Invalid mask width");

6793

6794

6796 return Op0;

6797

6798

6799

6800

6802 return Op0;

6803

6807

6808

6809 APInt IrrelevantPtrBits =

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

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

6813 Q.DL);

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

6815 return Op0;

6816 }

6817 break;

6818 }

6819 case Intrinsic::smax:

6820 case Intrinsic::smin:

6821 case Intrinsic::umax:

6822 case Intrinsic::umin: {

6823

6824 if (Op0 == Op1)

6825 return Op0;

6826

6827

6830

6831

6833 return ConstantInt::get(

6835

6838

6839

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

6842

6843

6844

6845

6848 return Op0;

6849

6850

6851

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

6854

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

6856 const APInt *InnerC;

6861 return Op0;

6862 }

6863 }

6864

6866 return V;

6868 return V;

6869

6873 return Op0;

6875 return Op1;

6876

6877 break;

6878 }

6879 case Intrinsic::scmp:

6880 case Intrinsic::ucmp: {

6881

6882

6885

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

6890

6895

6896 break;

6897 }

6898 case Intrinsic::usub_with_overflow:

6899 case Intrinsic::ssub_with_overflow:

6900

6901

6902

6905 break;

6906 case Intrinsic::uadd_with_overflow:

6907 case Intrinsic::sadd_with_overflow:

6908

6909

6915 }

6916 break;

6917 case Intrinsic::umul_with_overflow:

6918 case Intrinsic::smul_with_overflow:

6919

6920

6923

6924

6927 break;

6928 case Intrinsic::uadd_sat:

6929

6930

6933 [[fallthrough]];

6934 case Intrinsic::sadd_sat:

6935

6936

6937

6938

6941

6942

6944 return Op0;

6945

6947 return Op1;

6948 break;

6949 case Intrinsic::usub_sat:

6950

6953 [[fallthrough]];

6954 case Intrinsic::ssub_sat:

6955

6958

6960 return Op0;

6961 break;

6962 case Intrinsic::load_relative:

6966 break;

6967 case Intrinsic::powi:

6969

6970 if (Power->isZero())

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

6972

6973 if (Power->isOne())

6974 return Op0;

6975 }

6976 break;

6977 case Intrinsic::ldexp:

6979 case Intrinsic::copysign:

6980

6981 if (Op0 == Op1)

6982 return Op0;

6983

6984

6987 return Op1;

6988 break;

6989 case Intrinsic::is_fpclass: {

6991

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

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

6998 break;

6999 }

7000 case Intrinsic::maxnum:

7001 case Intrinsic::minnum:

7002 case Intrinsic::maximum:

7003 case Intrinsic::minimum:

7004 case Intrinsic::maximumnum:

7005 case Intrinsic::minimumnum: {

7006

7007

7008

7009

7010

7011

7012 if (Op0 == Op1)

7013 return Op0;

7014

7015

7018

7021 Constant *NewConst = nullptr;

7022

7024 ElementCount ElemCount = VTy->getElementCount();

7025

7026 if (Constant *SplatVal = C->getSplatValue()) {

7027

7031

7032 } else if (ElemCount.isFixed()) {

7033

7035

7036

7037

7038

7039

7041 for (unsigned i = 0; i != ElemCount.getFixedValue(); ++i) {

7042 auto *Elt = C->getAggregateElement(i);

7043 if (!Elt) {

7045 break;

7046 }

7049 (ElemResult != OptResult &&

7053 break;

7054 }

7055 NewC[i] = NewConst;

7057 OptResult = ElemResult;

7058 }

7061 }

7062 } else {

7063

7065 }

7066

7069 return Op0;

7071 return NewConst;

7072 }

7073

7074

7075

7077 return V;

7079 return V;

7080

7081 break;

7082 }

7083 case Intrinsic::vector_extract: {

7084

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

7090 return X;

7091

7092 break;

7093 }

7094

7095 case Intrinsic::aarch64_sve_andv:

7096 case Intrinsic::aarch64_sve_eorv:

7097 case Intrinsic::aarch64_sve_orv:

7098 case Intrinsic::aarch64_sve_saddv:

7099 case Intrinsic::aarch64_sve_smaxv:

7100 case Intrinsic::aarch64_sve_sminv:

7101 case Intrinsic::aarch64_sve_uaddv:

7102 case Intrinsic::aarch64_sve_umaxv:

7103 case Intrinsic::aarch64_sve_uminv:

7105 default:

7106 break;

7107 }

7108

7109 return nullptr;

7110}

7111

7115

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

7117 unsigned NumOperands = Args.size();

7120

7124

7125

7126 if (!NumOperands) {

7127 switch (IID) {

7128 case Intrinsic::vscale: {

7129 Type *RetTy = F->getReturnType();

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

7133 return nullptr;

7134 }

7135 default:

7136 return nullptr;

7137 }

7138 }

7139

7140 if (NumOperands == 1)

7142

7143 if (NumOperands == 2)

7146

7147

7148 switch (IID) {

7149 case Intrinsic::masked_load:

7150 case Intrinsic::masked_gather: {

7151 Value *MaskArg = Args[1];

7152 Value *PassthruArg = Args[2];

7153

7155 return PassthruArg;

7156 return nullptr;

7157 }

7158 case Intrinsic::fshl:

7159 case Intrinsic::fshr: {

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

7161

7162

7165

7166

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

7169

7170 const APInt *ShAmtC;

7172

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

7176 }

7177

7178

7181

7182

7185

7186 return nullptr;

7187 }

7188 case Intrinsic::experimental_constrained_fma: {

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

7191 *FPI->getRoundingMode()))

7192 return V;

7193 return nullptr;

7194 }

7195 case Intrinsic::fma:

7196 case Intrinsic::fmuladd: {

7199 return V;

7200 return nullptr;

7201 }

7202 case Intrinsic::smul_fix:

7203 case Intrinsic::smul_fix_sat: {

7204 Value *Op0 = Args[0];

7205 Value *Op1 = Args[1];

7206 Value *Op2 = Args[2];

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

7208

7209

7210

7211

7214

7215

7218

7219

7222

7223

7224 APInt ScaledOne =

7228 return Op0;

7229

7230 return nullptr;

7231 }

7232 case Intrinsic::vector_insert: {

7233 Value *Vec = Args[0];

7234 Value *SubVec = Args[1];

7235 Value *Idx = Args[2];

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

7237

7238

7239

7242 if (match(SubVec,

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

7245 X->getType() == ReturnType)

7246 return X;

7247

7248 return nullptr;

7249 }

7250 case Intrinsic::experimental_constrained_fadd: {

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

7253 *FPI->getExceptionBehavior(),

7254 *FPI->getRoundingMode());

7255 }

7256 case Intrinsic::experimental_constrained_fsub: {

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

7259 *FPI->getExceptionBehavior(),

7260 *FPI->getRoundingMode());

7261 }

7262 case Intrinsic::experimental_constrained_fmul: {

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

7265 *FPI->getExceptionBehavior(),

7266 *FPI->getRoundingMode());

7267 }

7268 case Intrinsic::experimental_constrained_fdiv: {

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

7271 *FPI->getExceptionBehavior(),

7272 *FPI->getRoundingMode());

7273 }

7274 case Intrinsic::experimental_constrained_frem: {

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

7277 *FPI->getExceptionBehavior(),

7278 *FPI->getRoundingMode());

7279 }

7280 case Intrinsic::experimental_constrained_ldexp:

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

7282 case Intrinsic::experimental_gc_relocate: {

7286

7287

7290 }

7291

7293

7294

7295

7297

7299 }

7300 }

7301 return nullptr;

7302 }

7303 case Intrinsic::experimental_vp_reverse: {

7304 Value *Vec = Call->getArgOperand(0);

7305 Value *Mask = Call->getArgOperand(1);

7306 Value *EVL = Call->getArgOperand(2);

7307

7309

7313 return X;

7314

7315

7317 return Vec;

7318 return nullptr;

7319 }

7320 default:

7321 return nullptr;

7322 }

7323}

7324

7330 return nullptr;

7331

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

7334 for (Value *Arg : Args) {

7336 if (C) {

7338 continue;

7339 return nullptr;

7340 }

7342 }

7343

7345}

7346

7349

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

7351

7352

7353

7354 if (Call->isMustTailCall())

7355 return nullptr;

7356

7357

7358

7361

7363 return V;

7364

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

7368 return Ret;

7369

7370 return nullptr;

7371}

7372

7377 return V;

7379 return Ret;

7380 return nullptr;

7381}

7382

7383

7385

7387 return Op0;

7388

7389 return nullptr;

7390}

7391

7393 return ::simplifyFreezeInst(Op0, Q);

7394}

7395

7399 return nullptr;

7400

7403

7404

7405

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

7408 return nullptr;

7409

7410

7411

7414 return C;

7415

7416

7417

7420 Q.DL, Offset, true,

7421 true);

7422 if (PtrOp == GV) {

7423

7426 Q.DL);

7427 }

7428

7429 return nullptr;

7430}

7431

7432

7433

7434

7438 unsigned MaxRecurse) {

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

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

7442

7444

7445 switch (I->getOpcode()) {

7446 default:

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

7452 }

7453 return nullptr;

7454 case Instruction::FNeg:

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

7456 case Instruction::FAdd:

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

7458 MaxRecurse);

7459 case Instruction::Add:

7463 case Instruction::FSub:

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

7465 MaxRecurse);

7466 case Instruction::Sub:

7470 case Instruction::FMul:

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

7472 MaxRecurse);

7473 case Instruction::Mul:

7477 case Instruction::SDiv:

7480 MaxRecurse);

7481 case Instruction::UDiv:

7484 MaxRecurse);

7485 case Instruction::FDiv:

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

7487 MaxRecurse);

7488 case Instruction::SRem:

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

7490 case Instruction::URem:

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

7492 case Instruction::FRem:

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

7494 MaxRecurse);

7495 case Instruction::Shl:

7499 case Instruction::LShr:

7502 MaxRecurse);

7503 case Instruction::AShr:

7506 MaxRecurse);

7507 case Instruction::And:

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

7509 case Instruction::Or:

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

7511 case Instruction::Xor:

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

7513 case Instruction::ICmp:

7515 NewOps[1], Q, MaxRecurse);

7516 case Instruction::FCmp:

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

7519 case Instruction::Select:

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

7521 case Instruction::GetElementPtr: {

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

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

7525 MaxRecurse);

7526 }

7527 case Instruction::InsertValue: {

7530 MaxRecurse);

7531 }

7532 case Instruction::InsertElement:

7534 case Instruction::ExtractValue: {

7537 MaxRecurse);

7538 }

7539 case Instruction::ExtractElement:

7541 case Instruction::ShuffleVector: {

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

7545 MaxRecurse);

7546 }

7547 case Instruction::PHI:

7549 case Instruction::Call:

7553 case Instruction::Freeze:

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

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

7557#undef HANDLE_CAST_INST

7559 MaxRecurse);

7560 case Instruction::Alloca:

7561

7562 return nullptr;

7563 case Instruction::Load:

7565 }

7566}

7567

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

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

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

7574}

7575

7579

7580

7581

7582

7584}

7585

7586

7587

7588

7589

7590

7591

7592

7593

7594

7595

7596

7597

7598

7603 bool Simplified = false;

7606

7607

7608

7609 if (SimpleV) {

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

7611 if (U != I)

7613

7614

7615 I->replaceAllUsesWith(SimpleV);

7616

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

7618 I->eraseFromParent();

7619 } else {

7621 }

7622

7623

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

7625 I = Worklist[Idx];

7626

7627

7629 if (!SimpleV) {

7630 if (UnsimplifiedUsers)

7631 UnsimplifiedUsers->insert(I);

7632 continue;

7633 }

7634

7635 Simplified = true;

7636

7637

7638

7639

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

7642

7643

7644 I->replaceAllUsesWith(SimpleV);

7645

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

7647 I->eraseFromParent();

7648 }

7649 return Simplified;

7650}

7651

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

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

7659 UnsimplifiedUsers);

7660}

7661

7662namespace llvm {

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

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

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

7671}

7672

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

7676}

7677

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

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

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

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

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

7685}

7688

7691 return false;

7692

7694}

7695

7696}

7697

7698void InstSimplifyFolder::anchor() {}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

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

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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

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

Simplify comparison with false branch of select.

Definition InstructionSimplify.cpp:139

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

Definition InstructionSimplify.cpp:115

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

Definition InstructionSimplify.cpp:6536

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

Definition InstructionSimplify.cpp:232

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

Definition InstructionSimplify.cpp:566

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

Definition InstructionSimplify.cpp:2660

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

Definition InstructionSimplify.cpp:5720

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.

Definition InstructionSimplify.cpp:148

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

Definition InstructionSimplify.cpp:525

static Constant * propagateNaN(Constant *In)

Try to propagate existing NaN values when possible.

Definition InstructionSimplify.cpp:5749

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

Fold an icmp when its operands have i1 scalar type.

Definition InstructionSimplify.cpp:2867

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

Definition InstructionSimplify.cpp:3154

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

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

Definition InstructionSimplify.cpp:3084

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

Definition InstructionSimplify.cpp:6325

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.

Definition InstructionSimplify.cpp:1140

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

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

Definition InstructionSimplify.cpp:5457

@ RecursionLimit

Definition InstructionSimplify.cpp:57

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

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

Definition InstructionSimplify.cpp:98

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

Definition InstructionSimplify.cpp:2020

static bool isIdempotent(Intrinsic::ID ID)

Definition InstructionSimplify.cpp:6287

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

Helper method to get range from metadata or attribute.

Definition InstructionSimplify.cpp:3774

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

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

Definition InstructionSimplify.cpp:1706

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

Definition InstructionSimplify.cpp:1512

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

Definition InstructionSimplify.cpp:7325

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

Definition InstructionSimplify.cpp:4345

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

Definition InstructionSimplify.cpp:1658

static Value * simplifyAndOrOfFCmpsWithConstants(FCmpInst *Cmp0, FCmpInst *Cmp1, bool IsAnd)

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

Definition InstructionSimplify.cpp:1822

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

Definition InstructionSimplify.cpp:3533

MonotonicType

Definition InstructionSimplify.cpp:3081

@ LowerEq

Definition InstructionSimplify.cpp:3081

@ GreaterEq

Definition InstructionSimplify.cpp:3081

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

Simplify comparison with true branch of select.

Definition InstructionSimplify.cpp:131

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

Definition InstructionSimplify.cpp:7112

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

Definition InstructionSimplify.cpp:3135

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

Returns true if a shift by Amount always yields poison.

Definition InstructionSimplify.cpp:1271

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.

Definition InstructionSimplify.cpp:1372

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

Definition InstructionSimplify.cpp:3741

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.

Definition InstructionSimplify.cpp:712

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

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

Definition InstructionSimplify.cpp:6174

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

Definition InstructionSimplify.cpp:3299

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

Definition InstructionSimplify.cpp:1796

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

Definition InstructionSimplify.cpp:198

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.

Definition InstructionSimplify.cpp:2970

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.

Definition InstructionSimplify.cpp:4822

static Constant * getFalse(Type *Ty)

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

Definition InstructionSimplify.cpp:91

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.

Definition InstructionSimplify.cpp:1046

static bool removesFPFraction(Intrinsic::ID ID)

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

Definition InstructionSimplify.cpp:6309

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

Definition InstructionSimplify.cpp:1749

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

Definition InstructionSimplify.cpp:4679

MinMaxOptResult

Definition InstructionSimplify.cpp:6604

@ UseEither

Definition InstructionSimplify.cpp:6610

@ CannotOptimize

Definition InstructionSimplify.cpp:6605

@ UseNewConstVal

Definition InstructionSimplify.cpp:6606

@ UseOtherVal

Definition InstructionSimplify.cpp:6607

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

Definition InstructionSimplify.cpp:3274

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

Definition InstructionSimplify.cpp:4553

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

Generic simplifications for associative binary operations.

Definition InstructionSimplify.cpp:250

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

Definition InstructionSimplify.cpp:478

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

Definition InstructionSimplify.cpp:4594

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.

Definition InstructionSimplify.cpp:5791

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

Definition InstructionSimplify.cpp:433

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.

Definition InstructionSimplify.cpp:7599

static bool isAllocDisjoint(const Value *V)

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

Definition InstructionSimplify.cpp:2640

static Constant * getTrue(Type *Ty)

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

Definition InstructionSimplify.cpp:95

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

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

Definition InstructionSimplify.cpp:981

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

Definition InstructionSimplify.cpp:6378

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

Definition InstructionSimplify.cpp:1997

static Value * simplifySelectWithBitTest(Value *CondVal, Value *TrueVal, Value *FalseVal)

An alternative way to test if a bit is set or not.

Definition InstructionSimplify.cpp:4668

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

Definition InstructionSimplify.cpp:2256

static Type * getCompareTy(Value *Op)

Definition InstructionSimplify.cpp:2614

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

Definition InstructionSimplify.cpp:1726

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.

Definition InstructionSimplify.cpp:972

bool isSelectWithIdenticalPHI(PHINode &PN, PHINode &IdenticalPN)

Look for the following pattern and simplify to_fold to identicalPhi.

Definition InstructionSimplify.cpp:4899

static APInt stripAndComputeConstantOffsets(const DataLayout &DL, Value *&V)

Compute the base pointer and cumulative constant offsets for V.

Definition InstructionSimplify.cpp:675

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

Definition InstructionSimplify.cpp:5553

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

Definition InstructionSimplify.cpp:1859

static MinMaxOptResult OptimizeConstMinMax(const Constant *RHSConst, const Intrinsic::ID IID, const CallBase *Call, Constant **OutNewConstVal)

Definition InstructionSimplify.cpp:6616

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

Definition InstructionSimplify.cpp:3030

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

Definition InstructionSimplify.cpp:2621

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

Definition InstructionSimplify.cpp:1903

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

Definition InstructionSimplify.cpp:354

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

Compute the constant difference between two pointer values.

Definition InstructionSimplify.cpp:688

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

Definition InstructionSimplify.cpp:1621

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

Definition InstructionSimplify.cpp:1946

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

Definition InstructionSimplify.cpp:3718

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.

Definition InstructionSimplify.cpp:1302

static Value * simplifySVEIntReduction(Intrinsic::ID IID, Type *ReturnType, Value *Op0, Value *Op1)

Definition InstructionSimplify.cpp:6679

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

Definition InstructionSimplify.cpp:2730

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

These are simplifications common to SRem and URem.

Definition InstructionSimplify.cpp:1175

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

Does the given value dominate the specified phi node?

Definition InstructionSimplify.cpp:176

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.

Definition InstructionSimplify.cpp:4704

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

Definition InstructionSimplify.cpp:6561

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

Definition InstructionSimplify.cpp:6427

const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]

This header provides classes for managing per-loop analyses.

uint64_t IntrinsicInst * II

const SmallVectorImpl< MachineOperand > & Cond

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 unsigned getScalarSizeInBits(Type *Ty)

static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

static SymbolRef::Type getType(const Symbol *Sym)

static const uint32_t IV[8]

APFloat makeQuiet() const

Assuming this is an IEEE-754 NaN value, quiet its signaling bit.

Class for arbitrary precision integers.

LLVM_ABI APInt zextOrTrunc(unsigned width) const

Zero extend or truncate to width.

unsigned getActiveBits() const

Compute the number of active bits in the value.

static APInt getMaxValue(unsigned numBits)

Gets maximum unsigned value of APInt for specific bit width.

bool isZero() const

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

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

static APInt getSignedMaxValue(unsigned numBits)

Gets maximum signed value of APInt for a specific bit width.

bool intersects(const APInt &RHS) const

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

bool sle(const APInt &RHS) const

Signed less or equal comparison.

unsigned countr_zero() const

Count the number of trailing zero bits.

static APInt getSignedMinValue(unsigned numBits)

Gets minimum signed value of APInt for a specific bit width.

bool isNonPositive() const

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

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

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

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.

Functions, function parameters, and return types can have attributes to indicate how they should be t...

LLVM_ABI std::optional< unsigned > getVScaleRangeMax() const

Returns the maximum value for the vscale_range attribute or std::nullopt when unknown.

bool isValid() const

Return true if the attribute is any kind of attribute.

LLVM Basic Block Representation.

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 LLVM_ABI unsigned isEliminableCastPair(Instruction::CastOps firstOpcode, Instruction::CastOps secondOpcode, Type *SrcTy, Type *MidTy, Type *DstTy, const DataLayout *DL)

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.

@ FCMP_OEQ

0 0 0 1 True if ordered and equal

@ FCMP_TRUE

1 1 1 1 Always true (always folded)

@ ICMP_SLT

signed less than

@ ICMP_SLE

signed less or equal

@ FCMP_OLT

0 1 0 0 True if ordered and less than

@ FCMP_ULE

1 1 0 1 True if unordered, less than, or equal

@ FCMP_OGT

0 0 1 0 True if ordered and greater than

@ FCMP_OGE

0 0 1 1 True if ordered and greater than or equal

@ ICMP_UGE

unsigned greater or equal

@ ICMP_UGT

unsigned greater than

@ ICMP_SGT

signed greater than

@ FCMP_ULT

1 1 0 0 True if unordered or less than

@ FCMP_ONE

0 1 1 0 True if ordered and operands are unequal

@ FCMP_UEQ

1 0 0 1 True if unordered or equal

@ ICMP_ULT

unsigned less than

@ FCMP_UGT

1 0 1 0 True if unordered or greater than

@ FCMP_OLE

0 1 0 1 True if ordered and less than or equal

@ FCMP_ORD

0 1 1 1 True if ordered (no nans)

@ ICMP_SGE

signed greater or equal

@ FCMP_UNE

1 1 1 0 True if unordered or not equal

@ ICMP_ULE

unsigned less or equal

@ FCMP_UGE

1 0 1 1 True if unordered, greater than, or equal

@ FCMP_FALSE

0 0 0 0 Always false (always folded)

@ FCMP_UNO

1 0 0 0 True if unordered: isnan(X) | isnan(Y)

Predicate getSwappedPredicate() const

For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.

bool isTrueWhenEqual() const

This is just a convenience.

static bool isFPPredicate(Predicate P)

Predicate getNonStrictPredicate() const

For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.

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

Determine if the predicate is an unordered operation.

static bool isIntPredicate(Predicate P)

static LLVM_ABI bool isOrdered(Predicate predicate)

Determine if the predicate is an ordered operation.

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

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

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

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

Return the absorbing element for the given binary operation, i.e.

static LLVM_ABI Constant * getNot(Constant *C)

static LLVM_ABI Constant * getInsertElement(Constant *Vec, Constant *Elt, Constant *Idx, Type *OnlyIfReducedTy=nullptr)

static LLVM_ABI 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 LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)

Return the identity constant for a binary opcode.

static LLVM_ABI std::optional< ConstantFPRange > makeExactFCmpRegion(FCmpInst::Predicate Pred, const APFloat &Other)

Produce the exact range such that all values in the returned range satisfy the given predicate with a...

ConstantFP - Floating Point Values [float, double].

const APFloat & getValueAPF() const

static LLVM_ABI Constant * getZero(Type *Ty, bool Negative=false)

static Constant * getNegativeZero(Type *Ty)

static LLVM_ABI Constant * getNaN(Type *Ty, bool Negative=false, uint64_t Payload=0)

This is the shared class of boolean and integer constants.

static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)

static ConstantInt * getSigned(IntegerType *Ty, int64_t V)

Return a ConstantInt with the specified value for the specified type.

static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)

uint64_t getZExtValue() const

Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...

static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)

static LLVM_ABI 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.

LLVM_ABI bool isFullSet() const

Return true if this set contains all of the elements possible for this data-type.

LLVM_ABI bool isEmptySet() const

Return true if this set contains no members.

static LLVM_ABI ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)

Produce the exact range such that all values in the returned range satisfy the given predicate with a...

LLVM_ABI ConstantRange inverse() const

Return a new range that is the logical not of the current set.

LLVM_ABI bool contains(const APInt &Val) const

Return true if the specified value is in the set.

static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)

static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)

Return a ConstantVector with the specified constant in each element.

static LLVM_ABI Constant * get(ArrayRef< Constant * > V)

This is an important base class in LLVM.

static LLVM_ABI Constant * getAllOnesValue(Type *Ty)

LLVM_ABI bool isAllOnesValue() const

Return true if this is the value that would be returned by getAllOnesValue.

LLVM_ABI bool isMaxSignedValue() const

Return true if the value is the largest signed value.

static LLVM_ABI Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

LLVM_ABI bool isNaN() const

Return true if this is a floating-point NaN constant or a vector floating-point constant with all NaN...

LLVM_ABI bool isMinSignedValue() const

Return true if the value is the smallest signed value.

LLVM_ABI Constant * getAggregateElement(unsigned Elt) const

For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...

LLVM_ABI bool isNullValue() const

Return true if this is the value that would be returned by getNullValue.

A parsed version of the target data layout string in and methods for querying it.

unsigned getAddressSizeInBits(unsigned AS) const

The size in bits of an address in for the given AS.

LLVM_ABI unsigned getIndexTypeSizeInBits(Type *Ty) const

The size in bits of the index used in GEP calculation for this type.

LLVM_ABI IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const

Returns the type of a GEP index in AddressSpace.

LLVM_ABI 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

The size in bits of indices used for address calculation in getelementptr and for addresses in the gi...

TypeSize getTypeSizeInBits(Type *Ty) const

Size examples:

Legacy analysis pass which computes a DominatorTree.

DominatorTree & getDomTree()

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

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

LLVM_ABI Value * getBasePtr() const

LLVM_ABI Value * getDerivedPtr() const

Represents flags for the getelementptr instruction/expression.

static LLVM_ABI 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 LLVM_ABI 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.

static bool isEquality(Predicate P)

Return true if this predicate is either EQ or NE.

bool isRelational() const

Return true if the predicate is relational (not EQ or NE).

Predicate getUnsignedPredicate() const

For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.

This instruction inserts a struct field of array element value into an aggregate value.

LLVM_ABI bool hasNoSignedZeros() const LLVM_READONLY

Determine whether the no-signed-zeros flag is set.

static bool isBitwiseLogicOp(unsigned Opcode)

Determine if the Opcode is and/or/xor.

LLVM_ABI bool isAssociative() const LLVM_READONLY

Return true if the instruction is associative:

LLVM_ABI bool isCommutative() const LLVM_READONLY

Return true if the instruction is commutative:

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

static ICmpInst::Predicate getPredicate(Intrinsic::ID ID)

Returns the comparison predicate underlying the intrinsic.

op_range incoming_values()

Value * getIncomingValueForBlock(const BasicBlock *BB) const

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

const Value * getFalseValue() const

const Value * getTrueValue() const

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.

static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

bool isIntOrIntVectorTy() const

Return true if this is an integer type or a vector of integer types.

LLVM_ABI unsigned getPointerAddressSpace() const

Get the address space of this pointer or pointer vector type.

Type * getScalarType() const

If this is a vector type, return the element type, otherwise return 'this'.

LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

Return the basic size of this type if it is a primitive type.

LLVMContext & getContext() const

Return the LLVMContext in which this type was uniqued.

LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY

If this is a vector type, return the getPrimitiveSizeInBits value for the element type.

static LLVM_ABI 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 * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const

This is a wrapper around stripAndAccumulateConstantOffsets with the in-bounds requirement set to fals...

LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const

Accumulate the constant offset this value has compared to a base pointer.

LLVM_ABI LLVMContext & getContext() const

All values hold a context through their type.

Base class of all SIMD vector types.

static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)

This static method is the primary way to construct an VectorType.

This class represents zero extension of integer types.

constexpr ScalarTy getFixedValue() const

constexpr bool isScalable() const

Returns whether the quantity is scaled by a runtime quantity (vscale).

constexpr bool isFixed() const

Returns true if the quantity is not scaled by vscale.

constexpr ScalarTy getKnownMinValue() const

Returns the minimum value this quantity can represent.

const ParentTy * getParent() const

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ C

The default llvm calling convention, compatible with C.

SpecificConstantMatch m_ZeroInt()

Convenience matchers for specific integer values.

BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)

Matches a register negated by a G_SUB.

BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)

Matches a register not-ed by a G_XOR.

cst_pred_ty< is_all_ones > m_AllOnes()

Match an integer or vector with all bits set.

cst_pred_ty< is_lowbit_mask > m_LowBitMask()

Match an integer or vector with only the low bit(s) set.

BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)

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)

auto m_PtrToIntOrAddr(const OpTy &Op)

Matches PtrToInt or PtrToAddr.

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.

ap_match< APInt > m_APInt(const APInt *&Res)

Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.

BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)

Matches an And with LHS and RHS in either order.

CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)

Matches Trunc.

BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)

ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)

Match APInt while allowing poison in splat vector constants.

specific_intval< false > m_SpecificInt(const APInt &V)

Match a specific integer value or vector with all elements equal to the value.

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.

ap_match< APFloat > m_APFloat(const APFloat *&Res)

Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...

ap_match< APFloat > m_APFloatAllowPoison(const APFloat *&Res)

Match APFloat while allowing poison in splat vector constants.

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.

IntrinsicID_match m_Intrinsic()

Match intrinsic calls like this: m_IntrinsicIntrinsic::fabs(m_Value(X))

ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)

Matches SelectInst.

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.

OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)

CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)

Matches ZExt.

OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWShl(const LHS &L, const RHS &R)

OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWMul(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)

MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)

match_immconstant_ty m_ImmConstant()

Match an arbitrary immediate Constant and ignore it.

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

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)

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)

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

MatchFunctor< Val, Pattern > match_fn(const Pattern &P)

A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.

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.

LLVM_ABI Intrinsic::ID getInverseMinMaxIntrinsic(Intrinsic::ID MinMaxID)

LLVM_ABI Value * simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)

Given operands for a AShr, fold the result or return nulll.

Definition InstructionSimplify.cpp:1505

unsigned Log2_32_Ceil(uint32_t Value)

Return the ceil log base 2 of the specified value, 32 if the value is zero.

LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)

Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

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

Definition InstructionSimplify.cpp:6044

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

Definition InstructionSimplify.cpp:5277

LLVM_ABI 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,...

LLVM_ABI bool canCreatePoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)

LLVM_ABI Constant * ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2)

Attempt to constant fold a select instruction with the specified operands.

LLVM_ABI Value * simplifyFreezeInst(Value *Op, const SimplifyQuery &Q)

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

Definition InstructionSimplify.cpp:7392

LLVM_ABI 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,...

LLVM_ABI bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS, bool &TrueIfSigned)

Given an exploded icmp instruction, return true if the comparison only checks the sign bit.

LLVM_ABI bool canConstantFoldCallTo(const CallBase *Call, const Function *F)

canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.

LLVM_ABI APInt getMinMaxLimit(SelectPatternFlavor SPF, unsigned BitWidth)

Return the minimum or maximum constant value for the specified integer min/max flavor and type.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

LLVM_ABI Value * simplifySDivInst(Value *LHS, Value *RHS, bool IsExact, const SimplifyQuery &Q)

Given operands for an SDiv, fold the result or return null.

Definition InstructionSimplify.cpp:1221

FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty

LLVM_ABI Value * simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q)

Given operand for a UnaryOperator, fold the result or return null.

Definition InstructionSimplify.cpp:6185

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

LLVM_ABI Value * simplifyMulInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for a Mul, fold the result or return null.

Definition InstructionSimplify.cpp:964

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

LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)

Like simplifyInstruction but the operands of I are replaced with NewOps.

Definition InstructionSimplify.cpp:7568

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

Given a callsite, callee, and arguments, fold the result or return null.

Definition InstructionSimplify.cpp:7347

LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)

Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.

bool canRoundingModeBe(RoundingMode RM, RoundingMode QRM)

Returns true if the rounding mode RM may be QRM at compile time or at run time.

LLVM_ABI bool isNoAliasCall(const Value *V)

Return true if this pointer is returned by a noalias function.

LLVM_ABI Value * simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q)

Given operands for an FCmpInst, fold the result or return null.

Definition InstructionSimplify.cpp:4340

LLVM_ABI Value * getSplatValue(const Value *V)

Get splat value if the input is a splat vector or return nullptr.

LLVM_ABI Constant * ConstantFoldGetElementPtr(Type *Ty, Constant *C, std::optional< ConstantRange > InRange, ArrayRef< Value * > Idxs)

LLVM_ABI CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF, bool Ordered=false)

Return the canonical comparison predicate for the specified minimum/maximum flavor.

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

Definition InstructionSimplify.cpp:5714

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

LLVM_ABI Value * simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an Or, fold the result or return null.

Definition InstructionSimplify.cpp:2525

LLVM_ABI Value * simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an Xor, fold the result or return null.

Definition InstructionSimplify.cpp:2610

LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)

Parse out a conservative ConstantRange from !range metadata.

LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, bool UseInstrInfo=true, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)

Determine the possible constant range of an integer or vector of integer value.

LLVM_ABI Constant * ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef< unsigned > Idxs)

Attempt to constant fold an extractvalue instruction with the specified operands and indices.

LLVM_ABI 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,...

LLVM_ABI bool MaskedValueIsZero(const Value *V, const APInt &Mask, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if 'V & Mask' is known to be zero.

LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)

Given operands for a CastInst, fold the result or return null.

Definition InstructionSimplify.cpp:5545

LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)

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

Definition InstructionSimplify.cpp:7576

unsigned M1(unsigned Val)

LLVM_ABI Value * simplifySubInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for a Sub, fold the result or return null.

Definition InstructionSimplify.cpp:892

LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for an Add, fold the result or return null.

Definition InstructionSimplify.cpp:661

LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)

ConstantFoldConstant - Fold the constant using the specified DataLayout.

auto dyn_cast_or_null(const Y &Val)

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.

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

LLVM_ABI bool isSplatValue(const Value *V, int Index=-1, unsigned Depth=0)

Return true if each element of the vector value V is poisoned or equal to every other non-poisoned el...

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

LLVM_ABI SelectPatternFlavor getInverseMinMaxFlavor(SelectPatternFlavor SPF)

Return the inverse minimum/maximum flavor of the specified flavor.

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

Definition InstructionSimplify.cpp:7652

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

LLVM_ABI Value * simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for a Shl, fold the result or return null.

Definition InstructionSimplify.cpp:1435

LLVM_ABI Value * simplifyFNegInst(Value *Op, FastMathFlags FMF, const SimplifyQuery &Q)

Given operand for an FNeg, fold the result or return null.

Definition InstructionSimplify.cpp:5742

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

Definition InstructionSimplify.cpp:6036

LLVM_ABI bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)

Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...

LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)

Return true if V is poison given that ValAssumedPoison is already poison.

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

Definition InstructionSimplify.cpp:6149

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

Definition InstructionSimplify.cpp:6028

FPClassTest

Floating-point class tests, supported by 'is_fpclass' intrinsic.

LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)

Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...

LLVM_ABI Value * simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, const SimplifyQuery &Q)

Given operands for a LShr, fold the result or return null.

Definition InstructionSimplify.cpp:1472

LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)

Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...

LLVM_ABI bool cannotBeNegativeZero(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if we can prove that the specified FP value is never equal to -0.0.

LLVM_ABI Value * simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an ICmpInst, fold the result or return null.

Definition InstructionSimplify.cpp:4104

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

LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)

Attempt to constant fold a cast with the specified operand.

LLVM_ABI Value * simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an And, fold the result or return null.

Definition InstructionSimplify.cpp:2251

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI bool intrinsicPropagatesPoison(Intrinsic::ID IID)

Return whether this intrinsic propagates poison for all operands.

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

Given operands for an ExtractValueInst, fold the result or return null.

Definition InstructionSimplify.cpp:5399

LLVM_ABI bool isNotCrossLaneOperation(const Instruction *I)

Return true if the instruction doesn't potentially cross vector lanes.

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

Given operands for an InsertValueInst, fold the result or return null.

Definition InstructionSimplify.cpp:5316

LLVM_ABI Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)

Attempt to constant fold a binary operation with the specified operands.

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

Definition InstructionSimplify.cpp:6111

LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)

Return true if the given value is known to be non-zero when defined.

constexpr int PoisonMaskElem

LLVM_ABI Value * simplifyLoadInst(LoadInst *LI, Value *PtrOp, const SimplifyQuery &Q)

Given a load instruction and its pointer operand, fold the result or return null.

Definition InstructionSimplify.cpp:7396

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

Definition InstructionSimplify.cpp:6052

LLVM_ABI SelectPatternResult matchDecomposedSelectPattern(CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, FastMathFlags FMF=FastMathFlags(), 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...

LLVM_ABI Value * simplifyConstrainedFPCall(CallBase *Call, const SimplifyQuery &Q)

Given a constrained FP intrinsic call, tries to compute its simplified version.

Definition InstructionSimplify.cpp:7373

LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for a BinaryOperator, fold the result or return null.

Definition InstructionSimplify.cpp:6264

std::optional< DecomposedBitTest > decomposeBitTest(Value *Cond, bool LookThroughTrunc=true, bool AllowNonZeroC=false, bool DecomposeAnd=false)

Decompose an icmp into the form ((X & Mask) pred C) if possible.

LLVM_ABI Value * findScalarElement(Value *V, unsigned EltNo)

Given a vector and an element number, see if the scalar value is already around as a register,...

LLVM_ABI bool isKnownNonEqual(const Value *V1, const Value *V2, const SimplifyQuery &SQ, unsigned Depth=0)

Return true if the given values are known to be non-equal when defined.

LLVM_ABI Value * simplifyUDivInst(Value *LHS, Value *RHS, bool IsExact, const SimplifyQuery &Q)

Given operands for a UDiv, fold the result or return null.

Definition InstructionSimplify.cpp:1233

DWARFExpression::Operation Op

LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)

PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...

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

Definition InstructionSimplify.cpp:6735

RoundingMode

Rounding mode.

@ NearestTiesToEven

roundTiesToEven.

@ TowardNegative

roundTowardNegative.

LLVM_ABI 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)

LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)

Return the number of times the sign bit of the register is replicated into the other bits.

LLVM_ABI Value * simplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx, const SimplifyQuery &Q)

Given operands for an InsertElement, fold the result or return null.

Definition InstructionSimplify.cpp:5322

constexpr unsigned BitWidth

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

Definition InstructionSimplify.cpp:4538

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

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

LLVM_ABI Value * simplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for an SRem, fold the result or return null.

Definition InstructionSimplify.cpp:1255

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

bool all_equal(std::initializer_list< T > Values)

Returns true if all Values in the initializer lists are equal or the list.

LLVM_ABI Constant * ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, ArrayRef< unsigned > Idxs)

Attempt to constant fold an insertvalue instruction with the specified operands and indices.

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

LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)

Return true if the given value is known to have exactly one bit set when defined.

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

LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for a CmpInst, fold the result or return null.

Definition InstructionSimplify.cpp:6282

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

LLVM_ABI Constant * ConstantFoldInstOperands(const 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.

LLVM_ABI bool isKnownNegation(const Value *X, const Value *Y, bool NeedNSW=false, bool AllowPoison=true)

Return true if the two given values are negation.

LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)

This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....

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

LLVM_ABI const SimplifyQuery getBestSimplifyQuery(Pass &, Function &)

Definition InstructionSimplify.cpp:7663

std::pair< Value *, FPClassTest > fcmpToClassTest(FCmpInst::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...

LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)

This method is similar to getUnderlyingObject except that it can look through phi and select instruct...

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.

LLVM_ABI Value * simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for a URem, fold the result or return null.

Definition InstructionSimplify.cpp:1266

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

Given operands for an ExtractElementInst, fold the result or return null.

Definition InstructionSimplify.cpp:5451

LLVM_ABI Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)

Given operands for a SelectInst, fold the result or return null.

Definition InstructionSimplify.cpp:5139

constexpr detail::IsaCheckPredicate< Types... > IsaPred

Function object wrapper for the llvm::isa type check.

LLVM_ABI std::optional< bool > isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsTrue=true, unsigned Depth=0)

Return true if RHS is known to be implied true by LHS.

LLVM_ABI std::optional< bool > computeKnownFPSignBit(const Value *V, const SimplifyQuery &SQ, unsigned Depth=0)

Return false if we can prove that the specified FP value's sign bit is 0.

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 Action captured(const Use *U, UseCaptureInfo CI)=0

Use U directly captures CI.UseCC and additionally CI.ResultCC through the return value of the user of...

virtual void tooManyUses()=0

tooManyUses - The depth of traversal has breached a limit.

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

@ Min

Evaluate all branches of an unknown condition.

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

LLVM_ABI bool isUndefValue(Value *V) const

If CanUseUndef is true, returns whether V is undef.

Definition InstructionSimplify.cpp:7689

const TargetLibraryInfo * TLI

SimplifyQuery getWithoutUndef() const

Capture information for a specific Use.