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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

102#include

103#include

104#include

105#include

106#include

107#include

108#include

109

110#define DEBUG_TYPE "instcombine"

112#include

113

114using namespace llvm;

116

118 "Number of instruction combining iterations performed");

119STATISTIC(NumOneIteration, "Number of functions with one iteration");

120STATISTIC(NumTwoIterations, "Number of functions with two iterations");

121STATISTIC(NumThreeIterations, "Number of functions with three iterations");

123 "Number of functions with four or more iterations");

124

125STATISTIC(NumCombined , "Number of insts combined");

126STATISTIC(NumConstProp, "Number of constant folds");

127STATISTIC(NumDeadInst , "Number of dead inst eliminated");

128STATISTIC(NumSunkInst , "Number of instructions sunk");

130STATISTIC(NumFactor , "Number of factorizations");

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

133 "Controls which instructions are visited");

134

136 cl::desc("Enable code sinking"),

138

140 "instcombine-max-sink-users", cl::init(32),

141 cl::desc("Maximum number of undroppable users for instruction sinking"));

142

145 cl::desc("Maximum array size considered when doing a combine"));

146

147namespace llvm {

149}

150

151

152

153

154

155

156

157

160

161std::optional<Instruction *>

163

164 if (II.getCalledFunction()->isTargetIntrinsic()) {

165 return TTIForTargetIntrinsicsOnly.instCombineIntrinsic(*this, II);

166 }

167 return std::nullopt;

168}

169

172 bool &KnownBitsComputed) {

173

174 if (II.getCalledFunction()->isTargetIntrinsic()) {

175 return TTIForTargetIntrinsicsOnly.simplifyDemandedUseBitsIntrinsic(

176 *this, II, DemandedMask, Known, KnownBitsComputed);

177 }

178 return std::nullopt;

179}

180

183 APInt &PoisonElts2, APInt &PoisonElts3,

185 SimplifyAndSetOp) {

186

187 if (II.getCalledFunction()->isTargetIntrinsic()) {

188 return TTIForTargetIntrinsicsOnly.simplifyDemandedVectorEltsIntrinsic(

189 *this, II, DemandedElts, PoisonElts, PoisonElts2, PoisonElts3,

190 SimplifyAndSetOp);

191 }

192 return std::nullopt;

193}

194

196

197

198

199 return TTIForTargetIntrinsicsOnly.isValidAddrSpaceCast(FromAS, ToAS);

200}

201

202Value *InstCombinerImpl::EmitGEPOffset(GEPOperator *GEP, bool RewriteGEP) {

203 if (!RewriteGEP)

205

208 if (Inst)

209 Builder.SetInsertPoint(Inst);

210

212

213 if (Inst && GEP->hasAllConstantIndices() &&

214 GEP->getSourceElementType()->isIntegerTy(8)) {

216 *Inst, Builder.CreateGEP(Builder.getInt8Ty(), GEP->getPointerOperand(),

217 Offset, "", GEP->getNoWrapFlags()));

219 }

221}

222

225 bool RewriteGEPs) {

227 if (Sum)

230 else

232 };

233

234 Value *Sum = nullptr;

235 Value *OneUseSum = nullptr;

236 Value *OneUseBase = nullptr;

238 for (GEPOperator *GEP : reverse(GEPs)) {

240 {

241

242

243 IRBuilderBase::InsertPointGuard Guard(Builder);

245 if (RewriteGEPs && Inst)

246 Builder.SetInsertPoint(Inst);

247

249 if (Offset->getType() != IdxTy)

252 if (GEP->hasOneUse()) {

253

254 OneUseSum = Add(OneUseSum, Offset);

256 if (!OneUseBase)

257 OneUseBase = GEP->getPointerOperand();

258 continue;

259 }

260

261 if (OneUseSum)

263

264

265

266 if (RewriteGEPs && Inst &&

267 !(GEP->getSourceElementType()->isIntegerTy(8) &&

270 *Inst,

272 OneUseBase ? OneUseBase : GEP->getPointerOperand(), Offset, "",

275 }

276 }

277

279 OneUseSum = OneUseBase = nullptr;

281 }

282 if (OneUseSum)

283 Sum = Add(Sum, OneUseSum);

284 if (!Sum)

286 return Sum;

287}

288

289

290

291

292

293

294bool InstCombinerImpl::isDesirableIntType(unsigned BitWidth) const {

296 case 8:

297 case 16:

298 case 32:

299 return true;

300 default:

302 }

303}

304

305

306

307

308

309

310

311

312

313bool InstCombinerImpl::shouldChangeType(unsigned FromWidth,

314 unsigned ToWidth) const {

315 bool FromLegal = FromWidth == 1 || DL.isLegalInteger(FromWidth);

316 bool ToLegal = ToWidth == 1 || DL.isLegalInteger(ToWidth);

317

318

319

320 if (ToWidth < FromWidth && isDesirableIntType(ToWidth))

321 return true;

322

323

324

325 if ((FromLegal || isDesirableIntType(FromWidth)) && !ToLegal)

326 return false;

327

328

329

330 if (!FromLegal && !ToLegal && ToWidth > FromWidth)

331 return false;

332

333 return true;

334}

335

336

337

338

339

340

341bool InstCombinerImpl::shouldChangeType(Type *From, Type *To) const {

342

343

345 return false;

346

349 return shouldChangeType(FromWidth, ToWidth);

350}

351

352

353

354

355

356

359 if (!OBO || !OBO->hasNoSignedWrap())

360 return false;

361

362 const APInt *BVal, *CVal;

364 return false;

365

366

367 bool Overflow = false;

368 switch (I.getOpcode()) {

369 case Instruction::Add:

370 (void)BVal->sadd_ov(*CVal, Overflow);

371 break;

372 case Instruction::Sub:

373 (void)BVal->ssub_ov(*CVal, Overflow);

374 break;

375 case Instruction::Mul:

376 (void)BVal->smul_ov(*CVal, Overflow);

377 break;

378 default:

379

380 return false;

381 }

382 return !Overflow;

383}

384

387 return OBO && OBO->hasNoUnsignedWrap();

388}

389

392 return OBO && OBO->hasNoSignedWrap();

393}

394

395

396

397

400 if (!FPMO) {

401 I.clearSubclassOptionalData();

402 return;

403 }

404

406 I.clearSubclassOptionalData();

407 I.setFastMathFlags(FMF);

408}

409

410

411

412

413

417 if (!Cast || !Cast->hasOneUse())

418 return false;

419

420

421 auto CastOpcode = Cast->getOpcode();

422 if (CastOpcode != Instruction::ZExt)

423 return false;

424

425

427 return false;

428

429 auto AssocOpcode = BinOp1->getOpcode();

431 if (!BinOp2 || !BinOp2->hasOneUse() || BinOp2->getOpcode() != AssocOpcode)

432 return false;

433

437 return false;

438

439

440

441

442

443

444

448 if (!CastC2)

449 return false;

451 if (!FoldedC)

452 return false;

453

457 Cast->dropPoisonGeneratingFlags();

458 return true;

459}

460

461

462

463Value *InstCombinerImpl::simplifyIntToPtrRoundTripCast(Value *Val) {

465 if (IntToPtr && DL.getTypeSizeInBits(IntToPtr->getDestTy()) ==

466 DL.getTypeSizeInBits(IntToPtr->getSrcTy())) {

468 Type *CastTy = IntToPtr->getDestTy();

469 if (PtrToInt &&

471 PtrToInt->getSrcTy()->getPointerAddressSpace() &&

472 DL.getTypeSizeInBits(PtrToInt->getSrcTy()) ==

473 DL.getTypeSizeInBits(PtrToInt->getDestTy()))

474 return PtrToInt->getOperand(0);

475 }

476 return nullptr;

477}

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

494

495

496

497

498

502

503 do {

504

505

506

507 if (I.isCommutative() && getComplexity(I.getOperand(0)) <

510

511 if (I.isCommutative()) {

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

516 }

517 }

518

521

522 if (I.isAssociative()) {

523

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

527 Value *C = I.getOperand(1);

528

529

531

536

537

538

539

541

542

543

544 if (IsNUW)

545 I.setHasNoUnsignedWrap(true);

546

547 if (IsNSW)

548 I.setHasNoSignedWrap(true);

549

551 ++NumReassoc;

552 continue;

553 }

554 }

555

556

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

558 Value *A = I.getOperand(0);

561

562

564

567

568

571 ++NumReassoc;

572 continue;

573 }

574 }

575 }

576

577 if (I.isAssociative() && I.isCommutative()) {

580 ++NumReassoc;

581 continue;

582 }

583

584

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

588 Value *C = I.getOperand(1);

589

590

592

595

596

599 ++NumReassoc;

600 continue;

601 }

602 }

603

604

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

606 Value *A = I.getOperand(0);

609

610

612

615

616

619 ++NumReassoc;

620 continue;

621 }

622 }

623

624

625

628 if (Op0 && Op1 &&

636 BinaryOperator *NewBO = (IsNUW && Opcode == Instruction::Add) ?

639

645 }

650

651

653 if (IsNUW)

654 I.setHasNoUnsignedWrap(true);

655

657 continue;

658 }

659 }

660

661

663 } while (true);

664}

665

666

667

670

671

672 if (LOp == Instruction::And)

673 return ROp == Instruction::Or || ROp == Instruction::Xor;

674

675

676 if (LOp == Instruction::Or)

677 return ROp == Instruction::And;

678

679

680

681 if (LOp == Instruction::Mul)

682 return ROp == Instruction::Add || ROp == Instruction::Sub;

683

684 return false;

685}

686

687

688

693

694

696

697

698

699

700}

701

702

703

706 return nullptr;

707

709}

710

711

712

713

714

715

719 assert(Op && "Expected a binary operator");

720 LHS = Op->getOperand(0);

721 RHS = Op->getOperand(1);

722 if (TopOpcode == Instruction::Add || TopOpcode == Instruction::Sub) {

725

727 Instruction::Shl, ConstantInt::get(Op->getType(), 1), C);

728 assert(RHS && "Constant folding of immediate constants failed");

729 return Instruction::Mul;

730 }

731

732 }

734 if (OtherOp && OtherOp->getOpcode() == Instruction::AShr &&

736

737 return Instruction::AShr;

738 }

739 }

740 return Op->getOpcode();

741}

742

743

744

749 assert(A && B && C && D && "All values must be provided");

750

751 Value *V = nullptr;

752 Value *RetVal = nullptr;

753 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);

755

756

758

759

761

762

763 if (A == C || (InnerCommutative && A == D)) {

764 if (A != C)

766

767

769

770

771

772 if (!V && (LHS->hasOneUse() || RHS->hasOneUse()))

773 V = Builder.CreateBinOp(TopLevelOpcode, B, D, RHS->getName());

774 if (V)

775 RetVal = Builder.CreateBinOp(InnerOpcode, A, V);

776 }

777 }

778

779

781

782

783 if (B == D || (InnerCommutative && B == C)) {

784 if (B != D)

786

787

789

790

791

792 if (!V && (LHS->hasOneUse() || RHS->hasOneUse()))

793 V = Builder.CreateBinOp(TopLevelOpcode, A, C, LHS->getName());

794 if (V)

795 RetVal = Builder.CreateBinOp(InnerOpcode, V, B);

796 }

797 }

798

799 if (!RetVal)

800 return nullptr;

801

802 ++NumFactor;

804

805

807 bool HasNSW = false;

808 bool HasNUW = false;

810 HasNSW = I.hasNoSignedWrap();

811 HasNUW = I.hasNoUnsignedWrap();

812 }

814 HasNSW &= LOBO->hasNoSignedWrap();

815 HasNUW &= LOBO->hasNoUnsignedWrap();

816 }

817

819 HasNSW &= ROBO->hasNoSignedWrap();

820 HasNUW &= ROBO->hasNoUnsignedWrap();

821 }

822

823 if (TopLevelOpcode == Instruction::Add && InnerOpcode == Instruction::Mul) {

824

825

826

827

828

829

830

831 const APInt *CInt;

834

835

837 }

838 }

839 return RetVal;

840}

841

842

843

844

845

846

847

848

849

851 unsigned Opc = I->getOpcode();

852 unsigned ConstIdx = 1;

853 switch (Opc) {

854 default:

855 return nullptr;

856

857

858

859 case Instruction::Sub:

860 ConstIdx = 0;

861 break;

862 case Instruction::ICmp:

863

864

865

867 return nullptr;

868 break;

869 case Instruction::Or:

871 return nullptr;

872 [[fallthrough]];

873 case Instruction::Add:

874 break;

875 }

876

878

879 if (match(I->getOperand(1 - ConstIdx),

881 return nullptr;

882

884

886 return nullptr;

887

888 Type *Ty = Op->getType();

889 Constant *BitWidthC = ConstantInt::get(Ty, Ty->getScalarSizeInBits());

890

891

895 if (!Cmp || !Cmp->isZeroValue())

896 return nullptr;

897 }

898

899

900 bool Consumes = false;

902 return nullptr;

904 assert(NotOp != nullptr &&

905 "Desync between isFreeToInvert and getFreelyInverted");

906

907 Value *CtpopOfNotOp = Builder.CreateIntrinsic(Ty, Intrinsic::ctpop, NotOp);

908

909 Value *R = nullptr;

910

911

912

913 switch (Opc) {

914 case Instruction::Sub:

916 break;

917 case Instruction::Or:

918 case Instruction::Add:

920 break;

921 case Instruction::ICmp:

924 break;

925 default:

927 }

928 assert(R != nullptr);

930}

931

932

933

934

935

936

937

938

939

940

941

942

943

944

945

946

947

948

949

950

951

952

953

954

957 auto IsValidBinOpc = [](unsigned Opc) {

958 switch (Opc) {

959 default:

960 return false;

961 case Instruction::And:

962 case Instruction::Or:

963 case Instruction::Xor:

964 case Instruction::Add:

965

966

967 return true;

968 }

969 };

970

971

972

973 auto IsCompletelyDistributable = [](unsigned BinOpc1, unsigned BinOpc2,

974 unsigned ShOpc) {

975 assert(ShOpc != Instruction::AShr);

976 return (BinOpc1 != Instruction::Add && BinOpc2 != Instruction::Add) ||

977 ShOpc == Instruction::Shl;

978 };

979

980 auto GetInvShift = [](unsigned ShOpc) {

981 assert(ShOpc != Instruction::AShr);

982 return ShOpc == Instruction::LShr ? Instruction::Shl : Instruction::LShr;

983 };

984

985 auto CanDistributeBinops = [&](unsigned BinOpc1, unsigned BinOpc2,

986 unsigned ShOpc, Constant *CMask,

988

989 if (BinOpc1 == Instruction::And)

990 return true;

991

992

993

994 if (!IsCompletelyDistributable(BinOpc1, BinOpc2, ShOpc))

995 return false;

996

997

998

999

1000 if (BinOpc2 == Instruction::And)

1001 return true;

1002

1003

1004

1008 CMask;

1009 };

1010

1011 auto MatchBinOp = [&](unsigned ShOpnum) -> Instruction * {

1013 Value *X, *Y, *ShiftedX, *Mask, *Shift;

1014 if (match(I.getOperand(ShOpnum),

1016 return nullptr;

1017 if (match(I.getOperand(1 - ShOpnum),

1022 return nullptr;

1023

1026 if (!IY || !IX)

1027 return nullptr;

1028

1029

1030 unsigned ShOpc = IY->getOpcode();

1031 if (ShOpc != IX->getOpcode())

1032 return nullptr;

1033

1034

1036 if (!BO2)

1037 return nullptr;

1038

1039 unsigned BinOpc = BO2->getOpcode();

1040

1041 if (!IsValidBinOpc(I.getOpcode()) || !IsValidBinOpc(BinOpc))

1042 return nullptr;

1043

1044 if (ShOpc == Instruction::AShr) {

1046 BinOpc == Instruction::Xor && match(Mask, m_AllOnes())) {

1048 Value *NewBinOp = Builder.CreateBinOp(I.getOpcode(), Y, NotX);

1051 }

1052

1053 return nullptr;

1054 }

1055

1056

1057

1058 if (BinOpc == I.getOpcode() &&

1059 IsCompletelyDistributable(I.getOpcode(), BinOpc, ShOpc)) {

1060 Value *NewBinOp2 = Builder.CreateBinOp(I.getOpcode(), X, Y);

1064 }

1065

1066

1067

1069 return nullptr;

1071 return nullptr;

1072

1073

1074 if (!CanDistributeBinops(I.getOpcode(), BinOpc, ShOpc, CMask, CShift))

1075 return nullptr;

1076

1081 Value *NewBinOp1 = Builder.CreateBinOp(I.getOpcode(), Y, NewBinOp2);

1083 NewBinOp1, CShift);

1084 };

1085

1087 return R;

1088 return MatchBinOp(1);

1089}

1090

1091

1092

1093

1094

1095

1096

1097

1098

1099

1102

1103

1105 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);

1106 Value *A, *CondVal, *TrueVal, *FalseVal;

1108

1109 auto MatchSelectAndCast = [&](Value *CastOp, Value *SelectOp) {

1111 A->getType()->getScalarSizeInBits() == 1 &&

1114 };

1115

1116

1117

1118 if (MatchSelectAndCast(LHS, RHS))

1119 CastOp = LHS;

1120 else if (MatchSelectAndCast(RHS, LHS))

1121 CastOp = RHS;

1122 else

1123 return nullptr;

1124

1125 auto NewFoldedConst = [&](bool IsTrueArm, Value *V) {

1126 bool IsCastOpRHS = (CastOp == RHS);

1129

1130 if (IsTrueArm) {

1132 } else if (IsZExt) {

1133 unsigned BitWidth = V->getType()->getScalarSizeInBits();

1135 } else {

1137 }

1138

1139 return IsCastOpRHS ? Builder.CreateBinOp(Opc, V, C)

1141 };

1142

1143

1144

1145 if (CondVal == A) {

1146 Value *NewTrueVal = NewFoldedConst(false, TrueVal);

1148 NewFoldedConst(true, FalseVal));

1149 }

1150

1152 Value *NewTrueVal = NewFoldedConst(true, TrueVal);

1154 NewFoldedConst(false, FalseVal));

1155 }

1156

1157 return nullptr;

1158}

1159

1161 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);

1167

1168 if (Op0)

1170 if (Op1)

1172

1173

1174

1175 if (Op0 && Op1 && LHSOpcode == RHSOpcode)

1177 return V;

1178

1179

1180

1181 if (Op0)

1185 return V;

1186

1187

1188

1189 if (Op1)

1193 return V;

1194

1195 return nullptr;

1196}

1197

1198

1199

1200

1201

1202

1204 Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);

1208

1209

1211 return R;

1212

1213

1215

1216

1219

1220

1221 auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();

1224

1225

1226 if (L && R) {

1227

1228 ++NumExpand;

1229 C = Builder.CreateBinOp(InnerOpcode, L, R);

1230 C->takeName(&I);

1231 return C;

1232 }

1233

1234

1236

1237 ++NumExpand;

1238 C = Builder.CreateBinOp(TopLevelOpcode, B, C);

1239 C->takeName(&I);

1240 return C;

1241 }

1242

1243

1245

1246 ++NumExpand;

1247 C = Builder.CreateBinOp(TopLevelOpcode, A, C);

1248 C->takeName(&I);

1249 return C;

1250 }

1251 }

1252

1254

1255

1258

1259

1260 auto SQDistributive = SQ.getWithInstruction(&I).getWithoutUndef();

1263

1264

1265 if (L && R) {

1266

1267 ++NumExpand;

1268 A = Builder.CreateBinOp(InnerOpcode, L, R);

1269 A->takeName(&I);

1270 return A;

1271 }

1272

1273

1275

1276 ++NumExpand;

1277 A = Builder.CreateBinOp(TopLevelOpcode, A, C);

1278 A->takeName(&I);

1279 return A;

1280 }

1281

1282

1284

1285 ++NumExpand;

1286 A = Builder.CreateBinOp(TopLevelOpcode, A, B);

1287 A->takeName(&I);

1288 return A;

1289 }

1290 }

1291

1293}

1294

1295static std::optional<std::pair<Value *, Value *>>

1297 if (LHS->getParent() != RHS->getParent())

1298 return std::nullopt;

1299

1300 if (LHS->getNumIncomingValues() < 2)

1301 return std::nullopt;

1302

1303 if (equal(LHS->blocks(), RHS->blocks()))

1304 return std::nullopt;

1305

1306 Value *L0 = LHS->getIncomingValue(0);

1307 Value *R0 = RHS->getIncomingValue(0);

1308

1309 for (unsigned I = 1, E = LHS->getNumIncomingValues(); I != E; ++I) {

1310 Value *L1 = LHS->getIncomingValue(I);

1311 Value *R1 = RHS->getIncomingValue(I);

1312

1313 if ((L0 == L1 && R0 == R1) || (L0 == R1 && R0 == L1))

1314 continue;

1315

1316 return std::nullopt;

1317 }

1318

1319 return std::optional(std::pair(L0, R0));

1320}

1321

1322std::optional<std::pair<Value *, Value *>>

1323InstCombinerImpl::matchSymmetricPair(Value *LHS, Value *RHS) {

1326 if (!LHSInst || !RHSInst || LHSInst->getOpcode() != RHSInst->getOpcode())

1327 return std::nullopt;

1329 case Instruction::PHI:

1331 case Instruction::Select: {

1337 return std::pair(TrueVal, FalseVal);

1338 return std::nullopt;

1339 }

1340 case Instruction::Call: {

1341

1344 if (LHSMinMax && RHSMinMax &&

1347 ((LHSMinMax->getLHS() == RHSMinMax->getLHS() &&

1348 LHSMinMax->getRHS() == RHSMinMax->getRHS()) ||

1349 (LHSMinMax->getLHS() == RHSMinMax->getRHS() &&

1350 LHSMinMax->getRHS() == RHSMinMax->getLHS())))

1351 return std::pair(LHSMinMax->getLHS(), LHSMinMax->getRHS());

1352 return std::nullopt;

1353 }

1354 default:

1355 return std::nullopt;

1356 }

1357}

1358

1365 if (!LHSIsSelect && !RHSIsSelect)

1366 return nullptr;

1367

1369 ? nullptr

1371

1375 FMF = I.getFastMathFlags();

1376 Builder.setFastMathFlags(FMF);

1377 }

1378

1381

1382 Value *Cond, *True = nullptr, *False = nullptr;

1383

1384

1385

1386

1387

1389

1390 if (Opcode != Instruction::Add || (!True && !False) || (True && False))

1391 return nullptr;

1396 }

1400 }

1401 return nullptr;

1402 };

1403

1404 if (LHSIsSelect && RHSIsSelect && A == D) {

1405

1409

1410 if (LHS->hasOneUse() && RHS->hasOneUse()) {

1411 if (False && !True)

1412 True = Builder.CreateBinOp(Opcode, B, E);

1413 else if (True && !False)

1414 False = Builder.CreateBinOp(Opcode, C, F);

1415 }

1416 } else if (LHSIsSelect && LHS->hasOneUse()) {

1417

1421 if (Value *NewSel = foldAddNegate(B, C, RHS))

1422 return NewSel;

1423 } else if (RHSIsSelect && RHS->hasOneUse()) {

1424

1428 if (Value *NewSel = foldAddNegate(E, F, LHS))

1429 return NewSel;

1430 }

1431

1432 if (!True || !False)

1433 return nullptr;

1434

1435 Value *NewSI = Builder.CreateSelect(Cond, True, False, I.getName(), SI);

1437 return NewSI;

1438}

1439

1440

1441

1445 if (U == IgnoredUser)

1446 continue;

1448 case Instruction::Select: {

1450 SI->swapValues();

1451 SI->swapProfMetadata();

1452 break;

1453 }

1454 case Instruction::Br: {

1457 if (BPI)

1458 BPI->swapSuccEdgesProbabilities(BI->getParent());

1459 break;

1460 }

1461 case Instruction::Xor:

1463

1465 break;

1466 default:

1468 "canFreelyInvertAllUsersOf() ?");

1469 }

1470 }

1471

1472

1475

1478 for (unsigned Idx = 0, End = DbgVal->getNumVariableLocationOps();

1479 Idx != End; ++Idx)

1480 if (DbgVal->getVariableLocationOp(Idx) == I)

1481 DbgVal->setExpression(

1483 }

1484}

1485

1486

1487

1488Value *InstCombinerImpl::dyn_castNegVal(Value *V) const {

1491 return NegV;

1492

1493

1496

1498 if (C->getType()->getElementType()->isIntegerTy())

1500

1502 for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {

1504 if (!Elt)

1505 return nullptr;

1506

1508 continue;

1509

1511 return nullptr;

1512 }

1514 }

1515

1516

1518 if (CV->getType()->isVectorTy() &&

1519 CV->getType()->getScalarType()->isIntegerTy() && CV->getSplatValue())

1521

1522 return nullptr;

1523}

1524

1525

1526

1527

1528

1529

1530

1531

1532Instruction *InstCombinerImpl::foldFBinOpOfIntCastsFromSign(

1533 BinaryOperator &BO, bool OpsFromSigned, std::array<Value *, 2> IntOps,

1535

1537 Type *IntTy = IntOps[0]->getType();

1538

1540

1541

1542 unsigned MaxRepresentableBits =

1544

1545

1546

1547 unsigned NumUsedLeadingBits[2] = {IntSz, IntSz};

1548

1549

1550

1551 auto IsNonZero = [&](unsigned OpNo) -> bool {

1552 if (OpsKnown[OpNo].hasKnownBits() &&

1553 OpsKnown[OpNo].getKnownBits(SQ).isNonZero())

1554 return true;

1556 };

1557

1558 auto IsNonNeg = [&](unsigned OpNo) -> bool {

1559

1560

1561

1562 return OpsKnown[OpNo].getKnownBits(SQ).isNonNegative();

1563 };

1564

1565

1566 auto IsValidPromotion = [&](unsigned OpNo) -> bool {

1567

1569 !IsNonNeg(OpNo))

1570 return false;

1571

1572

1573

1574

1575

1576

1577 if (MaxRepresentableBits < IntSz) {

1578

1579

1580

1581

1582 if (OpsFromSigned)

1583 NumUsedLeadingBits[OpNo] = IntSz - ComputeNumSignBits(IntOps[OpNo]);

1584

1585

1586 else {

1587 NumUsedLeadingBits[OpNo] =

1588 IntSz - OpsKnown[OpNo].getKnownBits(SQ).countMinLeadingZeros();

1589 }

1590 }

1591

1592

1593

1594

1595

1596 if (MaxRepresentableBits < NumUsedLeadingBits[OpNo])

1597 return false;

1598

1599 return !OpsFromSigned || BO.getOpcode() != Instruction::FMul ||

1600 IsNonZero(OpNo);

1601 };

1602

1603

1604 if (Op1FpC != nullptr) {

1605

1606 if (OpsFromSigned && BO.getOpcode() == Instruction::FMul &&

1608 return nullptr;

1609

1611 OpsFromSigned ? Instruction::FPToSI : Instruction::FPToUI, Op1FpC,

1612 IntTy, DL);

1613 if (Op1IntC == nullptr)

1614 return nullptr;

1616 : Instruction::UIToFP,

1617 Op1IntC, FPTy, DL) != Op1FpC)

1618 return nullptr;

1619

1620

1621 IntOps[1] = Op1IntC;

1622 }

1623

1624

1625 if (IntTy != IntOps[1]->getType())

1626 return nullptr;

1627

1628 if (Op1FpC == nullptr) {

1629 if (!IsValidPromotion(1))

1630 return nullptr;

1631 }

1632 if (!IsValidPromotion(0))

1633 return nullptr;

1634

1635

1637

1638 bool NeedsOverflowCheck = true;

1639

1640

1641 unsigned OverflowMaxOutputBits = OpsFromSigned ? 2 : 1;

1642 unsigned OverflowMaxCurBits =

1643 std::max(NumUsedLeadingBits[0], NumUsedLeadingBits[1]);

1644 bool OutputSigned = OpsFromSigned;

1646 case Instruction::FAdd:

1647 IntOpc = Instruction::Add;

1648 OverflowMaxOutputBits += OverflowMaxCurBits;

1649 break;

1650 case Instruction::FSub:

1651 IntOpc = Instruction::Sub;

1652 OverflowMaxOutputBits += OverflowMaxCurBits;

1653 break;

1654 case Instruction::FMul:

1655 IntOpc = Instruction::Mul;

1656 OverflowMaxOutputBits += OverflowMaxCurBits * 2;

1657 break;

1658 default:

1660 }

1661

1662 if (OverflowMaxOutputBits < IntSz) {

1663 NeedsOverflowCheck = false;

1664

1665

1666 if (IntOpc == Instruction::Sub)

1667 OutputSigned = true;

1668 }

1669

1670

1671

1672

1673 if (NeedsOverflowCheck &&

1674 !willNotOverflow(IntOpc, IntOps[0], IntOps[1], BO, OutputSigned))

1675 return nullptr;

1676

1677 Value *IntBinOp = Builder.CreateBinOp(IntOpc, IntOps[0], IntOps[1]);

1679 IntBO->setHasNoSignedWrap(OutputSigned);

1680 IntBO->setHasNoUnsignedWrap(!OutputSigned);

1681 }

1682 if (OutputSigned)

1683 return new SIToFPInst(IntBinOp, FPTy);

1684 return new UIToFPInst(IntBinOp, FPTy);

1685}

1686

1687

1688

1689

1690

1691

1693

1694

1696 return nullptr;

1697

1698 std::array<Value *, 2> IntOps = {nullptr, nullptr};

1700

1701

1702

1705 return nullptr;

1706

1710 return nullptr;

1711

1712

1714

1715

1716

1717

1718 if (Instruction *R = foldFBinOpOfIntCastsFromSign(BO, false,

1719 IntOps, Op1FpC, OpsKnown))

1720 return R;

1721 return foldFBinOpOfIntCastsFromSign(BO, true, IntOps,

1722 Op1FpC, OpsKnown);

1723}

1724

1725

1726

1727

1729

1730

1731

1737 X->getType()->isIntOrIntVectorTy(1))

1738 return nullptr;

1739

1740

1745 return createSelectInstWithUnknownProfile(X, TVal, FVal);

1746}

1747

1749 bool IsTrueArm) {

1751 for (Value *Op : I.operands()) {

1752 Value *V = nullptr;

1753 if (Op == SI) {

1754 V = IsTrueArm ? SI->getTrueValue() : SI->getFalseValue();

1755 } else if (match(SI->getCondition(),

1760

1762 V = IsTrueArm ? ConstantInt::get(Op->getType(), 1)

1764 } else {

1765 V = Op;

1766 }

1767 Ops.push_back(V);

1768 }

1769

1771}

1772

1781

1783 bool FoldWithMultiUse,

1784 bool SimplifyBothArms) {

1785

1786 if (SI->hasOneUse() && !FoldWithMultiUse)

1787 return nullptr;

1788

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

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

1791

1792

1793 if (SI->getType()->isIntOrIntVectorTy(1))

1794 return nullptr;

1795

1796

1797

1799 for (Value *IntrinOp : Op.operands())

1801 for (Value *PhiOp : PN->operands())

1802 if (PhiOp == &Op)

1803 return nullptr;

1804

1805

1806

1807

1808

1809

1810

1811

1813 if (CI->hasOneUse()) {

1814 Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1);

1815 if (((TV == Op0 && FV == Op1) || (FV == Op0 && TV == Op1)) &&

1816 !CI->isCommutative())

1817 return nullptr;

1818 }

1819 }

1820

1821

1825 if (!NewTV && !NewFV)

1826 return nullptr;

1827

1828 if (SimplifyBothArms && !(NewTV && NewFV))

1829 return nullptr;

1830

1831

1832 if (!NewTV)

1834 if (!NewFV)

1837}

1838

1843

1844

1846 for (Value *Op : I.operands()) {

1847 if (Op == PN)

1848 Ops.push_back(InValue);

1849 else

1850 Ops.push_back(Op->DoPHITranslation(PN->getParent(), InBB));

1851 }

1852

1853

1854

1855

1856

1860 return NewVal;

1861

1862

1863

1866 if (TerminatorBI && TerminatorBI->isConditional() &&

1871 DL, LHSIsTrue);

1872 if (ImpliedCond)

1874 }

1875

1876 return nullptr;

1877}

1878

1880 bool AllowMultipleUses) {

1882 if (NumPHIValues == 0)

1883 return nullptr;

1884

1885

1886

1887

1889 bool IdenticalUsers = false;

1890 if (!AllowMultipleUses && !OneUse) {

1891

1894 if (UI != &I && I.isIdenticalTo(UI))

1895 return nullptr;

1896 }

1897

1898 IdenticalUsers = true;

1899 }

1900

1901

1902 for (Value *Op : I.operands()) {

1903 if (Op == PN)

1904 continue;

1905

1906

1908 if (I)

1909 continue;

1910

1911

1913 if (I->getParent() == PN->getParent())

1914 continue;

1915

1916

1918 continue;

1919

1920

1921 return nullptr;

1922 }

1923

1924

1925

1928 bool SeenNonSimplifiedInVal = false;

1929 for (unsigned i = 0; i != NumPHIValues; ++i) {

1932

1935 continue;

1936 }

1937

1938

1939

1940 auto WillFold = [&]() {

1942 return false;

1943

1944

1945 const APInt *Ignored;

1948 return true;

1949

1950

1952 cast(InVal)->getSrcTy()->isIntOrIntVectorTy(1) &&

1955 return true;

1956

1957 return false;

1958 };

1959

1960 if (WillFold()) {

1961 OpsToMoveUseToIncomingBB.push_back(i);

1962 NewPhiValues.push_back(nullptr);

1963 continue;

1964 }

1965

1966 if (!OneUse && !IdenticalUsers)

1967 return nullptr;

1968

1969 if (SeenNonSimplifiedInVal)

1970 return nullptr;

1971 SeenNonSimplifiedInVal = true;

1972

1973

1974

1975

1976

1977

1979 if (!BI || !BI->isUnconditional() || DT.isReachableFromEntry(InBB))

1980 return nullptr;

1981

1982 NewPhiValues.push_back(nullptr);

1983 OpsToMoveUseToIncomingBB.push_back(i);

1984

1985

1986

1987

1989 return nullptr;

1990 }

1991

1992

1993

1995 for (auto OpIndex : OpsToMoveUseToIncomingBB) {

1998

2000 if (!Clone) {

2001 Clone = I.clone();

2003 if (U == PN)

2004 U = Op;

2005 else

2006 U = U->DoPHITranslation(PN->getParent(), OpBB);

2007 }

2009 Clones.insert({OpBB, Clone});

2010

2012 }

2013

2014 NewPhiValues[OpIndex] = Clone;

2015 }

2016

2017

2022

2023 for (unsigned i = 0; i != NumPHIValues; ++i)

2025

2026 if (IdenticalUsers) {

2027

2032 continue;

2034 }

2038 }

2039 OneUse = true;

2040 }

2041

2042 if (OneUse) {

2044 }

2046}

2047

2050 return nullptr;

2051

2052

2056 if (!BO0 || !BO1 || !BO0->hasNUses(2) || !BO1->hasNUses(2) ||

2057 BO0->getOpcode() != Opc || BO1->getOpcode() != Opc ||

2058 !BO0->isAssociative() || !BO1->isAssociative() ||

2059 BO0->getParent() != BO1->getParent())

2060 return nullptr;

2061

2062 assert(BO.isCommutative() && BO0->isCommutative() && BO1->isCommutative() &&

2063 "Expected commutative instructions!");

2064

2065

2067 Value *Start0, *Step0, *Start1, *Step1;

2071 return nullptr;

2072

2074 "Expected PHIs with two incoming values!");

2075

2076

2081 if (!Init0 || !Init1 || !C0 || !C1)

2082 return nullptr;

2083

2084

2087 if (Init || C)

2088 return nullptr;

2089

2090

2092 "reduced.phi");

2093

2094

2096 if (Opc == Instruction::FAdd || Opc == Instruction::FMul) {

2097

2098 FastMathFlags Intersect = BO0->getFastMathFlags() &

2100 NewBO->setFastMathFlags(Intersect);

2101 } else {

2104 Flags.AllKnownNonZero = false;

2105 Flags.mergeFlags(*BO0);

2106 Flags.mergeFlags(*BO1);

2107 Flags.mergeFlags(BO);

2108 Flags.applyFlags(*NewBO);

2109 }

2110 NewBO->takeName(&BO);

2111

2115 if (V == Init0) {

2120 "Invalid incoming block!");

2121 NewPN->addIncoming(Init, BB);

2122 } else if (V == BO0) {

2127 "Invalid incoming block!");

2128 NewPN->addIncoming(NewBO, BB);

2129 } else

2131 }

2132

2133 LLVM_DEBUG(dbgs() << " Combined " << *PN0 << "\n " << *BO0

2134 << "\n with " << *PN1 << "\n " << *BO1

2135 << '\n');

2136

2137

2140

2147

2149}

2150

2152

2154 return NewBO;

2155

2156

2157

2158

2161 if (!Phi0 || !Phi1 || !Phi0->hasOneUse() || !Phi1->hasOneUse() ||

2162 Phi0->getNumOperands() != Phi1->getNumOperands())

2163 return nullptr;

2164

2165

2166 if (BO.getParent() != Phi0->getParent() ||

2167 BO.getParent() != Phi1->getParent())

2168 return nullptr;

2169

2170

2171

2172

2173

2174

2175

2176

2177

2178

2180 false);

2181 if (C) {

2183 auto CanFoldIncomingValuePair = [&](std::tuple<Use &, Use &> T) {

2184 auto &Phi0Use = std::get<0>(T);

2185 auto &Phi1Use = std::get<1>(T);

2186 if (Phi0->getIncomingBlock(Phi0Use) != Phi1->getIncomingBlock(Phi1Use))

2187 return false;

2188 Value *Phi0UseV = Phi0Use.get();

2189 Value *Phi1UseV = Phi1Use.get();

2190 if (Phi0UseV == C)

2191 NewIncomingValues.push_back(Phi1UseV);

2192 else if (Phi1UseV == C)

2193 NewIncomingValues.push_back(Phi0UseV);

2194 else

2195 return false;

2196 return true;

2197 };

2198

2199 if (all_of(zip(Phi0->operands(), Phi1->operands()),

2200 CanFoldIncomingValuePair)) {

2202 PHINode::Create(Phi0->getType(), Phi0->getNumOperands());

2203 assert(NewIncomingValues.size() == Phi0->getNumOperands() &&

2204 "The number of collected incoming values should equal the number "

2205 "of the original PHINode operands!");

2206 for (unsigned I = 0; I < Phi0->getNumOperands(); I++)

2207 NewPhi->addIncoming(NewIncomingValues[I], Phi0->getIncomingBlock(I));

2208 return NewPhi;

2209 }

2210 }

2211

2212 if (Phi0->getNumOperands() != 2 || Phi1->getNumOperands() != 2)

2213 return nullptr;

2214

2215

2219 ConstBB = Phi0->getIncomingBlock(0);

2220 OtherBB = Phi0->getIncomingBlock(1);

2222 ConstBB = Phi0->getIncomingBlock(1);

2223 OtherBB = Phi0->getIncomingBlock(0);

2224 } else {

2225 return nullptr;

2226 }

2227 if (match(Phi1->getIncomingValueForBlock(ConstBB), m_ImmConstant(C1)))

2228 return nullptr;

2229

2230

2231

2232

2234 if (!PredBlockBranch || PredBlockBranch->isConditional() ||

2235 DT.isReachableFromEntry(OtherBB))

2236 return nullptr;

2237

2238

2239

2240

2241 for (auto BBIter = BO.getParent()->begin(); &*BBIter != &BO; ++BBIter)

2243 return nullptr;

2244

2245

2247 if (!NewC)

2248 return nullptr;

2249

2250

2251

2252 Builder.SetInsertPoint(PredBlockBranch);

2254 Phi0->getIncomingValueForBlock(OtherBB),

2255 Phi1->getIncomingValueForBlock(OtherBB));

2257 NotFoldedNewBO->copyIRFlags(&BO);

2258

2259

2263 return NewPhi;

2264}

2265

2267 bool IsOtherParamConst = isa(I.getOperand(1));

2268

2272 return NewSel;

2275 return NewPhi;

2276 }

2277 return nullptr;

2278}

2279

2281

2282

2283

2284 if (GEP.hasAllZeroIndices() && !Src.hasAllZeroIndices() &&

2285 !Src.hasOneUse())

2286 return false;

2287 return true;

2288}

2289

2290

2291

2292

2293

2294

2295

2301 return nullptr;

2303 }

2304

2307 return nullptr;

2308

2313 for (unsigned I = 0; I < NumElts; ++I) {

2314 Constant *CElt = C->getAggregateElement(I);

2315 if (ShMask[I] >= 0) {

2316 assert(ShMask[I] < (int)NumElts && "Not expecting narrowing shuffle");

2317 Constant *NewCElt = NewVecC[ShMask[I]];

2318

2319

2320

2321

2322

2323

2324 if (!CElt || (isa<PoisonValue>(NewCElt) && NewCElt != CElt) ||

2325 I >= NewCNumElts)

2326 return nullptr;

2327 NewVecC[ShMask[I]] = CElt;

2328 }

2329 }

2331}

2332

2333

2340 if (!SplatLHS)

2343}

2344

2347 return nullptr;

2348

2355

2356 auto foldConstantsThroughSubVectorInsertSplat =

2357 [&](Value *MaybeSubVector, Value *MaybeSplat,

2362 match(MaybeSubVector,

2365 return nullptr;

2366 SubVector =

2369 if (!SubVector || !Dest)

2370 return nullptr;

2371 auto *InsertVector =

2372 Builder.CreateInsertVector(Dest->getType(), Dest, SubVector, Idx);

2374 };

2375

2376

2377

2378

2379

2380 if (Instruction *Folded = foldConstantsThroughSubVectorInsertSplat(

2381 LHS, RHS, false))

2382 return Folded;

2383 if (Instruction *Folded = foldConstantsThroughSubVectorInsertSplat(

2384 RHS, LHS, true))

2385 return Folded;

2386

2387

2388

2389

2390 Value *L0, *L1, *R0, *R1;

2394 LHS->hasOneUse() && RHS->hasOneUse() &&

2397

2398

2399

2400

2401

2402 Value *NewBO0 = Builder.CreateBinOp(Opcode, L0, R0);

2405 Value *NewBO1 = Builder.CreateBinOp(Opcode, L1, R1);

2409 }

2410

2411 auto createBinOpReverse = [&](Value *X, Value *Y) {

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

2419 };

2420

2421

2422

2423

2426

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

2429 (LHS == RHS && LHS->hasNUses(2))))

2430 return createBinOpReverse(V1, V2);

2431

2432

2434 return createBinOpReverse(V1, RHS);

2435 }

2436

2438 return createBinOpReverse(LHS, V2);

2439

2440 auto createBinOpVPReverse = [&](Value *X, Value *Y, Value *EVL) {

2444

2449 M, Intrinsic::experimental_vp_reverse, V->getType());

2451 };

2452

2456

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

2460 (LHS == RHS && LHS->hasNUses(2))))

2461 return createBinOpVPReverse(V1, V2, EVL);

2462

2463

2465 return createBinOpVPReverse(V1, RHS, EVL);

2466 }

2467

2471 return createBinOpVPReverse(LHS, V2, EVL);

2472

2473

2474

2475

2477 return nullptr;

2478

2484 };

2485

2486

2487

2491 (LHS->hasOneUse() || RHS->hasOneUse() || LHS == RHS)) {

2492

2493 return createBinOpShuffle(V1, V2, Mask);

2494 }

2495

2496

2497

2504

2505

2506

2507

2508 if (LShuf->isSelect() &&

2510 RShuf->isSelect() &&

2512

2513

2514

2515

2518 return NewBO;

2519 }

2520 }

2521

2522

2523

2524

2525

2526

2532 "Shuffle should not change scalar type");

2533

2537

2538

2541

2542

2543

2544 Value *NewLHS = ConstOp1 ? V1 : NewC;

2545 Value *NewRHS = ConstOp1 ? NewC : V1;

2546 return createBinOpShuffle(NewLHS, NewRHS, Mask);

2547 }

2548 }

2549

2550

2552

2555

2558 int SplatIndex;

2563 X->getType() != Inst.getType() ||

2565 return nullptr;

2566

2567

2568

2569

2573 return nullptr;

2574 }

2575

2576

2577

2578

2581 Value *NewSplat = Builder.CreateShuffleVector(NewBO, NewMask);

2583

2584

2585

2587 R->copyFastMathFlags(&Inst);

2588 R->andIRFlags(RHS);

2589 }

2591 NewInstBO->copyIRFlags(R);

2592 return R;

2593 }

2594

2595 return nullptr;

2596}

2597

2598

2599

2600

2602

2604

2605

2606

2607 if (BO.getOpcode() == Instruction::Sub)

2609

2613 return nullptr;

2614

2615

2616

2617 CastInst::CastOps CastOpc = IsSext ? Instruction::SExt : Instruction::ZExt;

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

2622

2623

2626 return nullptr;

2628 if (!NarrowC)

2629 return nullptr;

2630 Y = NarrowC;

2631 }

2632

2633

2634 if (BO.getOpcode() == Instruction::Sub)

2636

2637

2638

2640 return nullptr;

2641

2642

2643

2644 Value *NarrowBO = Builder.CreateBinOp(BO.getOpcode(), X, Y, "narrow");

2646 if (IsSext)

2647 NewBinOp->setHasNoSignedWrap();

2648 else

2649 NewBinOp->setHasNoUnsignedWrap();

2650 }

2652}

2653

2654

2655

2660

2661

2662

2665 if (GEP.hasAllConstantIndices())

2666 return nullptr;

2667

2674 return nullptr;

2675

2676

2677

2678

2681 Type *Ty = GEP.getSourceElementType();

2682 Value *NewTrueC = Builder.CreateGEP(Ty, TrueC, IndexC, "", NW);

2683 Value *NewFalseC = Builder.CreateGEP(Ty, FalseC, IndexC, "", NW);

2685}

2686

2687

2688

2689

2693 if (GEP.getNumIndices() != 1)

2694 return nullptr;

2697 const APInt *C1;

2699 return nullptr;

2700 Value *VarIndex;

2701 const APInt *C2;

2703 unsigned IndexSizeInBits = DL.getIndexTypeSizeInBits(PtrTy);

2705 return nullptr;

2706 if (C1->getBitWidth() != IndexSizeInBits ||

2708 return nullptr;

2711 return nullptr;

2714 if (NewOffset.isZero() ||

2715 (Src->hasOneUse() && GEP.getOperand(1)->hasOneUse())) {

2717 if (GEP.hasNoUnsignedWrap() &&

2723 }

2724

2725 Value *GEPConst =

2728 }

2729

2730 return nullptr;

2731}

2732

2733

2734

2737 if (GEP.hasAllConstantIndices())

2738 return nullptr;

2739

2743 while (true) {

2744 if (!InnerGEP)

2745 return nullptr;

2746

2748 if (InnerGEP->hasAllConstantIndices())

2749 break;

2750

2751 if (!InnerGEP->hasOneUse())

2752 return nullptr;

2753

2754 Skipped.push_back(InnerGEP);

2756 }

2757

2758

2759

2760 if (Skipped.empty())

2761 return nullptr;

2762

2763

2764

2765 if (!InnerGEP->hasOneUse())

2766 return nullptr;

2767

2768

2769 Type *Ty = GEP.getType();

2770 if (InnerGEP->getType() != Ty)

2771 return nullptr;

2772

2775 if (GEP.accumulateConstantOffset(DL, Offset) ||

2776 !InnerGEP->accumulateConstantOffset(DL, Offset))

2777 return nullptr;

2778

2779 IC.replaceOperand(*Skipped.back(), 0, InnerGEP->getPointerOperand());

2781 SkippedGEP->setNoWrapFlags(NW);

2782

2787}

2788

2791

2792

2793

2795 return nullptr;

2796

2798 return I;

2799

2801 return I;

2802

2803 if (Src->getResultElementType() != GEP.getSourceElementType())

2804 return nullptr;

2805

2806

2807 bool EndsWithSequential = false;

2809 I != E; ++I)

2810 EndsWithSequential = I.isSequential();

2811 if (!EndsWithSequential)

2812 return nullptr;

2813

2814

2815

2816 Value *SO1 = Src->getOperand(Src->getNumOperands() - 1);

2817 Value *GO1 = GEP.getOperand(1);

2818

2819

2820

2821

2822

2824 return nullptr;

2825

2828

2829

2830 if (Sum == nullptr)

2831 return nullptr;

2832

2834 Indices.append(Src->op_begin() + 1, Src->op_end() - 1);

2836 Indices.append(GEP.op_begin() + 2, GEP.op_end());

2837

2838

2839 unsigned NumNonZeroIndices = count_if(Indices, [](Value *Idx) {

2841 return C || C->isNullValue();

2842 });

2843 if (NumNonZeroIndices > 1)

2844 return nullptr;

2845

2848 Src->getSourceElementType(), Src->getOperand(0), Indices, "",

2850}

2851

2854 bool &DoesConsume, unsigned Depth) {

2855 static Value *const NonNull = reinterpret_cast<Value *>(uintptr_t(1));

2856

2859 DoesConsume = true;

2860 return A;

2861 }

2862

2864

2867

2869 return nullptr;

2870

2871

2872

2873 if (!WillInvertAllUses)

2874 return nullptr;

2875

2876

2877

2880 return Builder->CreateCmp(I->getInversePredicate(), I->getOperand(0),

2881 I->getOperand(1));

2882 return NonNull;

2883 }

2884

2885

2886

2889 DoesConsume, Depth))

2892 DoesConsume, Depth))

2894 return nullptr;

2895 }

2896

2897

2898

2901 DoesConsume, Depth))

2904 DoesConsume, Depth))

2906 return nullptr;

2907 }

2908

2909

2910

2913 DoesConsume, Depth))

2915 return nullptr;

2916 }

2917

2918

2919

2922 DoesConsume, Depth))

2924 return nullptr;

2925 }

2926

2928

2929

2932

2934 bool LocalDoesConsume = DoesConsume;

2936 LocalDoesConsume, Depth))

2937 return nullptr;

2939 LocalDoesConsume, Depth)) {

2940 DoesConsume = LocalDoesConsume;

2941 if (Builder != nullptr) {

2943 DoesConsume, Depth);

2944 assert(NotB != nullptr &&

2945 "Unable to build inverted value for known freely invertable op");

2947 return Builder->CreateBinaryIntrinsic(

2949 return Builder->CreateSelect(Cond, NotA, NotB);

2950 }

2951 return NonNull;

2952 }

2953 }

2954

2956 bool LocalDoesConsume = DoesConsume;

2958 for (Use &U : PN->operands()) {

2959 BasicBlock *IncomingBlock = PN->getIncomingBlock(U);

2961 U.get(), false,

2963 if (NewIncomingVal == nullptr)

2964 return nullptr;

2965

2966 if (NewIncomingVal == V)

2967 return nullptr;

2969 IncomingValues.emplace_back(NewIncomingVal, IncomingBlock);

2970 }

2971

2972 DoesConsume = LocalDoesConsume;

2973 if (Builder != nullptr) {

2975 Builder->SetInsertPoint(PN);

2977 Builder->CreatePHI(PN->getType(), PN->getNumIncomingValues());

2978 for (auto [Val, Pred] : IncomingValues)

2980 return NewPN;

2981 }

2982 return NonNull;

2983 }

2984

2987 DoesConsume, Depth))

2988 return Builder ? Builder->CreateSExt(AV, V->getType()) : NonNull;

2989 return nullptr;

2990 }

2991

2994 DoesConsume, Depth))

2995 return Builder ? Builder->CreateTrunc(AV, V->getType()) : NonNull;

2996 return nullptr;

2997 }

2998

2999

3000

3001

3003 bool IsLogical, Value *A,

3005 bool LocalDoesConsume = DoesConsume;

3007 LocalDoesConsume, Depth))

3008 return nullptr;

3010 LocalDoesConsume, Depth)) {

3012 LocalDoesConsume, Depth);

3013 DoesConsume = LocalDoesConsume;

3014 if (IsLogical)

3015 return Builder ? Builder->CreateLogicalOp(Opcode, NotA, NotB) : NonNull;

3016 return Builder ? Builder->CreateBinOp(Opcode, NotA, NotB) : NonNull;

3017 }

3018

3019 return nullptr;

3020 };

3021

3023 return TryInvertAndOrUsingDeMorgan(Instruction::And, false, A,

3024 B);

3025

3027 return TryInvertAndOrUsingDeMorgan(Instruction::Or, false, A,

3028 B);

3029

3031 return TryInvertAndOrUsingDeMorgan(Instruction::And, true, A,

3032 B);

3033

3035 return TryInvertAndOrUsingDeMorgan(Instruction::Or, true, A,

3036 B);

3037

3038 return nullptr;

3039}

3040

3041

3043 Value *PtrOp = GEP.getOperand(0);

3044 Type *GEPEltType = GEP.getSourceElementType();

3046 return false;

3047

3048

3049

3051 return true;

3052

3053

3054

3055 if (GEP.getNumIndices() == 1 &&

3059 return true;

3060

3061

3062

3064 return PtrOpGep && PtrOpGep->hasAllConstantIndices() &&

3066 const APInt *C;

3067 return match(V, m_APInt(C)) && !C->isZero();

3068 });

3069}

3070

3074 if (!Op1)

3075 return nullptr;

3076

3077

3078

3079

3080

3081

3082

3083 if (Op1 == &GEP)

3084 return nullptr;

3086

3087 int DI = -1;

3088

3091 if (!Op2 || Op1->getNumOperands() != Op2->getNumOperands() ||

3092 Op1->getSourceElementType() != Op2->getSourceElementType())

3093 return nullptr;

3094

3095

3096 if (Op2 == &GEP)

3097 return nullptr;

3098

3099

3100 Type *CurTy = nullptr;

3101

3102 for (unsigned J = 0, F = Op1->getNumOperands(); J != F; ++J) {

3103 if (Op1->getOperand(J)->getType() != Op2->getOperand(J)->getType())

3104 return nullptr;

3105

3106 if (Op1->getOperand(J) != Op2->getOperand(J)) {

3107 if (DI == -1) {

3108

3109

3110

3111

3112

3113

3114 if (J > 1) {

3115 assert(CurTy && "No current type?");

3117 return nullptr;

3118 }

3119

3120 DI = J;

3121 } else {

3122

3123

3124

3125

3126

3127

3128 return nullptr;

3129 }

3130 }

3131

3132

3133 if (J > 0) {

3134 if (J == 1) {

3135 CurTy = Op1->getSourceElementType();

3136 } else {

3137 CurTy =

3139 }

3140 }

3141 }

3142

3143 NW &= Op2->getNoWrapFlags();

3144 }

3145

3146

3147

3148

3149 if (DI != -1 && !PN->hasOneUse())

3150 return nullptr;

3151

3153 NewGEP->setNoWrapFlags(NW);

3154

3155 if (DI == -1) {

3156

3157

3158 } else {

3159

3160

3161

3163 {

3165 Builder.SetInsertPoint(PN);

3166 NewPN = Builder.CreatePHI(Op1->getOperand(DI)->getType(),

3168 }

3169

3173

3174 NewGEP->setOperand(DI, NewPN);

3175 }

3176

3177 NewGEP->insertBefore(*GEP.getParent(), GEP.getParent()->getFirstInsertionPt());

3178 return NewGEP;

3179}

3180

3182 Value *PtrOp = GEP.getOperand(0);

3184 Type *GEPType = GEP.getType();

3185 Type *GEPEltType = GEP.getSourceElementType();

3188 SQ.getWithInstruction(&GEP)))

3190

3191

3192

3193

3195 auto VWidth = GEPFVTy->getNumElements();

3196 APInt PoisonElts(VWidth, 0);

3199 PoisonElts)) {

3200 if (V != &GEP)

3202 return &GEP;

3203 }

3204 }

3205

3206

3207

3208 bool MadeChange = false;

3209

3210

3211

3212 Type *NewScalarIndexTy =

3213 DL.getIndexType(GEP.getPointerOperandType()->getScalarType());

3214

3217 ++I, ++GTI) {

3218

3220 continue;

3221

3222 Type *IndexTy = (*I)->getType();

3223 Type *NewIndexType =

3227 : NewScalarIndexTy;

3228

3229

3230

3232 if (EltTy->isSized() && DL.getTypeAllocSize(EltTy).isZero())

3235 MadeChange = true;

3236 }

3237

3238 if (IndexTy != NewIndexType) {

3239

3240

3241

3244 if (GEP.hasNoUnsignedWrap() && GEP.hasNoUnsignedSignedWrap())

3245 *I = Builder.CreateZExt(*I, NewIndexType, "", true);

3246 else

3247 *I = Builder.CreateSExt(*I, NewIndexType);

3248 } else {

3249 *I = Builder.CreateTrunc(*I, NewIndexType, "", GEP.hasNoUnsignedWrap(),

3250 GEP.hasNoUnsignedSignedWrap());

3251 }

3252 MadeChange = true;

3253 }

3254 }

3255 if (MadeChange)

3256 return &GEP;

3257

3258

3259 if (!GEPEltType->isIntegerTy(8) && GEP.hasAllConstantIndices()) {

3260 APInt Offset(DL.getIndexTypeSizeInBits(GEPType), 0);

3261 if (GEP.accumulateConstantOffset(DL, Offset))

3264 GEP.getNoWrapFlags()));

3265 }

3266

3270 Builder.CreatePtrAdd(PtrOp, Offset, "", GEP.getNoWrapFlags());

3272 }

3273

3274

3276 if (LastIdx && LastIdx->isNullValue() && !LastIdx->getType()->isVectorTy()) {

3278 GEP, Builder.CreateGEP(GEP.getSourceElementType(), PtrOp,

3279 drop_end(Indices), "", GEP.getNoWrapFlags()));

3280 }

3281

3282

3284 if (FirstIdx && FirstIdx->isNullValue() &&

3285 !FirstIdx->getType()->isVectorTy()) {

3287 ++GTI;

3290 GEP.getPointerOperand(),

3292 GEP.getNoWrapFlags()));

3293 }

3294

3295

3296

3297

3299 return Op->getType()->isVectorTy() && getSplatValue(Op);

3300 })) {

3302 for (auto &Op : GEP.operands()) {

3303 if (Op->getType()->isVectorTy())

3306 continue;

3307 }

3309 }

3310

3311 Value *Res = Builder.CreateGEP(GEP.getSourceElementType(), NewOps[0],

3312 ArrayRef(NewOps).drop_front(), GEP.getName(),

3313 GEP.getNoWrapFlags());

3316 Res = Builder.CreateVectorSplat(EC, Res);

3317 }

3319 }

3320

3321 bool SeenNonZeroIndex = false;

3322 for (auto [IdxNum, Idx] : enumerate(Indices)) {

3324 if (C && C->isNullValue())

3325 continue;

3326

3327 if (!SeenNonZeroIndex) {

3328 SeenNonZeroIndex = true;

3329 continue;

3330 }

3331

3332

3334 Value *FrontGEP =

3335 Builder.CreateGEP(GEPEltType, PtrOp, FrontIndices,

3336 GEP.getName() + ".split", GEP.getNoWrapFlags());

3337

3343 BackIndices, GEP.getNoWrapFlags());

3344 }

3345

3346

3350 }

3351

3354 return I;

3355

3356 if (GEP.getNumIndices() == 1) {

3357 unsigned AS = GEP.getPointerAddressSpace();

3358 if (GEP.getOperand(1)->getType()->getScalarSizeInBits() ==

3359 DL.getIndexSizeInBits(AS)) {

3360 uint64_t TyAllocSize = DL.getTypeAllocSize(GEPEltType).getFixedValue();

3361

3362 if (TyAllocSize == 1) {

3363

3364

3365

3366

3367 Value *X = GEP.getPointerOperand();

3371 GEPType == Y->getType()) {

3372 bool HasNonAddressBits =

3373 DL.getAddressSizeInBits(AS) != DL.getPointerSizeInBits(AS);

3375 GEP.replaceUsesWithIf(Y, [&](Use &U) {

3376 bool ShouldReplace =

3379 Changed |= ShouldReplace;

3380 return ShouldReplace;

3381 });

3383 }

3384 } else if (auto *ExactIns =

3386

3388 if (ExactIns->isExact()) {

3396 GEP.getPointerOperand(), V,

3397 GEP.getNoWrapFlags());

3398 }

3399 }

3400 if (ExactIns->isExact() && ExactIns->hasOneUse()) {

3401

3402

3403

3404

3406 std::optional NewC;

3415 if (Rem == 0)

3416 NewC = Quot;

3419 int64_t Rem;

3421

3422 if (!Quot.isAllOnes() && Rem == 0)

3423 NewC = Quot;

3424 }

3425

3426 if (NewC.has_value()) {

3429 ConstantInt::get(V->getType(), *NewC));

3432 GEP.getPointerOperand(), NewOp,

3433 GEP.getNoWrapFlags());

3434 }

3435 }

3436 }

3437 }

3438 }

3439

3441 return nullptr;

3442

3443 if (GEP.isInBounds()) {

3444 unsigned IdxWidth =

3446 APInt BasePtrOffset(IdxWidth, 0);

3447 Value *UnderlyingPtrOp =

3449 bool CanBeNull, CanBeFreed;

3451 DL, CanBeNull, CanBeFreed);

3452 if (!CanBeNull && !CanBeFreed && DerefBytes != 0) {

3453 if (GEP.accumulateConstantOffset(DL, BasePtrOffset) &&

3455 APInt AllocSize(IdxWidth, DerefBytes);

3456 if (BasePtrOffset.ule(AllocSize)) {

3458 GEP.getSourceElementType(), PtrOp, Indices, GEP.getName());

3459 }

3460 }

3461 }

3462 }

3463

3464

3465 if (GEP.hasNoUnsignedSignedWrap() && GEP.hasNoUnsignedWrap() &&

3467 return isKnownNonNegative(Idx, SQ.getWithInstruction(&GEP));

3468 })) {

3470 return &GEP;

3471 }

3472

3473

3474

3475 if (GEP.getNumIndices() == 1) {

3476

3477

3478 auto GetPreservedNoWrapFlags = [&](bool AddIsNUW) {

3479

3480

3481 if (GEP.hasNoUnsignedWrap() && AddIsNUW)

3482 return GEP.getNoWrapFlags();

3484 };

3485

3486

3487 Value *Idx1, *Idx2;

3488 if (match(GEP.getOperand(1),

3490

3491

3492

3493

3494

3496 GEPNoWrapFlags NWFlags = GetPreservedNoWrapFlags(NUW);

3497 auto *NewPtr =

3498 Builder.CreateGEP(GEP.getSourceElementType(), GEP.getPointerOperand(),

3499 Idx1, "", NWFlags);

3501 Builder.CreateGEP(GEP.getSourceElementType(),

3502 NewPtr, Idx2, "", NWFlags));

3503 }

3507

3508

3509

3510

3511

3512

3513 bool NUW = match(GEP.getOperand(1),

3515 GEPNoWrapFlags NWFlags = GetPreservedNoWrapFlags(NUW);

3516 auto *NewPtr = Builder.CreateGEP(

3517 GEP.getSourceElementType(), GEP.getPointerOperand(),

3518 Builder.CreateSExt(Idx1, GEP.getOperand(1)->getType()), "", NWFlags);

3521 Builder.CreateGEP(GEP.getSourceElementType(), NewPtr,

3522 Builder.CreateSExt(C, GEP.getOperand(1)->getType()),

3523 "", NWFlags));

3524 }

3525 }

3526

3528 return R;

3529

3530 return nullptr;

3531}

3532

3536 return true;

3539

3541}

3542

3543

3544

3548

3549 return false;

3550

3552

3553 return false;

3554

3556 return false;

3557

3558

3559

3560

3562 return Dest && Dest->Ptr == UsedV;

3563}

3564

3565static std::optional

3572

3573 do {

3577 switch (I->getOpcode()) {

3578 default:

3579

3580 return std::nullopt;

3581

3582 case Instruction::AddrSpaceCast:

3583 case Instruction::BitCast:

3584 case Instruction::GetElementPtr:

3585 Users.emplace_back(I);

3587 continue;

3588

3589 case Instruction::ICmp: {

3591

3592

3593

3595 return std::nullopt;

3596 unsigned OtherIndex = (ICI->getOperand(0) == PI) ? 1 : 0;

3598 return std::nullopt;

3599

3600

3601

3602

3603 auto AlignmentAndSizeKnownValid = [](CallBase *CB) {

3604

3605

3606

3607 const APInt *Alignment;

3609 return match(CB->getArgOperand(0), m_APInt(Alignment)) &&

3611 Alignment->isPowerOf2() && Size->urem(*Alignment).isZero();

3612 };

3614 LibFunc TheLibFunc;

3615 if (CB && TLI.getLibFunc(*CB->getCalledFunction(), TheLibFunc) &&

3616 TLI.has(TheLibFunc) && TheLibFunc == LibFunc_aligned_alloc &&

3617 !AlignmentAndSizeKnownValid(CB))

3618 return std::nullopt;

3619 Users.emplace_back(I);

3620 continue;

3621 }

3622

3623 case Instruction::Call:

3624

3626 switch (II->getIntrinsicID()) {

3627 default:

3628 return std::nullopt;

3629

3630 case Intrinsic::memmove:

3631 case Intrinsic::memcpy:

3632 case Intrinsic::memset: {

3634 if (MI->isVolatile())

3635 return std::nullopt;

3636

3637

3641 return std::nullopt;

3642 Access |= NewAccess;

3643 [[fallthrough]];

3644 }

3645 case Intrinsic::assume:

3646 case Intrinsic::invariant_start:

3647 case Intrinsic::invariant_end:

3648 case Intrinsic::lifetime_start:

3649 case Intrinsic::lifetime_end:

3650 case Intrinsic::objectsize:

3651 Users.emplace_back(I);

3652 continue;

3653 case Intrinsic::launder_invariant_group:

3654 case Intrinsic::strip_invariant_group:

3655 Users.emplace_back(I);

3657 continue;

3658 }

3659 }

3660

3663 Users.emplace_back(I);

3664 continue;

3665 }

3666

3669 Users.emplace_back(I);

3671 continue;

3672 }

3673

3677 Users.emplace_back(I);

3678 continue;

3679 }

3680

3681 return std::nullopt;

3682

3683 case Instruction::Store: {

3685 if (SI->isVolatile() || SI->getPointerOperand() != PI)

3686 return std::nullopt;

3688 return std::nullopt;

3690 Users.emplace_back(I);

3691 continue;

3692 }

3693

3694 case Instruction::Load: {

3697 return std::nullopt;

3699 return std::nullopt;

3701 Users.emplace_back(I);

3702 continue;

3703 }

3704 }

3706 }

3707 } while (!Worklist.empty());

3708

3711}

3712

3715

3716

3717

3718

3719

3720

3721

3722

3723

3724

3725

3727

3728

3729

3731 std::unique_ptr DIB;

3734 DIB.reset(new DIBuilder(*MI.getModule(), false));

3735 }

3736

3737

3738

3739 bool KnowInitUndef = false;

3740 bool KnowInitZero = false;

3745 KnowInitUndef = true;

3746 else if (Init->isNullValue())

3747 KnowInitZero = true;

3748 }

3749

3750

3751 auto &F = *MI.getFunction();

3752 if (F.hasFnAttribute(Attribute::SanitizeMemory) ||

3753 F.hasFnAttribute(Attribute::SanitizeAddress))

3754 KnowInitUndef = false;

3755

3756 auto Removable =

3758 if (Removable) {

3760

3761

3763 continue;

3764

3766

3768 if (II->getIntrinsicID() == Intrinsic::objectsize) {

3771 II, DL, &TLI, AA, true, &InsertedInstructions);

3772 for (Instruction *Inserted : InsertedInstructions)

3776 User = nullptr;

3777 continue;

3778 }

3780 if (KnowInitZero && isRefSet(*Removable)) {

3782 Builder.SetInsertPoint(MTI);

3783 auto *M = Builder.CreateMemSet(

3784 MTI->getRawDest(),

3786 MTI->getLength(), MTI->getDestAlign());

3787 M->copyMetadata(*MTI);

3788 }

3789 }

3790 }

3791 }

3794 continue;

3795

3797

3801 C->isFalseWhenEqual()));

3803 for (auto *DVR : DVRs)

3804 if (DVR->isAddressOfVariable())

3806 } else {

3807

3808

3811 assert(KnowInitZero || KnowInitUndef);

3814 } else

3817 }

3819 }

3820

3822

3823 Module *M = II->getModule();

3826 F, II->getNormalDest(), II->getUnwindDest(), {}, "", II->getParent());

3827 NewII->setDebugLoc(II->getDebugLoc());

3828 }

3829

3830

3831

3832

3833

3834

3835

3836

3837

3838

3839

3840

3841

3842

3843

3844

3845

3846

3847

3848

3849

3850

3851

3852

3853

3854

3855 for (auto *DVR : DVRs)

3856 if (DVR->isAddressOfVariable() || DVR->getExpression()->startsWithDeref())

3857 DVR->eraseFromParent();

3858

3860 }

3861 return nullptr;

3862}

3863

3864

3865

3866

3867

3868

3869

3870

3871

3872

3873

3874

3875

3876

3877

3878

3884

3885

3886

3887

3888

3889 if (!PredBB)

3890 return nullptr;

3891

3892

3893

3897 return nullptr;

3898

3899

3900

3901

3902

3903 if (FreeInstrBB->size() != 2) {

3905 if (&Inst == &FI || &Inst == FreeInstrBBTerminator)

3906 continue;

3908 if (!Cast || !Cast->isNoopCast(DL))

3909 return nullptr;

3910 }

3911 }

3912

3920 TrueBB, FalseBB)))

3921 return nullptr;

3923 return nullptr;

3924

3925

3927 return nullptr;

3929 "Broken CFG: missing edge from predecessor to successor");

3930

3931

3932

3934 if (&Instr == FreeInstrBBTerminator)

3935 break;

3936 Instr.moveBeforePreserving(TI->getIterator());

3937 }

3939 "Only the branch instruction should remain");

3940

3941

3942

3943

3944

3945

3946

3947

3948

3950 Attrs = Attrs.removeParamAttribute(FI.getContext(), 0, Attribute::NonNull);

3951 Attribute Dereferenceable = Attrs.getParamAttr(0, Attribute::Dereferenceable);

3952 if (Dereferenceable.isValid()) {

3954 Attrs = Attrs.removeParamAttribute(FI.getContext(), 0,

3955 Attribute::Dereferenceable);

3956 Attrs = Attrs.addDereferenceableOrNullParamAttr(FI.getContext(), 0, Bytes);

3957 }

3959

3960 return &FI;

3961}

3962

3964

3966

3969 }

3970

3971

3972

3975

3976

3977

3982

3983

3984

3985

3986

3987

3988

3989

3990

3991

3992

3994 LibFunc Func;

3995 if (TLI.getLibFunc(FI, Func) && TLI.has(Func) && Func == LibFunc_free)

3997 return I;

3998 }

3999

4000 return nullptr;

4001}

4002

4005 if (!RetVal)

4006 return nullptr;

4007

4011 bool HasDereferenceable =

4012 F->getAttributes().getRetDereferenceableBytes() > 0;

4013 if (F->hasRetAttribute(Attribute::NonNull) ||

4014 (HasDereferenceable &&

4016 if (Value *V = simplifyNonNullOperand(RetVal, HasDereferenceable))

4018 }

4019 }

4020

4021 if (!AttributeFuncs::isNoFPClassCompatibleType(RetTy))

4022 return nullptr;

4023

4024 FPClassTest ReturnClass = F->getAttributes().getRetNoFPClass();

4025 if (ReturnClass == fcNone)

4026 return nullptr;

4027

4029 Value *Simplified =

4031 if (!Simplified)

4032 return nullptr;

4033

4035}

4036

4037

4039

4040

4041

4043 while (Instruction *Prev = I.getPrevNode()) {

4044

4045

4046

4047

4048 if (Prev->isEHPad())

4049 break;

4050

4052 break;

4053

4054

4055

4056

4057

4061 }

4063}

4064

4067 return nullptr;

4068}

4069

4072

4073

4074

4075

4076

4079 do {

4080 if (BBI != FirstInstr)

4081 --BBI;

4082 } while (BBI != FirstInstr && BBI->isDebugOrPseudoInst());

4083

4085 };

4086

4089 return &BI;

4090

4091 return nullptr;

4092}

4093

4096 if (DeadEdges.insert({From, To}).second)

4097 return;

4098

4099

4101 for (Use &U : PN.incoming_values())

4102 if (PN.getIncomingBlock(U) == From && isa<PoisonValue>(U)) {

4106 }

4107

4109}

4110

4111

4112

4118 std::next(I->getReverseIterator())))) {

4119 if (!Inst.use_empty() && !Inst.getType()->isTokenTy()) {

4122 }

4123 if (Inst.isEHPad() || Inst.getType()->isTokenTy())

4124 continue;

4125

4126 Inst.dropDbgRecords();

4129 }

4130

4136 }

4137

4138

4141}

4142

4148 return DeadEdges.contains({Pred, BB}) || DT.dominates(BB, Pred);

4149 }))

4150 continue;

4151

4153 }

4154}

4155

4160

4161 if (Succ == LiveSucc)

4162 continue;

4163

4165 }

4166

4168}

4169

4173

4174

4178

4180 if (BPI)

4181 BPI->swapSuccEdgesProbabilities(BI.getParent());

4183 }

4184

4185

4186

4187

4192 Value *NotX = Builder.CreateNot(X, "not." + X->getName());

4195 if (BPI)

4196 BPI->swapSuccEdgesProbabilities(BI.getParent());

4198 }

4199

4200

4201

4204

4205

4209

4213 if (BPI)

4214 BPI->swapSuccEdgesProbabilities(BI.getParent());

4216 return &BI;

4217 }

4218

4221 return nullptr;

4222 }

4226 return nullptr;

4227 }

4228

4229

4230

4231

4235 if (DT.dominates(Edge0, U)) {

4238 continue;

4239 }

4241 if (DT.dominates(Edge1, U)) {

4244 }

4245 }

4246 }

4247

4248 DC.registerBranch(&BI);

4249 return nullptr;

4250}

4251

4252

4253

4254

4257 bool IsTrueArm) {

4258 unsigned CstOpIdx = IsTrueArm ? 1 : 2;

4260 if (C)

4261 return nullptr;

4262

4263 BasicBlock *CstBB = SI.findCaseValue(C)->getCaseSuccessor();

4264 if (CstBB != SI.getDefaultDest())

4265 return nullptr;

4266 Value *X = Select->getOperand(3 - CstOpIdx);

4268 const APInt *RHSC;

4271 return nullptr;

4272 if (IsTrueArm)

4274

4275

4277 for (auto Case : SI.cases())

4278 if (!CR.contains(Case.getCaseValue()->getValue()))

4279 return nullptr;

4280

4281 return X;

4282}

4283

4289

4290 for (auto Case : SI.cases()) {

4293 "Result of expression should be constant");

4295 }

4297 }

4298

4301

4302 for (auto Case : SI.cases()) {

4305 "Result of expression should be constant");

4307 }

4309 }

4310

4314 all_of(SI.cases(), [&](const auto &Case) {

4315 return Case.getCaseValue()->getValue().countr_zero() >= ShiftAmt;

4316 })) {

4317

4321 Value *NewCond = Op0;

4323

4325 NewCond = Builder.CreateAnd(

4327 }

4328 for (auto Case : SI.cases()) {

4329 const APInt &CaseVal = Case.getCaseValue()->getValue();

4331 : CaseVal.lshr(ShiftAmt);

4332 Case.setValue(ConstantInt::get(SI.getContext(), ShiftedCase));

4333 }

4335 }

4336 }

4337

4338

4343

4344 if (all_of(SI.cases(), [&](const auto &Case) {

4345 const APInt &CaseVal = Case.getCaseValue()->getValue();

4346 return IsZExt ? CaseVal.isIntN(NewWidth)

4347 : CaseVal.isSignedIntN(NewWidth);

4348 })) {

4349 for (auto &Case : SI.cases()) {

4350 APInt TruncatedCase = Case.getCaseValue()->getValue().trunc(NewWidth);

4351 Case.setValue(ConstantInt::get(SI.getContext(), TruncatedCase));

4352 }

4354 }

4355 }

4356

4357

4365 }

4366

4370

4371

4372

4373 for (const auto &C : SI.cases()) {

4374 LeadingKnownZeros =

4375 std::min(LeadingKnownZeros, C.getCaseValue()->getValue().countl_zero());

4376 LeadingKnownOnes =

4377 std::min(LeadingKnownOnes, C.getCaseValue()->getValue().countl_one());

4378 }

4379

4380 unsigned NewWidth = Known.getBitWidth() - std::max(LeadingKnownZeros, LeadingKnownOnes);

4381

4382

4383

4384

4385

4386 if (NewWidth > 0 && NewWidth < Known.getBitWidth() &&

4387 shouldChangeType(Known.getBitWidth(), NewWidth)) {

4391

4392 for (auto Case : SI.cases()) {

4393 APInt TruncatedCase = Case.getCaseValue()->getValue().trunc(NewWidth);

4394 Case.setValue(ConstantInt::get(SI.getContext(), TruncatedCase));

4395 }

4397 }

4398

4401 return nullptr;

4402 }

4405 SI.findCaseValue(CI)->getCaseSuccessor());

4406 return nullptr;

4407 }

4408

4409 return nullptr;

4410}

4411

4413InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {

4415 if (!WO)

4416 return nullptr;

4417

4419 const APInt *C = nullptr;

4421 if (*EV.idx_begin() == 0 && (OvID == Intrinsic::smul_with_overflow ||

4422 OvID == Intrinsic::umul_with_overflow)) {

4423

4424 if (C->isAllOnes())

4426

4427 if (C->isPowerOf2()) {

4428 return BinaryOperator::CreateShl(

4429 WO->getLHS(),

4430 ConstantInt::get(WO->getLHS()->getType(), C->logBase2()));

4431 }

4432 }

4433 }

4434

4435

4436

4437

4438 if (!WO->hasOneUse())

4439 return nullptr;

4440

4441

4442

4445 Value *LHS = WO->getLHS(), *RHS = WO->getRHS();

4446

4450 }

4451

4452 assert(*EV.idx_begin() == 1 && "Unexpected extract index for overflow inst");

4453

4454

4455 if (OvID == Intrinsic::usub_with_overflow)

4456 return new ICmpInst(ICmpInst::ICMP_ULT, WO->getLHS(), WO->getRHS());

4457

4458

4459

4460 if (OvID == Intrinsic::smul_with_overflow &&

4461 WO->getLHS()->getType()->isIntOrIntVectorTy(1))

4462 return BinaryOperator::CreateAnd(WO->getLHS(), WO->getRHS());

4463

4464

4465 if (OvID == Intrinsic::umul_with_overflow && WO->getLHS() == WO->getRHS()) {

4466 unsigned BitWidth = WO->getLHS()->getType()->getScalarSizeInBits();

4467

4469 return new ICmpInst(

4471 ConstantInt::get(WO->getLHS()->getType(),

4473 }

4474

4475

4476

4477

4478 if (C) {

4479

4480

4482 WO->getBinaryOp(), *C, WO->getNoWrapKind());

4483

4485 APInt NewRHSC, Offset;

4487 auto *OpTy = WO->getRHS()->getType();

4488 auto *NewLHS = WO->getLHS();

4490 NewLHS = Builder.CreateAdd(NewLHS, ConstantInt::get(OpTy, Offset));

4492 ConstantInt::get(OpTy, NewRHSC));

4493 }

4494

4495 return nullptr;

4496}

4497

4501

4502

4504 return nullptr;

4508

4509 const APFloat *ConstVal = nullptr;

4510 Value *VarOp = nullptr;

4511 bool ConstIsTrue = false;

4512

4514 VarOp = FalseVal;

4515 ConstIsTrue = true;

4517 VarOp = TrueVal;

4518 ConstIsTrue = false;

4519 } else {

4520 return nullptr;

4521 }

4522

4523 Builder.SetInsertPoint(&EV);

4524

4526 Builder.CreateCall(FrexpCall->getCalledFunction(), {VarOp}, "frexp");

4528

4529 Value *NewEV = Builder.CreateExtractValue(NewFrexp, 0, "mantissa");

4530

4531 int Exp;

4533

4534 Constant *ConstantMantissa = ConstantFP::get(TrueVal->getType(), Mantissa);

4535

4536 Value *NewSel = Builder.CreateSelectFMF(

4537 Cond, ConstIsTrue ? ConstantMantissa : NewEV,

4538 ConstIsTrue ? NewEV : ConstantMantissa, SelectInst, "select.frexp");

4539 return NewSel;

4540}

4543

4546

4548 SQ.getWithInstruction(&EV)))

4550

4551 Value *Cond, *TrueVal, *FalseVal;

4554 auto *SelInst =

4556 if (Value *Result =

4559 }

4561

4562 const unsigned *exti, *exte, *insi, *inse;

4563 for (exti = EV.idx_begin(), insi = IV->idx_begin(),

4564 exte = EV.idx_end(), inse = IV->idx_end();

4565 exti != exte && insi != inse;

4566 ++exti, ++insi) {

4567 if (*insi != *exti)

4568

4569

4570

4571

4572

4573

4574

4575

4578 }

4579 if (exti == exte && insi == inse)

4580

4581

4582

4583

4585 if (exti == exte) {

4586

4587

4588

4589

4590

4591

4592

4593

4594 Value *NewEV = Builder.CreateExtractValue(IV->getAggregateOperand(),

4598 }

4599 if (insi == inse)

4600

4601

4602

4603

4604

4605

4606

4607

4610 }

4611

4612 if (Instruction *R = foldExtractOfOverflowIntrinsic(EV))

4613 return R;

4614

4616

4618 STy && STy->isScalableTy())

4619 return nullptr;

4620

4621

4622

4623

4624

4625

4626 if (L->isSimple() && L->hasOneUse()) {

4627

4629

4631 for (unsigned Idx : EV.indices())

4633

4634

4635

4636 Builder.SetInsertPoint(L);

4638 L->getPointerOperand(), Indices);

4640

4641

4643

4644

4646 }

4647 }

4648

4651 return Res;

4652

4653

4654

4657 return R;

4658

4659

4660

4661

4662

4663

4664

4665

4666

4667 return nullptr;

4668}

4669

4670

4672 switch (Personality) {

4676

4677

4678 return false;

4680 return false;

4682

4683

4684 return false;

4696 }

4698}

4699

4706

4708

4709

4710

4713

4714

4715

4716 bool MakeNewInstruction = false;

4718 bool CleanupFlag = LI.isCleanup();

4719

4721 for (unsigned i = 0, e = LI.getNumClauses(); i != e; ++i) {

4722 bool isLastClause = i + 1 == e;

4724

4727

4728

4729

4730 if (AlreadyCaught.insert(TypeInfo).second) {

4731

4732 NewClauses.push_back(CatchClause);

4733 } else {

4734

4735 MakeNewInstruction = true;

4736 }

4737

4738

4739

4740 if (isCatchAll(Personality, TypeInfo)) {

4741 if (!isLastClause)

4742 MakeNewInstruction = true;

4743 CleanupFlag = false;

4744 break;

4745 }

4746 } else {

4747

4748

4749

4750

4751

4752

4753

4754 assert(LI.isFilter(i) && "Unsupported landingpad clause!");

4757 unsigned NumTypeInfos = FilterType->getNumElements();

4758

4759

4760

4761

4762 if (!NumTypeInfos) {

4763 NewClauses.push_back(FilterClause);

4764 if (!isLastClause)

4765 MakeNewInstruction = true;

4766 CleanupFlag = false;

4767 break;

4768 }

4769

4770 bool MakeNewFilter = false;

4773

4774 assert(NumTypeInfos > 0 && "Should have handled empty filter already!");

4777

4778 if (isCatchAll(Personality, TypeInfo)) {

4779

4780 MakeNewInstruction = true;

4781 continue;

4782 }

4783

4784

4785

4786 NewFilterElts.push_back(TypeInfo);

4787 if (NumTypeInfos > 1)

4788 MakeNewFilter = true;

4789 } else {

4792 NewFilterElts.reserve(NumTypeInfos);

4793

4794

4795

4796

4797 bool SawCatchAll = false;

4798 for (unsigned j = 0; j != NumTypeInfos; ++j) {

4801 if (isCatchAll(Personality, TypeInfo)) {

4802

4803 SawCatchAll = true;

4804 break;

4805 }

4806

4807

4808

4809

4810

4811

4812

4813

4814

4815

4816

4817

4818

4819

4820

4821

4822

4823

4824

4825

4826 if (SeenInFilter.insert(TypeInfo).second)

4828 }

4829

4830 if (SawCatchAll) {

4831

4832 MakeNewInstruction = true;

4833 continue;

4834 }

4835

4836

4837 if (NewFilterElts.size() < NumTypeInfos)

4838 MakeNewFilter = true;

4839 }

4840 if (MakeNewFilter) {

4842 NewFilterElts.size());

4844 MakeNewInstruction = true;

4845 }

4846

4847 NewClauses.push_back(FilterClause);

4848

4849

4850

4851

4852

4853 if (MakeNewFilter && !NewFilterElts.size()) {

4854 assert(MakeNewInstruction && "New filter but not a new instruction!");

4855 CleanupFlag = false;

4856 break;

4857 }

4858 }

4859 }

4860

4861

4862

4863

4864

4865

4866 for (unsigned i = 0, e = NewClauses.size(); i + 1 < e; ) {

4867 unsigned j;

4868

4869 for (j = i; j != e; ++j)

4871 break;

4872

4873

4874

4875

4876 for (unsigned k = i; k + 1 < j; ++k)

4877 if (shorter_filter(NewClauses[k+1], NewClauses[k])) {

4878

4879

4880 std::stable_sort(NewClauses.begin() + i, NewClauses.begin() + j,

4882 MakeNewInstruction = true;

4883 break;

4884 }

4885

4886

4887 i = j + 1;

4888 }

4889

4890

4891

4892

4893

4894

4895

4896

4897

4898

4899

4900

4901 for (unsigned i = 0; i + 1 < NewClauses.size(); ++i) {

4902

4905 if (!FTy)

4906

4907 continue;

4909

4910

4911 for (unsigned j = NewClauses.size() - 1; j != i; --j) {

4912 Value *LFilter = NewClauses[j];

4914 if (!LTy)

4915

4916 continue;

4917

4918

4920

4921 if (!FElts) {

4922

4923 NewClauses.erase(J);

4924 MakeNewInstruction = true;

4925

4926 continue;

4927 }

4928 unsigned LElts = LTy->getNumElements();

4929

4930 if (FElts > LElts)

4931

4932 continue;

4933

4935

4936

4938 assert(FElts <= LElts && "Should have handled this case earlier!");

4939

4940 NewClauses.erase(J);

4941 MakeNewInstruction = true;

4942 }

4943

4944 continue;

4945 }

4948

4949

4950 assert(FElts > 0 && "Should have eliminated the empty filter earlier!");

4951 for (unsigned l = 0; l != LElts; ++l)

4952 if (LArray->getOperand(l)->isNullValue()) {

4953

4954 NewClauses.erase(J);

4955 MakeNewInstruction = true;

4956 break;

4957 }

4958

4959 continue;

4960 }

4961

4962

4963

4964

4966 bool AllFound = true;

4967 for (unsigned f = 0; f != FElts; ++f) {

4969 AllFound = false;

4970 for (unsigned l = 0; l != LElts; ++l) {

4972 if (LTypeInfo == FTypeInfo) {

4973 AllFound = true;

4974 break;

4975 }

4976 }

4977 if (!AllFound)

4978 break;

4979 }

4980 if (AllFound) {

4981

4982 NewClauses.erase(J);

4983 MakeNewInstruction = true;

4984 }

4985

4986 }

4987 }

4988

4989

4990

4991 if (MakeNewInstruction) {

4993 NewClauses.size());

4996

4997

4998

4999 if (NewClauses.empty())

5000 CleanupFlag = true;

5002 return NLI;

5003 }

5004

5005

5006

5007 if (LI.isCleanup() != CleanupFlag) {

5008 assert(!CleanupFlag && "Adding a cleanup, not removing one?!");

5010 return &LI;

5011 }

5012

5013 return nullptr;

5014}

5015

5018

5019

5020

5021

5022

5023

5024

5025

5026

5027

5028

5029

5030 auto CanPushFreeze = [](Value *V) {

5032 return false;

5033

5034

5035

5036

5037

5039 false);

5040 };

5041

5042

5043

5044

5048 Worklist.push_back(OrigUse);

5050 auto *U = Worklist.pop_back_val();

5051 Value *V = U->get();

5052 if (!CanPushFreeze(V)) {

5053

5054 if (U == OrigUse)

5055 return nullptr;

5056

5058 Builder.SetInsertPoint(UserI);

5059 Value *Frozen = Builder.CreateFreeze(V, V->getName() + ".fr");

5060 U->set(Frozen);

5061 continue;

5062 }

5063

5065 if (!Visited.insert(I).second)

5066 continue;

5067

5068

5072 continue;

5074 }

5075

5076 I->dropPoisonGeneratingAnnotations();

5077 this->Worklist.add(I);

5078 }

5079

5080 return OrigUse->get();

5081}

5082

5085

5086

5087

5088

5089

5090 Use *StartU = nullptr;

5094

5095 Worklist.push_back(U.get());

5096 continue;

5097 }

5098

5099

5100 if (StartU)

5101 return nullptr;

5102 StartU = &U;

5103 }

5104

5105 if (!StartU || Worklist.empty())

5106 return nullptr;

5107

5108 Value *StartV = StartU->get();

5111

5112

5113 if (StartNeedsFreeze && StartBB->getTerminator() == StartV)

5114 return nullptr;

5115

5120 if (!Visited.insert(V).second)

5121 continue;

5122

5123 if (Visited.size() > 32)

5124 return nullptr;

5125

5126

5128 continue;

5129

5132 false))

5133 return nullptr;

5134

5137 }

5138

5140 I->dropPoisonGeneratingAnnotations();

5141

5142 if (StartNeedsFreeze) {

5144 Value *FrozenStartV = Builder.CreateFreeze(StartV,

5145 StartV->getName() + ".fr");

5147 }

5149}

5150

5153

5155 return false;

5156

5157

5158

5159

5160

5161

5164 MoveBefore =

5166 } else {

5167 auto MoveBeforeOpt = cast(Op)->getInsertionPointAfterDef();

5168 if (!MoveBeforeOpt)

5169 return false;

5170 MoveBefore = *MoveBeforeOpt;

5171 }

5172

5173

5174 MoveBefore.setHeadBit(false);

5175

5177 if (&FI != &*MoveBefore) {

5178 FI.moveBefore(*MoveBefore->getParent(), MoveBefore);

5180 }

5181

5182 Op->replaceUsesWithIf(&FI, [&](Use &U) -> bool {

5183 bool Dominates = DT.dominates(&FI, U);

5185 return Dominates;

5186 });

5187

5189}

5190

5191

5193 for (auto *U : V->users()) {

5195 return true;

5197 return true;

5198 }

5199 return false;

5200}

5201

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

5204

5207

5208

5211 return NV;

5213 return NV;

5214 }

5215

5218

5219

5220

5221

5222

5223

5224

5225

5226

5227

5228

5229

5230

5231

5232

5233 auto getUndefReplacement = [&](Type *Ty) {

5234 auto pickCommonConstantFromPHI = [](PHINode &PN) -> Value * {

5235

5236

5237 Constant *BestValue = nullptr;

5238 for (Value *V : PN.incoming_values()) {

5240 continue;

5241

5243 if (C)

5244 return nullptr;

5245

5247 return nullptr;

5248

5249 if (BestValue && BestValue != C)

5250 return nullptr;

5251

5252 BestValue = C;

5253 }

5254 return BestValue;

5255 };

5256

5258 Value *BestValue = nullptr;

5259 for (auto *U : I.users()) {

5260 Value *V = NullValue;

5267 V = NullValue;

5269 if (Value *MaybeV = pickCommonConstantFromPHI(*PHI))

5270 V = MaybeV;

5271 }

5272

5273 if (!BestValue)

5274 BestValue = V;

5275 else if (BestValue != V)

5276 BestValue = NullValue;

5277 }

5278 assert(BestValue && "Must have at least one use");

5279 assert(BestValue != &I && "Cannot replace with itself");

5280 return BestValue;

5281 };

5282

5284

5285

5286

5288 return nullptr;

5290 }

5291

5292 auto getFreezeVectorReplacement = [](Constant *C) -> Constant * {

5293 Type *Ty = C->getType();

5295 if (!VTy)

5296 return nullptr;

5297 unsigned NumElts = VTy->getNumElements();

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

5300 Constant *EltC = C->getAggregateElement(i);

5302 BestValue = EltC;

5303 break;

5304 }

5305 }

5307 };

5308

5310 if (match(Op0, m_Constant(C)) && C->containsUndefOrPoisonElement() &&

5311 C->containsConstantExpression()) {

5312 if (Constant *Repl = getFreezeVectorReplacement(C))

5314 }

5315

5316

5318 return &I;

5319

5320 return nullptr;

5321}

5322

5323

5324

5325

5328 if (!CB)

5329

5330

5331

5332 return false;

5334 if (!Dest)

5335 return false;

5337 if (!AI)

5338

5339 return false;

5340

5341

5342

5345 auto pushUsers = [&](const Instruction &I) {

5346 for (const User *U : I.users()) {

5347 if (Visited.insert(U).second)

5349 }

5350 };

5351 pushUsers(*AI);

5352 while (!AllocaUsers.empty()) {

5355 pushUsers(*UserI);

5356 continue;

5357 }

5358 if (UserI == CB)

5359 continue;

5360

5361 return false;

5362 }

5363 return true;

5364}

5365

5366

5367

5368

5369

5373

5374

5375 if (isa(I) || I->isEHPad() || I->mayThrow() || I->willReturn() ||

5376 I->isTerminator())

5377 return false;

5378

5379

5380

5381

5382

5384 return false;

5385

5386

5388 return false;

5389

5390

5392 if (CI->isConvergent())

5393 return false;

5394 }

5395

5396

5397

5398 if (I->mayWriteToMemory()) {

5400 return false;

5401 }

5402

5403

5404

5405 if (I->mayReadFromMemory() &&

5406 I->hasMetadata(LLVMContext::MD_invariant_load)) {

5407

5408

5409

5411 return false;

5413 E = I->getParent()->end();

5414 Scan != E; ++Scan)

5415 if (Scan->mayWriteToMemory())

5416 return false;

5417 }

5418

5419 I->dropDroppableUses([&](const Use *U) {

5421 if (I && I->getParent() != DestBlock) {

5423 return true;

5424 }

5425 return false;

5426 });

5427

5428

5429

5431 I->moveBefore(*DestBlock, InsertPos);

5432 ++NumSunkInst;

5433

5434

5435

5436

5437

5438

5441 if (!DbgVariableRecords.empty())

5443 DbgVariableRecords);

5444

5445

5446

5447

5448

5449

5450

5451

5452

5453

5454 return true;

5455}

5456

5461

5462

5463

5464

5466 for (auto &DVR : DbgVariableRecords)

5467 if (DVR->getParent() != DestBlock)

5468 DbgVariableRecordsToSalvage.push_back(DVR);

5469

5470

5471

5474 if (DVR->getParent() == SrcBlock)

5475 DbgVariableRecordsToSink.push_back(DVR);

5476

5477

5478

5479

5480

5482 return B->getInstruction()->comesBefore(A->getInstruction());

5483 };

5485

5486

5487

5488

5489 using InstVarPair = std::pair<const Instruction *, DebugVariable>;

5491 if (DbgVariableRecordsToSink.size() > 1) {

5493

5496 DebugVariable(DVR->getVariable(), DVR->getExpression(),

5497 DVR->getDebugLoc()->getInlinedAt());

5498 CountMap[std::make_pair(DVR->getInstruction(), DbgUserVariable)] += 1;

5499 }

5500

5501

5502

5504 for (auto It : CountMap) {

5505 if (It.second > 1) {

5506 FilterOutMap[It.first] = nullptr;

5507 DupSet.insert(It.first.first);

5508 }

5509 }

5510

5511

5512

5513 for (const Instruction *Inst : DupSet) {

5517 DebugVariable(DVR.getVariable(), DVR.getExpression(),

5518 DVR.getDebugLoc()->getInlinedAt());

5519 auto FilterIt =

5520 FilterOutMap.find(std::make_pair(Inst, DbgUserVariable));

5521 if (FilterIt == FilterOutMap.end())

5522 continue;

5523 if (FilterIt->second != nullptr)

5524 continue;

5525 FilterIt->second = &DVR;

5526 }

5527 }

5528 }

5529

5530

5531

5536 continue;

5537

5539 DebugVariable(DVR->getVariable(), DVR->getExpression(),

5540 DVR->getDebugLoc()->getInlinedAt());

5541

5542

5543

5544 if (!FilterOutMap.empty()) {

5545 InstVarPair IVP = std::make_pair(DVR->getInstruction(), DbgUserVariable);

5546 auto It = FilterOutMap.find(IVP);

5547

5548

5549 if (It != FilterOutMap.end() && It->second != DVR)

5550 continue;

5551 }

5552

5553 if (!SunkVariables.insert(DbgUserVariable).second)

5554 continue;

5555

5556 if (DVR->isDbgAssign())

5557 continue;

5558

5561 }

5562

5563

5564 if (DVRClones.empty())

5565 return;

5566

5568

5569

5570

5571

5572

5573

5574

5575

5576

5577

5578 assert(InsertPos.getHeadBit());

5580 InsertPos->getParent()->insertDbgRecordBefore(DVRClone, InsertPos);

5581 LLVM_DEBUG(dbgs() << "SINK: " << *DVRClone << '\n');

5582 }

5583}

5584

5586 while (Worklist.isEmpty()) {

5587

5588

5590

5591

5592

5593

5596 ++NumDeadInst;

5597 continue;

5598 }

5599

5601 }

5602

5604 if (I == nullptr) continue;

5605

5606

5609 ++NumDeadInst;

5610 continue;

5611 }

5612

5614 continue;

5615

5616

5617

5618

5619 auto getOptionalSinkBlockForInst =

5620 [this](Instruction *I) -> std::optional<BasicBlock *> {

5622 return std::nullopt;

5623

5626 unsigned NumUsers = 0;

5627

5628 for (Use &U : I->uses()) {

5631

5632

5634 if (II->getIntrinsicID() != Intrinsic::assume ||

5635 II->getOperandBundle("dereferenceable"))

5636 continue;

5637 }

5638

5640 return std::nullopt;

5641

5643

5646 UserBB = PN->getIncomingBlock(U);

5647

5648

5649

5650 if (UserParent && UserParent != UserBB)

5651 return std::nullopt;

5652 UserParent = UserBB;

5653

5654

5655

5656 if (NumUsers == 0) {

5657

5658

5659 if (UserParent == BB || DT.isReachableFromEntry(UserParent))

5660 return std::nullopt;

5661

5663

5664

5665

5666

5667

5668

5669

5670

5672 return std::nullopt;

5673

5674 assert(DT.dominates(BB, UserParent) && "Dominance relation broken?");

5675 }

5676

5677 NumUsers++;

5678 }

5679

5680

5681 if (!UserParent)

5682 return std::nullopt;

5683

5684 return UserParent;

5685 };

5686

5687 auto OptBB = getOptionalSinkBlockForInst(I);

5688 if (OptBB) {

5689 auto *UserParent = *OptBB;

5690

5694

5695

5696

5697 for (Use &U : I->operands())

5700 }

5701 }

5702

5703

5705 Builder.CollectMetadataToCopy(

5706 I, {LLVMContext::MD_dbg, LLVMContext::MD_annotation});

5707

5708#ifndef NDEBUG

5709 std::string OrigI;

5710#endif

5712 LLVM_DEBUG(dbgs() << "IC: Visiting: " << OrigI << '\n');

5713

5715 ++NumCombined;

5716

5717 if (Result != I) {

5719 << " New = " << *Result << '\n');

5720

5721

5722

5723

5724 Result->setDebugLoc(Result->getDebugLoc().orElse(I->getDebugLoc()));

5725

5726 Result->copyMetadata(*I, LLVMContext::MD_annotation);

5727

5728 I->replaceAllUsesWith(Result);

5729

5730

5731 Result->takeName(I);

5732

5733

5734 BasicBlock *InstParent = I->getParent();

5736

5737

5739

5742 else

5744 }

5745

5746 Result->insertInto(InstParent, InsertPos);

5747

5748

5749 Worklist.pushUsersToWorkList(*Result);

5751

5753 } else {

5755 << " New = " << *I << '\n');

5756

5757

5758

5761 } else {

5762 Worklist.pushUsersToWorkList(*I);

5764 }

5765 }

5767 }

5768 }

5769

5772}

5773

5774

5775

5776

5777

5778

5779

5783

5784public:

5786

5787 if (I->hasMetadataOtherThanDebugLoc())

5788 return;

5789

5790 auto Track = [](Metadata *ScopeList, auto &Container) {

5792 if (!MDScopeList || !Container.insert(MDScopeList).second)

5793 return;

5794 for (const auto &MDOperand : MDScopeList->operands())

5796 Container.insert(MDScope);

5797 };

5798

5799 Track(I->getMetadata(LLVMContext::MD_alias_scope), UsedAliasScopesAndLists);

5800 Track(I->getMetadata(LLVMContext::MD_noalias), UsedNoAliasScopesAndLists);

5801 }

5802

5805 if (!Decl)

5806 return false;

5807

5809 "llvm.experimental.noalias.scope.decl in use ?");

5812 "llvm.experimental.noalias.scope should refer to a single scope");

5815 return !UsedAliasScopesAndLists.contains(MD) ||

5816 !UsedNoAliasScopesAndLists.contains(MD);

5817

5818

5819 return true;

5820 }

5821};

5822

5823

5824

5825

5826

5827

5828

5829

5830

5837

5840 if (Succ != LiveSucc && DeadEdges.insert({BB, Succ}).second)

5841 for (PHINode &PN : Succ->phis())

5842 for (Use &U : PN.incoming_values())

5846 }

5847 };

5848

5851 return DeadEdges.contains({Pred, BB}) || DT.dominates(BB, Pred);

5852 })) {

5853 HandleOnlyLiveSuccessor(BB, nullptr);

5854 continue;

5855 }

5856 LiveBlocks.insert(BB);

5857

5859

5860 if (!Inst.use_empty() &&

5861 (Inst.getNumOperands() == 0 || isa(Inst.getOperand(0))))

5863 LLVM_DEBUG(dbgs() << "IC: ConstFold to: " << *C << " from: " << Inst

5864 << '\n');

5865 Inst.replaceAllUsesWith(C);

5866 ++NumConstProp;

5868 Inst.eraseFromParent();

5870 continue;

5871 }

5872

5873

5874 for (Use &U : Inst.operands()) {

5876 continue;

5877

5879 Constant *&FoldRes = FoldedConstants[C];

5880 if (!FoldRes)

5882

5883 if (FoldRes != C) {

5884 LLVM_DEBUG(dbgs() << "IC: ConstFold operand of: " << Inst

5885 << "\n Old = " << *C

5886 << "\n New = " << *FoldRes << '\n');

5887 U = FoldRes;

5889 }

5890 }

5891

5892

5893

5894

5895 if (!Inst.isDebugOrPseudoInst()) {

5896 InstrsForInstructionWorklist.push_back(&Inst);

5897 SeenAliasScopes.analyse(&Inst);

5898 }

5899 }

5900

5901

5902

5906

5907 HandleOnlyLiveSuccessor(BB, nullptr);

5908 continue;

5909 }

5911 bool CondVal = Cond->getZExtValue();

5912 HandleOnlyLiveSuccessor(BB, BI->getSuccessor(!CondVal));

5913 continue;

5914 }

5917

5918 HandleOnlyLiveSuccessor(BB, nullptr);

5919 continue;

5920 }

5922 HandleOnlyLiveSuccessor(BB,

5923 SI->findCaseValue(Cond)->getCaseSuccessor());

5924 continue;

5925 }

5926 }

5927 }

5928

5929

5930

5931

5933 if (LiveBlocks.count(&BB))

5934 continue;

5935

5936 unsigned NumDeadInstInBB;

5938

5940 NumDeadInst += NumDeadInstInBB;

5941 }

5942

5943

5944

5945

5946

5947

5948 Worklist.reserve(InstrsForInstructionWorklist.size());

5950

5951

5954 ++NumDeadInst;

5957 Inst->eraseFromParent();

5959 continue;

5960 }

5961

5963 }

5964

5966}

5967

5979

5986 auto &DL = F.getDataLayout();

5988 F.hasFnAttribute("instcombine-no-verify-fixpoint");

5989

5990

5991

5995 Worklist.add(I);

5998 }));

5999

6001

6002

6003

6004 bool MadeIRChange = false;

6007

6008

6009 unsigned Iteration = 0;

6010 while (true) {

6011 if (Iteration >= Opts.MaxIterations && !VerifyFixpoint) {

6013 << " on " << F.getName()

6014 << " reached; stopping without verifying fixpoint\n");

6015 break;

6016 }

6017

6018 ++Iteration;

6019 ++NumWorklistIterations;

6020 LLVM_DEBUG(dbgs() << "\n\nINSTCOMBINE ITERATION #" << Iteration << " on "

6021 << F.getName() << "\n");

6022

6023 InstCombinerImpl IC(Worklist, Builder, F, AA, AC, TLI, TTI, DT, ORE, BFI,

6024 BPI, PSI, DL, RPOT);

6027 MadeChangeInThisIteration |= IC.run();

6028 if (!MadeChangeInThisIteration)

6029 break;

6030

6031 MadeIRChange = true;

6034 "Instruction Combining on " + Twine(F.getName()) +

6036 " iterations. " +

6037 "Use 'instcombine' or function attribute "

6038 "'instcombine-no-verify-fixpoint' to suppress this error.");

6039 }

6040 }

6041

6042 if (Iteration == 1)

6043 ++NumOneIteration;

6044 else if (Iteration == 2)

6045 ++NumTwoIterations;

6046 else if (Iteration == 3)

6047 ++NumThreeIterations;

6048 else

6049 ++NumFourOrMoreIterations;

6050

6051 return MadeIRChange;

6052}

6053

6055

6059 OS, MapClassName2PassName);

6060 OS << '<';

6061 OS << "max-iterations=" << Options.MaxIterations << ";";

6062 OS << (Options.VerifyFixpoint ? "" : "no-") << "verify-fixpoint";

6063 OS << '>';

6064}

6065

6066char InstCombinePass::ID = 0;

6067

6071

6072 if (LRT.shouldSkip(&ID))

6074

6080

6085 auto *BFI = (PSI && PSI->hasProfileSummary()) ?

6088

6090 BFI, BPI, PSI, Options)) {

6091

6092 LRT.update(&ID, false);

6094 }

6095

6096

6098 LRT.update(&ID, true);

6101 return PA;

6102}

6103

6119

6122 return false;

6123

6124

6131

6132

6138 nullptr;

6140 if (auto *WrapperPass =

6142 BPI = &WrapperPass->getBPI();

6143

6146}

6147

6149

6153

6155 "Combine redundant instructions", false, false)

6167

6168

6172

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

AMDGPU Register Bank Select

This file declares a class to represent arbitrary precision floating point values and provide a varie...

This file implements a class to represent arbitrary precision integral constant values and operations...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

This is the interface for LLVM's primary stateless and local alias analysis.

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

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

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

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

This file contains the declarations for the subclasses of Constant, which represent the different fla...

This file provides an implementation of debug counters.

#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)

This file defines the DenseMap class.

static bool isSigned(unsigned int Opcode)

This is the interface for a simple mod/ref and alias analysis over globals.

shuff Hexagon Optimize Shuffle Vector

This file provides various utilities for inspecting and working with the control flow graph in LLVM I...

This header defines various interfaces for pass management in LLVM.

This defines the Use class.

iv Induction Variable Users

static bool leftDistributesOverRight(Instruction::BinaryOps LOp, bool HasNUW, bool HasNSW, Intrinsic::ID ROp)

Return whether "X LOp (Y ROp Z)" is always equal to "(X LOp Y) ROp (X LOp Z)".

This file provides internal interfaces used to implement the InstCombine.

This file provides the primary interface to the instcombine pass.

static Value * simplifySwitchOnSelectUsingRanges(SwitchInst &SI, SelectInst *Select, bool IsTrueArm)

Definition InstructionCombining.cpp:4255

static bool isUsedWithinShuffleVector(Value *V)

Definition InstructionCombining.cpp:5192

static bool isNeverEqualToUnescapedAlloc(Value *V, const TargetLibraryInfo &TLI, Instruction *AI)

Definition InstructionCombining.cpp:3533

static Constant * constantFoldBinOpWithSplat(unsigned Opcode, Constant *Vector, Constant *Splat, bool SplatLHS, const DataLayout &DL)

Definition InstructionCombining.cpp:2334

static bool shorter_filter(const Value *LHS, const Value *RHS)

Definition InstructionCombining.cpp:4700

static Instruction * combineConstantOffsets(GetElementPtrInst &GEP, InstCombinerImpl &IC)

Combine constant offsets separated by variable offsets.

Definition InstructionCombining.cpp:2735

static Instruction * foldSelectGEP(GetElementPtrInst &GEP, InstCombiner::BuilderTy &Builder)

Thread a GEP operation with constant indices through the constant true/false arms of a select.

Definition InstructionCombining.cpp:2663

static bool shouldMergeGEPs(GEPOperator &GEP, GEPOperator &Src)

Definition InstructionCombining.cpp:2280

static cl::opt< unsigned > MaxArraySize("instcombine-maxarray-size", cl::init(1024), cl::desc("Maximum array size considered when doing a combine"))

static cl::opt< unsigned > ShouldLowerDbgDeclare("instcombine-lower-dbg-declare", cl::Hidden, cl::init(true))

static bool hasNoSignedWrap(BinaryOperator &I)

Definition InstructionCombining.cpp:390

static bool simplifyAssocCastAssoc(BinaryOperator *BinOp1, InstCombinerImpl &IC)

Combine constant operands of associative operations either before or after a cast to eliminate one of...

Definition InstructionCombining.cpp:414

static bool combineInstructionsOverFunction(Function &F, InstructionWorklist &Worklist, AliasAnalysis *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, TargetTransformInfo &TTI, DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI, ProfileSummaryInfo *PSI, const InstCombineOptions &Opts)

Definition InstructionCombining.cpp:5980

static Value * simplifyInstructionWithPHI(Instruction &I, PHINode *PN, Value *InValue, BasicBlock *InBB, const DataLayout &DL, const SimplifyQuery SQ)

Definition InstructionCombining.cpp:1839

static bool shouldCanonicalizeGEPToPtrAdd(GetElementPtrInst &GEP)

Return true if we should canonicalize the gep to an i8 ptradd.

Definition InstructionCombining.cpp:3042

static void ClearSubclassDataAfterReassociation(BinaryOperator &I)

Conservatively clears subclassOptionalData after a reassociation or commutation.

Definition InstructionCombining.cpp:398

static Value * getIdentityValue(Instruction::BinaryOps Opcode, Value *V)

This function returns identity value for given opcode, which can be used to factor patterns like (X *...

Definition InstructionCombining.cpp:704

static Value * foldFrexpOfSelect(ExtractValueInst &EV, IntrinsicInst *FrexpCall, SelectInst *SelectInst, InstCombiner::BuilderTy &Builder)

Definition InstructionCombining.cpp:4498

static std::optional< std::pair< Value *, Value * > > matchSymmetricPhiNodesPair(PHINode *LHS, PHINode *RHS)

Definition InstructionCombining.cpp:1296

static Value * foldOperationIntoSelectOperand(Instruction &I, SelectInst *SI, Value *NewOp, InstCombiner &IC)

Definition InstructionCombining.cpp:1773

static Instruction * canonicalizeGEPOfConstGEPI8(GetElementPtrInst &GEP, GEPOperator *Src, InstCombinerImpl &IC)

Definition InstructionCombining.cpp:2690

static Instruction * tryToMoveFreeBeforeNullTest(CallInst &FI, const DataLayout &DL)

Move the call to free before a NULL test.

Definition InstructionCombining.cpp:3879

static Value * simplifyOperationIntoSelectOperand(Instruction &I, SelectInst *SI, bool IsTrueArm)

Definition InstructionCombining.cpp:1748

static bool rightDistributesOverLeft(Instruction::BinaryOps LOp, Instruction::BinaryOps ROp)

Return whether "(X LOp Y) ROp Z" is always equal to "(X ROp Z) LOp (Y ROp Z)".

Definition InstructionCombining.cpp:689

static Value * tryFactorization(BinaryOperator &I, const SimplifyQuery &SQ, InstCombiner::BuilderTy &Builder, Instruction::BinaryOps InnerOpcode, Value *A, Value *B, Value *C, Value *D)

This tries to simplify binary operations by factorizing out common terms (e.

Definition InstructionCombining.cpp:745

static bool isRemovableWrite(CallBase &CB, Value *UsedV, const TargetLibraryInfo &TLI)

Given a call CB which uses an address UsedV, return true if we can prove the call's only possible eff...

Definition InstructionCombining.cpp:3545

static Instruction::BinaryOps getBinOpsForFactorization(Instruction::BinaryOps TopOpcode, BinaryOperator *Op, Value *&LHS, Value *&RHS, BinaryOperator *OtherOp)

This function predicates factorization using distributive laws.

Definition InstructionCombining.cpp:717

static bool hasNoUnsignedWrap(BinaryOperator &I)

Definition InstructionCombining.cpp:385

static bool SoleWriteToDeadLocal(Instruction *I, TargetLibraryInfo &TLI)

Check for case where the call writes to an otherwise dead alloca.

Definition InstructionCombining.cpp:5326

static cl::opt< unsigned > MaxSinkNumUsers("instcombine-max-sink-users", cl::init(32), cl::desc("Maximum number of undroppable users for instruction sinking"))

static Instruction * foldGEPOfPhi(GetElementPtrInst &GEP, PHINode *PN, IRBuilderBase &Builder)

Definition InstructionCombining.cpp:3071

static std::optional< ModRefInfo > isAllocSiteRemovable(Instruction *AI, SmallVectorImpl< WeakTrackingVH > &Users, const TargetLibraryInfo &TLI, bool KnowInit)

Definition InstructionCombining.cpp:3566

static bool isCatchAll(EHPersonality Personality, Constant *TypeInfo)

Return 'true' if the given typeinfo will match anything.

Definition InstructionCombining.cpp:4671

static cl::opt< bool > EnableCodeSinking("instcombine-code-sinking", cl::desc("Enable code sinking"), cl::init(true))

static bool maintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C)

Definition InstructionCombining.cpp:357

static GEPNoWrapFlags getMergedGEPNoWrapFlags(GEPOperator &GEP1, GEPOperator &GEP2)

Determine nowrap flags for (gep (gep p, x), y) to (gep p, (x + y)) transform.

Definition InstructionCombining.cpp:2656

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

uint64_t IntrinsicInst * II

static bool IsSelect(MachineInstr &MI)

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

const SmallVectorImpl< MachineOperand > & Cond

static unsigned getNumElements(Type *Ty)

BaseType

A given derived pointer can have multiple base pointers through phi/selects.

This file defines the SmallPtrSet class.

This file defines the SmallVector class.

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)

This pass exposes codegen information to IR-level passes.

static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)

Returns the opcode of Values or ~0 if they do not all agree.

static const uint32_t IV[8]

bool isNoAliasScopeDeclDead(Instruction *Inst)

Definition InstructionCombining.cpp:5803

void analyse(Instruction *I)

Definition InstructionCombining.cpp:5785

A manager for alias analyses.

A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.

static constexpr roundingMode rmNearestTiesToEven

static LLVM_ABI unsigned int semanticsPrecision(const fltSemantics &)

Class for arbitrary precision integers.

static APInt getAllOnes(unsigned numBits)

Return an APInt of a specified width with all bits set.

static LLVM_ABI void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)

Dual division/remainder interface.

bool isMinSignedValue() const

Determine if this is the smallest signed value.

static LLVM_ABI void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)

LLVM_ABI APInt trunc(unsigned width) const

Truncate to new width.

bool isAllOnes() const

Determine if all bits are set. This is true for zero-width values.

bool isZero() const

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

unsigned getBitWidth() const

Return the number of bits in the APInt.

LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const

APInt ashr(unsigned ShiftAmt) const

Arithmetic right-shift function.

LLVM_ABI APInt smul_ov(const APInt &RHS, bool &Overflow) const

bool isNonNegative() const

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

bool ule(const APInt &RHS) const

Unsigned less or equal comparison.

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.

LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const

APInt lshr(unsigned shiftAmt) const

Logical right-shift function.

PassT::Result * getCachedResult(IRUnitT &IR) const

Get the cached result of an analysis pass for a given IR unit.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

LLVM_ABI void setPreservesCFG()

This function should be called by the pass, iff they do not:

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

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

Return a copy of *this with only the first N elements.

size_t size() const

size - Get the array size.

Class to represent array types.

static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)

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

uint64_t getNumElements() const

Type * getElementType() const

A function analysis which provides an AssumptionCache.

An immutable pass that tracks lazily created AssumptionCache objects.

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

LLVM_ABI void registerAssumption(AssumeInst *CI)

Add an @llvm.assume intrinsic to this function's cache.

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

LLVM_ABI uint64_t getDereferenceableBytes() const

Returns the number of dereferenceable bytes from the dereferenceable attribute.

bool isValid() const

Return true if the attribute is any kind of attribute.

Legacy wrapper pass to provide the BasicAAResult object.

LLVM Basic Block Representation.

iterator_range< const_phi_iterator > phis() const

Returns a range that iterates over the phis in the basic block.

LLVM_ABI const_iterator getFirstInsertionPt() const

Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...

LLVM_ABI iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const

Return a const iterator range over the instructions in the block, skipping any debug instructions.

LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const

Returns an iterator to the first instruction in this block that is not a PHINode instruction.

LLVM_ABI bool isEntryBlock() const

Return true if this is the entry block of the containing function.

LLVM_ABI const BasicBlock * getSinglePredecessor() const

Return the predecessor of this block if it has a single predecessor block.

const Instruction & front() const

LLVM_ABI const BasicBlock * getUniquePredecessor() const

Return the predecessor of this block if it has a unique predecessor block.

InstListType::iterator iterator

Instruction iterators...

LLVM_ABI const_iterator getFirstNonPHIOrDbgOrAlloca() const

Returns an iterator to the first instruction in this block that is not a PHINode, a debug intrinsic,...

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

static LLVM_ABI BinaryOperator * CreateNeg(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Helper functions to construct and inspect unary operations (NEG and NOT) via binary operators SUB and...

BinaryOps getOpcode() const

static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)

Construct a binary instruction, given the opcode and the two operands.

static BinaryOperator * CreateNUW(BinaryOps Opc, Value *V1, Value *V2, const Twine &Name="")

Analysis pass which computes BlockFrequencyInfo.

BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...

Conditional or Unconditional Branch instruction.

LLVM_ABI void swapSuccessors()

Swap the successors of this branch instruction.

bool isConditional() const

BasicBlock * getSuccessor(unsigned i) const

bool isUnconditional() const

Value * getCondition() const

Analysis pass which computes BranchProbabilityInfo.

Analysis providing branch probability information.

Represents analyses that only rely on functions' control flow.

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

Function * getCalledFunction() const

Returns the function called, or null if this is an indirect function invocation or the function signa...

void setAttributes(AttributeList A)

Set the attributes for this call.

bool doesNotThrow() const

Determine if the call cannot unwind.

Value * getArgOperand(unsigned i) const

AttributeList getAttributes() const

Return the attributes for this call.

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

static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ ICMP_UGT

unsigned greater than

@ ICMP_ULT

unsigned less than

Predicate getSwappedPredicate() const

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

Predicate getInversePredicate() const

For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...

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

ConstantArray - Constant Array Declarations.

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

A vector constant whose element type is a simple 1/2/4/8-byte integer or float/double,...

static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)

static LLVM_ABI Constant * getNot(Constant *C)

static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)

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 Constant * getNeg(Constant *C, bool HasNSW=false)

This is the shared class of boolean and integer constants.

static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)

static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)

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

This class represents a range of values.

LLVM_ABI bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const

Set up Pred and RHS such that ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.

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 bool contains(const APInt &Val) const

Return true if the specified value is in the set.

static LLVM_ABI ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, const APInt &Other, unsigned NoWrapKind)

Produce the range that contains X if and only if "X BinOp Other" does not wrap.

Constant Vector Declarations.

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 * getIntegerValue(Type *Ty, const APInt &V)

Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...

static LLVM_ABI Constant * replaceUndefsWith(Constant *C, Constant *Replacement)

Try to replace undefined constant C or undefined elements in C with Replacement.

static LLVM_ABI Constant * getAllOnesValue(Type *Ty)

const Constant * stripPointerCasts() const

static LLVM_ABI Constant * getNullValue(Type *Ty)

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

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.

static LLVM_ABI DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)

Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...

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

Record of a variable value-assignment, aka a non instruction representation of the dbg....

static bool shouldExecute(CounterInfo &Counter)

Identifies a unique instance of a variable.

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

Analysis pass which computes a DominatorTree.

Legacy analysis pass which computes a DominatorTree.

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

Utility class for floating point operations which can have information about relaxed accuracy require...

Convenience struct for specifying and reasoning about fast-math flags.

This class represents a freeze function that returns random concrete value if an operand is either a ...

FunctionPass class - This class is used to implement most global optimizations.

bool skipFunction(const Function &F) const

Optional passes call this function to check whether the pass should be skipped.

const BasicBlock & getEntryBlock() const

Represents flags for the getelementptr instruction/expression.

static GEPNoWrapFlags inBounds()

static GEPNoWrapFlags all()

static GEPNoWrapFlags noUnsignedWrap()

GEPNoWrapFlags intersectForReassociate(GEPNoWrapFlags Other) const

Given (gep (gep p, x), y), determine the nowrap flags for (gep (gep, p, y), x).

bool hasNoUnsignedWrap() const

GEPNoWrapFlags intersectForOffsetAdd(GEPNoWrapFlags Other) const

Given (gep (gep p, x), y), determine the nowrap flags for (gep p, x+y).

static GEPNoWrapFlags none()

GEPNoWrapFlags getNoWrapFlags() const

an instruction for type-safe pointer arithmetic to access elements of arrays and structs

static LLVM_ABI Type * getTypeAtIndex(Type *Ty, Value *Idx)

Return the type of the element at the given index of an indexable type.

static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

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.

static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

Create an "inbounds" getelementptr.

Legacy wrapper pass to provide the GlobalsAAResult object.

This instruction compares its operands according to the predicate given to the constructor.

CmpPredicate getCmpPredicate() const

static bool isEquality(Predicate P)

Return true if this predicate is either EQ or NE.

Common base class shared among various IRBuilders.

Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())

ConstantInt * getInt(const APInt &AI)

Get a constant integer value.

Provides an 'InsertHelper' that calls a user-provided callback after performing the default insertion...

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

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

static InsertValueInst * Create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

LLVM_ABI InstCombinePass(InstCombineOptions Opts={})

Definition InstructionCombining.cpp:6054

LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)

Definition InstructionCombining.cpp:6056

LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

Definition InstructionCombining.cpp:6068

Instruction * foldBinOpOfSelectAndCastOfSelectCondition(BinaryOperator &I)

Tries to simplify binops of select and cast of the select condition.

Definition InstructionCombining.cpp:1101

Instruction * foldBinOpIntoSelectOrPhi(BinaryOperator &I)

This is a convenience wrapper function for the above two functions.

Definition InstructionCombining.cpp:2266

bool SimplifyAssociativeOrCommutative(BinaryOperator &I)

Performs a few simplifications for operators which are associative or commutative.

Definition InstructionCombining.cpp:499

Instruction * visitGEPOfGEP(GetElementPtrInst &GEP, GEPOperator *Src)

Definition InstructionCombining.cpp:2789

Value * foldUsingDistributiveLaws(BinaryOperator &I)

Tries to simplify binary operations which some other binary operation distributes over.

Definition InstructionCombining.cpp:1203

Instruction * foldBinOpShiftWithShift(BinaryOperator &I)

Definition InstructionCombining.cpp:955

Instruction * visitUnreachableInst(UnreachableInst &I)

Definition InstructionCombining.cpp:4065

Instruction * foldOpIntoPhi(Instruction &I, PHINode *PN, bool AllowMultipleUses=false)

Given a binary operator, cast instruction, or select which has a PHI node as operand #0,...

Definition InstructionCombining.cpp:1879

void handleUnreachableFrom(Instruction *I, SmallVectorImpl< BasicBlock * > &Worklist)

Definition InstructionCombining.cpp:4113

Value * SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, APInt &PoisonElts, unsigned Depth=0, bool AllowMultipleUsers=false) override

The specified value produces a vector with any number of elements.

Instruction * visitFreeze(FreezeInst &I)

Definition InstructionCombining.cpp:5202

void handlePotentiallyDeadBlocks(SmallVectorImpl< BasicBlock * > &Worklist)

Definition InstructionCombining.cpp:4143

bool prepareWorklist(Function &F)

Perform early cleanup and prepare the InstCombine worklist.

Definition InstructionCombining.cpp:5831

Instruction * FoldOpIntoSelect(Instruction &Op, SelectInst *SI, bool FoldWithMultiUse=false, bool SimplifyBothArms=false)

Given an instruction with a select as one operand and a constant as the other operand,...

Definition InstructionCombining.cpp:1782

Instruction * visitFree(CallInst &FI, Value *FreedOp)

Definition InstructionCombining.cpp:3963

Instruction * visitExtractValueInst(ExtractValueInst &EV)

Definition InstructionCombining.cpp:4541

void handlePotentiallyDeadSuccessors(BasicBlock *BB, BasicBlock *LiveSucc)

Definition InstructionCombining.cpp:4156

Instruction * visitUnconditionalBranchInst(BranchInst &BI)

Definition InstructionCombining.cpp:4070

Instruction * foldBinopWithRecurrence(BinaryOperator &BO)

Try to fold binary operators whose operands are simple interleaved recurrences to a single recurrence...

Definition InstructionCombining.cpp:2048

Instruction * eraseInstFromFunction(Instruction &I) override

Combiner aware instruction erasure.

Instruction * visitLandingPadInst(LandingPadInst &LI)

Definition InstructionCombining.cpp:4707

Instruction * visitReturnInst(ReturnInst &RI)

Definition InstructionCombining.cpp:4003

Instruction * visitSwitchInst(SwitchInst &SI)

Definition InstructionCombining.cpp:4284

Instruction * foldBinopWithPhiOperands(BinaryOperator &BO)

For a binary operator with 2 phi operands, try to hoist the binary operation before the phi.

Definition InstructionCombining.cpp:2151

bool mergeStoreIntoSuccessor(StoreInst &SI)

Try to transform: if () { *P = v1; } else { *P = v2 } or: *P = v1; if () { *P = v2; }...

Instruction * tryFoldInstWithCtpopWithNot(Instruction *I)

Definition InstructionCombining.cpp:850

void CreateNonTerminatorUnreachable(Instruction *InsertAt)

Create and insert the idiom we use to indicate a block is unreachable without having to rewrite the C...

Value * pushFreezeToPreventPoisonFromPropagating(FreezeInst &FI)

Definition InstructionCombining.cpp:5017

bool run()

Run the combiner over the entire worklist until it is empty.

Definition InstructionCombining.cpp:5585

Instruction * foldVectorBinop(BinaryOperator &Inst)

Canonicalize the position of binops relative to shufflevector.

Definition InstructionCombining.cpp:2345

bool removeInstructionsBeforeUnreachable(Instruction &I)

Definition InstructionCombining.cpp:4038

Value * SimplifySelectsFeedingBinaryOp(BinaryOperator &I, Value *LHS, Value *RHS)

Definition InstructionCombining.cpp:1359

void tryToSinkInstructionDbgVariableRecords(Instruction *I, BasicBlock::iterator InsertPos, BasicBlock *SrcBlock, BasicBlock *DestBlock, SmallVectorImpl< DbgVariableRecord * > &DPUsers)

Definition InstructionCombining.cpp:5457

void addDeadEdge(BasicBlock *From, BasicBlock *To, SmallVectorImpl< BasicBlock * > &Worklist)

Definition InstructionCombining.cpp:4094

Constant * unshuffleConstant(ArrayRef< int > ShMask, Constant *C, VectorType *NewCTy)

Find a constant NewC that has property: shuffle(NewC, ShMask) = C Returns nullptr if such a constant ...

Definition InstructionCombining.cpp:2296

Instruction * visitAllocSite(Instruction &FI)

Definition InstructionCombining.cpp:3713

Instruction * visitGetElementPtrInst(GetElementPtrInst &GEP)

Definition InstructionCombining.cpp:3181

Instruction * visitBranchInst(BranchInst &BI)

Definition InstructionCombining.cpp:4170

Value * tryFactorizationFolds(BinaryOperator &I)

This tries to simplify binary operations by factorizing out common terms (e.

Definition InstructionCombining.cpp:1160

Instruction * foldFreezeIntoRecurrence(FreezeInst &I, PHINode *PN)

Definition InstructionCombining.cpp:5083

Value * SimplifyDemandedUseFPClass(Value *V, FPClassTest DemandedMask, KnownFPClass &Known, Instruction *CxtI, unsigned Depth=0)

Attempts to replace V with a simpler value based on the demanded floating-point classes.

bool tryToSinkInstruction(Instruction *I, BasicBlock *DestBlock)

Try to move the specified instruction from its current block into the beginning of DestBlock,...

Definition InstructionCombining.cpp:5370

bool freezeOtherUses(FreezeInst &FI)

Definition InstructionCombining.cpp:5151

void freelyInvertAllUsersOf(Value *V, Value *IgnoredUser=nullptr)

Freely adapt every user of V as-if V was changed to !V.

Definition InstructionCombining.cpp:1442

The core instruction combiner logic.

const DataLayout & getDataLayout() const

IRBuilder< TargetFolder, IRBuilderCallbackInserter > BuilderTy

An IRBuilder that automatically inserts new instructions into the worklist.

bool isFreeToInvert(Value *V, bool WillInvertAllUses, bool &DoesConsume)

Return true if the specified value is free to invert (apply ~ to).

static unsigned getComplexity(Value *V)

Assign a complexity or rank value to LLVM Values.

unsigned ComputeNumSignBits(const Value *Op, const Instruction *CxtI=nullptr, unsigned Depth=0) const

Instruction * InsertNewInstBefore(Instruction *New, BasicBlock::iterator Old)

Inserts an instruction New before instruction Old.

Instruction * replaceInstUsesWith(Instruction &I, Value *V)

A combiner-aware RAUW-like routine.

uint64_t MaxArraySizeForCombine

Maximum size of array considered when transforming.

static bool shouldAvoidAbsorbingNotIntoSelect(const SelectInst &SI)

void replaceUse(Use &U, Value *NewValue)

Replace use and add the previously used value to the worklist.

static bool isCanonicalPredicate(CmpPredicate Pred)

Predicate canonicalization reduces the number of patterns that need to be matched by other transforms...

InstructionWorklist & Worklist

A worklist of the instructions that need to be simplified.

Instruction * InsertNewInstWith(Instruction *New, BasicBlock::iterator Old)

Same as InsertNewInstBefore, but also sets the debug loc.

BranchProbabilityInfo * BPI

ReversePostOrderTraversal< BasicBlock * > & RPOT

void computeKnownBits(const Value *V, KnownBits &Known, const Instruction *CxtI, unsigned Depth=0) const

std::optional< Instruction * > targetInstCombineIntrinsic(IntrinsicInst &II)

Definition InstructionCombining.cpp:162

void addToWorklist(Instruction *I)

Value * getFreelyInvertedImpl(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume, unsigned Depth)

Return nonnull value if V is free to invert under the condition of WillInvertAllUses.

Definition InstructionCombining.cpp:2852

SmallDenseSet< std::pair< const BasicBlock *, const BasicBlock * >, 8 > BackEdges

Backedges, used to avoid pushing instructions across backedges in cases where this may result in infi...

std::optional< Value * > targetSimplifyDemandedVectorEltsIntrinsic(IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2, APInt &UndefElts3, std::function< void(Instruction *, unsigned, APInt, APInt &)> SimplifyAndSetOp)

Definition InstructionCombining.cpp:181

void computeBackEdges()

Definition InstructionCombining.cpp:5968

Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)

Replace operand of instruction and add old operand to the worklist.

static Constant * getSafeVectorConstantForBinop(BinaryOperator::BinaryOps Opcode, Constant *In, bool IsRHSConstant)

Some binary operators require special handling to avoid poison and undefined behavior.

SmallDenseSet< std::pair< BasicBlock *, BasicBlock * >, 8 > DeadEdges

Edges that are known to never be taken.

std::optional< Value * > targetSimplifyDemandedUseBitsIntrinsic(IntrinsicInst &II, APInt DemandedMask, KnownBits &Known, bool &KnownBitsComputed)

Definition InstructionCombining.cpp:170

bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const

Definition InstructionCombining.cpp:195

Value * getFreelyInverted(Value *V, bool WillInvertAllUses, BuilderTy *Builder, bool &DoesConsume)

bool isBackEdge(const BasicBlock *From, const BasicBlock *To)

void visit(Iterator Start, Iterator End)

The legacy pass manager's instcombine pass.

InstructionCombiningPass()

Definition InstructionCombining.cpp:6150

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

Definition InstructionCombining.cpp:6104

bool runOnFunction(Function &F) override

runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.

Definition InstructionCombining.cpp:6120

InstructionWorklist - This is the worklist management logic for InstCombine and other simplification ...

void add(Instruction *I)

Add instruction to the worklist.

LLVM_ABI void dropUBImplyingAttrsAndMetadata(ArrayRef< unsigned > Keep={})

Drop any attributes or metadata that can cause immediate undefined behavior.

static bool isBitwiseLogicOp(unsigned Opcode)

Determine if the Opcode is and/or/xor.

LLVM_ABI void copyIRFlags(const Value *V, bool IncludeWrapFlags=true)

Convenience method to copy supported exact, fast-math, and (optionally) wrapping flags from V to this...

const DebugLoc & getDebugLoc() const

Return the debug location for this node as a DebugLoc.

LLVM_ABI const Module * getModule() const

Return the module owning the function this instruction belongs to or nullptr it the function does not...

LLVM_ABI void setAAMetadata(const AAMDNodes &N)

Sets the AA metadata on this instruction from the AAMDNodes structure.

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 void moveBefore(InstListType::iterator InsertPos)

Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...

LLVM_ABI void setFastMathFlags(FastMathFlags FMF)

Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...

LLVM_ABI const Function * getFunction() const

Return the function this instruction belongs to.

bool isTerminator() const

LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY

Convenience function for getting all the fast-math flags, which must be an operator which supports th...

LLVM_ABI bool willReturn() const LLVM_READONLY

Return true if the instruction will return (unwinding is considered as a form of returning control fl...

unsigned getOpcode() const

Returns a member of one of the enums like Instruction::Add.

bool isBitwiseLogicOp() const

Return true if this is and/or/xor.

LLVM_ABI void dropPoisonGeneratingFlags()

Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.

void setDebugLoc(DebugLoc Loc)

Set the debug location information for this instruction.

Class to represent integer types.

static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)

This static method is the primary way of constructing an IntegerType.

A wrapper class for inspecting calls to intrinsic functions.

static InvokeInst * Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr, InsertPosition InsertBefore=nullptr)

The landingpad instruction holds all of the information necessary to generate correct exception handl...

bool isCleanup() const

Return 'true' if this landingpad instruction is a cleanup.

unsigned getNumClauses() const

Get the number of clauses for this landing pad.

static LLVM_ABI LandingPadInst * Create(Type *RetTy, unsigned NumReservedClauses, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

Constructors - NumReservedClauses is a hint for the number of incoming clauses that this landingpad w...

LLVM_ABI void addClause(Constant *ClauseVal)

Add a catch or filter clause to the landing pad.

bool isCatch(unsigned Idx) const

Return 'true' if the clause and index Idx is a catch clause.

bool isFilter(unsigned Idx) const

Return 'true' if the clause and index Idx is a filter clause.

Constant * getClause(unsigned Idx) const

Get the value of the clause at index Idx.

void setCleanup(bool V)

Indicate that this landingpad instruction is a cleanup.

A function/module analysis which provides an empty LastRunTrackingInfo.

This is an alternative analysis pass to BlockFrequencyInfoWrapperPass.

static void getLazyBFIAnalysisUsage(AnalysisUsage &AU)

Helper for client passes to set up the analysis usage on behalf of this pass.

An instruction for reading from memory.

Value * getPointerOperand()

bool isVolatile() const

Return true if this is a load from a volatile memory location.

const MDOperand & getOperand(unsigned I) const

unsigned getNumOperands() const

Return number of MDNode operands.

Tracking metadata reference owned by Metadata.

This is the common base class for memset/memcpy/memmove.

static LLVM_ABI MemoryLocation getForDest(const MemIntrinsic *MI)

Return a location representing the destination of a memory set or transfer.

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

Returns the comparison predicate underlying the intrinsic.

A Module instance is used to store all the information related to an LLVM module.

MDNode * getScopeList() const

Utility class for integer operators which may exhibit overflow - Add, Sub, Mul, and Shl.

bool hasNoSignedWrap() const

Test whether this operation is known to never undergo signed overflow, aka the nsw property.

bool hasNoUnsignedWrap() const

Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.

void addIncoming(Value *V, BasicBlock *BB)

Add an incoming value to the end of the PHI list.

op_range incoming_values()

BasicBlock * getIncomingBlock(unsigned i) const

Return incoming basic block number i.

Value * getIncomingValue(unsigned i) const

Return incoming value number x.

unsigned getNumIncomingValues() const

Return the number of incoming edges.

static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...

PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...

static LLVM_ABI PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

AnalysisType & getAnalysis() const

getAnalysis() - This function is used by subclasses to get to the analysis information ...

AnalysisType * getAnalysisIfAvailable() const

getAnalysisIfAvailable() - Subclasses use this function to get analysis information tha...

In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...

static LLVM_ABI PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

PreservedAnalyses & preserveSet()

Mark an analysis set as preserved.

PreservedAnalyses & preserve()

Mark an analysis as preserved.

An analysis pass based on the new PM to deliver ProfileSummaryInfo.

An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.

Analysis providing profile information.

bool hasProfileSummary() const

Returns true if profile summary is available.

A global registry used in conjunction with static constructors to make pluggable components (like tar...

Return a value (possibly void), from a function.

Value * getReturnValue() const

Convenience accessor. Returns null if there is no return value.

static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)

This class represents the LLVM 'select' instruction.

const Value * getFalseValue() const

const Value * getCondition() const

static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)

const Value * getTrueValue() const

bool insert(const value_type &X)

Insert a new element into the SetVector.

This instruction constructs a fixed permutation of two input vectors.

size_type count(ConstPtrType Ptr) const

count - Return 1 if the specified pointer is in the set, 0 otherwise.

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.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

reference emplace_back(ArgTypes &&... Args)

void reserve(size_type N)

iterator erase(const_iterator CI)

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

typename SuperClass::iterator iterator

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

An instruction for storing to memory.

StringRef - Represent a constant reference to a string, i.e.

TargetFolder - Create constants with target dependent folding.

Analysis pass providing the TargetTransformInfo.

Analysis pass providing the TargetLibraryInfo.

Provides information about what library functions are available for the current target.

bool has(LibFunc F) const

Tests whether a library function is available.

bool getLibFunc(StringRef funcName, LibFunc &F) const

Searches for a particular function name.

Wrapper pass for TargetTransformInfo.

This pass provides access to the codegen interfaces that are needed for IR-level transformations.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

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.

LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const

Return true if this is a type whose size is a known multiple of vscale.

bool isPointerTy() const

True if this is an instance of PointerType.

LLVM_ABI unsigned getPointerAddressSpace() const

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

static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)

Type * getScalarType() const

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

bool isStructTy() const

True if this is an instance of StructType.

LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

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

bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const

Return true if it makes sense to take the size of this type.

LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY

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

static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)

bool isIntegerTy() const

True if this is an instance of IntegerType.

LLVM_ABI const fltSemantics & getFltSemantics() const

static LLVM_ABI UndefValue * get(Type *T)

Static factory methods - Return an 'undef' object of the specified type.

This function has undefined behavior.

A Use represents the edge between a Value definition and its users.

const Use & getOperandUse(unsigned i) const

LLVM_ABI bool isDroppable() const

A droppable user is a user for which uses can be dropped without affecting correctness and should be ...

LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)

Replace uses of one Value with another.

Value * getOperand(unsigned i) const

unsigned getNumOperands() 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 bool hasOneUser() const

Return true if there is exactly one user of this value.

bool hasOneUse() const

Return true if there is exactly one use of this value.

iterator_range< user_iterator > users()

bool hasUseList() const

Check if this Value has a use-list.

LLVM_ABI bool hasNUses(unsigned N) const

Return true if this Value has exactly N uses.

LLVM_ABI const Value * stripPointerCasts() const

Strip off pointer casts, all-zero GEPs and address space casts.

LLVM_ABI LLVMContext & getContext() const

All values hold a context through their type.

LLVM_ABI uint64_t getPointerDereferenceableBytes(const DataLayout &DL, bool &CanBeNull, bool &CanBeFreed) const

Returns the number of bytes known to be dereferenceable for the pointer value.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

LLVM_ABI void takeName(Value *V)

Transfer the name from V to this value.

Base class of all SIMD vector types.

ElementCount getElementCount() const

Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...

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

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

Value handle that is nullable, but tries to track the Value.

An efficient, type-erasing, non-owning reference to a callable.

Type * getIndexedType() const

const ParentTy * getParent() const

reverse_self_iterator getReverseIterator()

self_iterator getIterator()

This class implements an extremely fast bulk output stream that can only output to a stream.

A raw_ostream that writes to an std::string.

#define llvm_unreachable(msg)

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

Abstract Attribute helper functions.

@ C

The default llvm calling convention, compatible with C.

LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})

Look up the Function declaration of the intrinsic id in the Module M.

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

Matches a register negated by a G_SUB.

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

Matches a register not-ed by a G_XOR.

OneUse_match< SubPat > m_OneUse(const SubPat &SP)

cst_pred_ty< is_all_ones > m_AllOnes()

Match an integer or vector with all bits set.

class_match< PoisonValue > m_Poison()

Match an arbitrary poison constant.

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.

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::AShr > m_AShr(const LHS &L, const RHS &R)

auto m_PtrToIntOrAddr(const OpTy &Op)

Matches PtrToInt or PtrToAddr.

class_match< Constant > m_Constant()

Match an arbitrary Constant and ignore it.

OneOps_match< OpTy, Instruction::Freeze > m_Freeze(const OpTy &Op)

Matches FreezeInst.

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

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

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)

br_match m_UnconditionalBr(BasicBlock *&Succ)

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.

bind_ty< Instruction > m_Instruction(Instruction *&I)

Match an instruction, capturing it if we match.

specificval_ty m_Specific(const Value *V)

Match if we have a specific specified value.

DisjointOr_match< LHS, RHS > m_DisjointOr(const LHS &L, const RHS &R)

constantexpr_match m_ConstantExpr()

Match a constant expression or a constant that contains a constant expression.

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

cst_pred_ty< is_nonnegative > m_NonNegative()

Match an integer or vector of non-negative values.

class_match< ConstantInt > m_ConstantInt()

Match an arbitrary ConstantInt and ignore it.

IntrinsicID_match m_Intrinsic()

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

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

Matches SelectInst.

ExtractValue_match< Ind, Val_t > m_ExtractValue(const Val_t &V)

Match a single index ExtractValue instruction.

match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)

Combine two pattern matchers matching L && R.

BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)

NNegZExt_match< OpTy > m_NNegZExt(const OpTy &Op)

auto m_LogicalOr()

Matches L || R where L and R are arbitrary values.

Splat_match< T > m_ConstantSplat(const T &SubPattern)

Match a constant splat. TODO: Extend this to non-constant splats.

TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)

Matches ShuffleVectorInst independently of mask value.

ThreeOps_match< decltype(m_Value()), LHS, RHS, Instruction::Select, true > m_c_Select(const LHS &L, const RHS &R)

Match Select(C, LHS, RHS) or Select(C, RHS, LHS)

SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)

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

Matches ZExt.

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

brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)

match_immconstant_ty m_ImmConstant()

Match an arbitrary immediate Constant and ignore it.

match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)

Match either "add" or "or disjoint".

CastInst_match< OpTy, UIToFPInst > m_UIToFP(const OpTy &Op)

CastOperator_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)

Matches BitCast.

match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)

Match either "sext" or "zext nneg".

BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)

match_combine_or< OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap >, DisjointOr_match< LHS, RHS > > m_NSWAddLike(const LHS &L, const RHS &R)

Match either "add nsw" or "or disjoint".

class_match< Value > m_Value()

Match an arbitrary value and ignore it.

AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R)

Matches a BinaryOperator with LHS and RHS in either order.

CastInst_match< OpTy, SIToFPInst > m_SIToFP(const OpTy &Op)

BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)

CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)

match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)

BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)

Matches shift operations.

BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)

cstfp_pred_ty< is_non_zero_fp > m_NonZeroFP()

Match a floating-point non-zero.

m_Intrinsic_Ty< Opnd0 >::Ty m_VecReverse(const Opnd0 &Op0)

auto m_LogicalAnd()

Matches L && R where L and R are arbitrary values.

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)

auto m_Undef()

Match an arbitrary undef constant.

BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)

CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)

Matches SExt.

is_zero m_Zero()

Match any null constant or a vector with all elements equal to 0.

match_combine_or< OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap >, DisjointOr_match< LHS, RHS > > m_NUWAddLike(const LHS &L, const RHS &R)

Match either "add nuw" or "or disjoint".

m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_VectorInsert(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)

BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(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.

initializer< Ty > init(const Ty &Val)

friend class Instruction

Iterator for Instructions in a `BasicBlock.

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

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

detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)

zip iterator for two or more iteratable types.

FunctionAddr VTableAddr Value

void stable_sort(R &&Range)

LLVM_ABI void initializeInstructionCombiningPassPass(PassRegistry &)

LLVM_ABI unsigned removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB)

Remove all instructions from a basic block other than its terminator and any present EH pad instructi...

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 * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, GEPNoWrapFlags NW, const SimplifyQuery &Q)

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

LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)

If this is a call to an allocation function that initializes memory to a fixed value,...

bool succ_empty(const Instruction *I)

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

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

LLVM_ABI FunctionPass * createInstructionCombiningPass()

Definition InstructionCombining.cpp:6173

LLVM_ABI void findDbgValues(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)

Finds the dbg.values describing a value.

auto enumerate(FirstRange &&First, RestRanges &&...Rest)

Given two or more input ranges, returns a new range whose values are tuples (A, B,...

decltype(auto) dyn_cast(const From &Val)

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

LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)

Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...

auto successors(const MachineBasicBlock *BB)

LLVM_ABI Constant * ConstantFoldInstruction(const Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)

ConstantFoldInstruction - Try to constant fold the specified instruction.

LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)

Return true if this is a call to an allocation function that does not have side effects that we are r...

LLVM_ABI std::optional< StringRef > getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI)

If a function is part of an allocation family (e.g.

OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy

Provide the ModuleAnalysisManager to Function proxy.

LLVM_ABI Value * lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL, const TargetLibraryInfo *TLI, bool MustSucceed)

Try to turn a call to @llvm.objectsize into an integer value of the given Type.

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

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

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

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

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

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

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

gep_type_iterator gep_type_end(const User *GEP)

LLVM_ABI Value * getSplatValue(const Value *V)

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

LLVM_ABI Value * getReallocatedOperand(const CallBase *CB)

If this is a call to a realloc function, return the reallocated operand.

APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM)

Equivalent of C standard library function.

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 handleUnreachableTerminator(Instruction *I, SmallVectorImpl< Value * > &PoisonedValues)

If a terminator in an unreachable basic block has an operand of type Instruction, transform it into p...

int countr_zero(T Val)

Count number of 0's from the least significant bit to the most stopping at the first 1.

LLVM_ABI bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)

Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...

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

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

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

ConstantFoldConstant - Fold the constant using the specified DataLayout.

auto dyn_cast_or_null(const Y &Val)

constexpr bool has_single_bit(T Value) noexcept

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 isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)

Return true if the result produced by the instruction is not used, and the instruction will return.

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 Value * emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)

Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...

constexpr unsigned MaxAnalysisRecursionDepth

auto reverse(ContainerTy &&C)

bool isModSet(const ModRefInfo MRI)

FPClassTest

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

LLVM_ABI bool LowerDbgDeclare(Function &F)

Lowers dbg.declare records into appropriate set of dbg.value records.

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 raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

generic_gep_type_iterator<> gep_type_iterator

LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, StoreInst *SI, DIBuilder &Builder)

Inserts a dbg.value record before a store to an alloca'd value that has an associated dbg....

LLVM_ABI void salvageDebugInfoForDbgValues(Instruction &I, ArrayRef< DbgVariableRecord * > DPInsns)

Implementation of salvageDebugInfo, applying only to instructions in Insns, rather than all debug use...

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 bool canCreateUndefOrPoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)

canCreateUndefOrPoison returns true if Op can create undef or poison from non-undef & non-poison oper...

LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)

See if the given exception handling personality function is one that we understand.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

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 Value * simplifyExtractValueInst(Value *Agg, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)

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

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

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

LLVM_ABI bool replaceAllDbgUsesWith(Instruction &From, Value &To, Instruction &DomPoint, DominatorTree &DT)

Point debug users of From to To or salvage them.

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

auto drop_end(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the last N elements excluded.

ModRefInfo

Flags indicating whether a memory access modifies or references memory.

@ Ref

The access may reference the value stored in memory.

@ ModRef

The access may reference and may modify the value stored in memory.

@ Mod

The access may modify the value stored in memory.

@ NoModRef

The access neither references nor modifies the value stored in memory.

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

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

@ Sub

Subtraction of integers.

DWARFExpression::Operation Op

bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I, bool IgnoreUBImplyingAttrs=true)

Don't use information from its non-constant operands.

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.

ArrayRef(const T &OneElt) -> ArrayRef< T >

LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)

If this if a call to a free function, return the freed operand.

constexpr unsigned BitWidth

LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)

Return true if this function can prove that the instruction I will always transfer execution to one o...

LLVM_ABI Constant * getLosslessInvCast(Constant *C, Type *InvCastTo, unsigned CastOp, const DataLayout &DL, PreservedCastFlags *Flags=nullptr)

Try to cast C to InvC losslessly, satisfying CastOp(InvC) equals C, or CastOp(InvC) is a refined valu...

auto count_if(R &&Range, UnaryPredicate P)

Wrapper function around std::count_if to count the number of times an element satisfying a given pred...

decltype(auto) cast(const From &Val)

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

gep_type_iterator gep_type_begin(const User *GEP)

auto predecessors(const MachineBasicBlock *BB)

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

Returns true if Element is found in Range.

cl::opt< bool > ProfcheckDisableMetadataFixes("profcheck-disable-metadata-fixes", cl::Hidden, cl::init(false), cl::desc("Disable metadata propagation fixes discovered through Issue #147390"))

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

bool equal(L &&LRange, R &&RRange)

Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.

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

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

AAResults AliasAnalysis

Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.

static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)

Filter the DbgRecord range to DbgVariableRecord types only and downcast.

LLVM_ABI void initializeInstCombine(PassRegistry &)

Initialize all passes linked into the InstCombine library.

Definition InstructionCombining.cpp:6169

LLVM_ABI void findDbgUsers(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)

Finds the debug info records describing a value.

LLVM_ABI Constant * ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2)

bool isRefSet(const ModRefInfo MRI)

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 void reportFatalUsageError(Error Err)

Report a fatal error that does not indicate a bug in LLVM.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

unsigned countMinLeadingOnes() const

Returns the minimum number of leading one bits.

unsigned getBitWidth() const

Get the bit width of this value.

unsigned countMinLeadingZeros() const

Returns the minimum number of leading zero bits.

A CRTP mix-in to automatically provide informational APIs needed for passes.

SimplifyQuery getWithInstruction(const Instruction *I) const