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

1

2

3

4

5

6

7

8

9

10

11

12

26

27using namespace llvm;

30

31#define DEBUG_TYPE "iv-descriptors"

32

35 for (const Use &Use : I->operands())

37 return false;

38 return true;

39}

40

42 switch (Kind) {

43 default:

44 break;

61 return true;

62 }

63 return false;

64}

65

69

70

71

72

73

77 if (!Phi->hasOneUse())

78 return Phi;

79

80 const APInt *M = nullptr;

82

83

84

86 int32_t Bits = (*M + 1).exactLogBase2();

87 if (Bits > 0) {

91 return J;

92 }

93 }

94 return Phi;

95}

96

97

98

103 bool IsSigned = false;

104 const DataLayout &DL = Exit->getDataLayout();

105 uint64_t MaxBitWidth = DL.getTypeSizeInBits(Exit->getType());

106

107 if (DB) {

108

109

110

111

112

113 auto Mask = DB->getDemandedBits(Exit);

114 MaxBitWidth = Mask.getBitWidth() - Mask.countl_zero();

115 }

116

117 if (MaxBitWidth == DL.getTypeSizeInBits(Exit->getType()) && AC && DT) {

118

119

120

122 auto NumTypeBits = DL.getTypeSizeInBits(Exit->getType());

123 MaxBitWidth = NumTypeBits - NumSignBits;

125 if (!Bits.isNonNegative()) {

126

127

128

129 IsSigned = true;

130

131

132 ++MaxBitWidth;

133 }

134 }

136

137 return std::make_pair(Type::getIntNTy(Exit->getContext(), MaxBitWidth),

138 IsSigned);

139}

140

141

142

143

144

146 Type *RecurrenceType,

148 unsigned &MinWidthCastToRecurTy) {

149

153 MinWidthCastToRecurTy = -1U;

154

155 while (!Worklist.empty()) {

159 if (Cast->getSrcTy() == RecurrenceType) {

160

161

162

164 continue;

165 }

166 if (Cast->getDestTy() == RecurrenceType) {

167

168

169

170

171 MinWidthCastToRecurTy = std::min(

172 MinWidthCastToRecurTy, Cast->getSrcTy()->getScalarSizeInBits());

173 continue;

174 }

175 }

176

177

182 }

183}

184

185

186

189

191 return false;

192

193 if (Kind == RecurKind::FAdd && Exit->getOpcode() != Instruction::FAdd)

194 return false;

195

198 return false;

199

200

201 if (Exit != ExactFPMathInst || Exit->hasNUsesOrMore(3))

202 return false;

203

204

205

206 auto *Op0 = Exit->getOperand(0);

207 auto *Op1 = Exit->getOperand(1);

209 return false;

211 return false;

212

213 LLVM_DEBUG(dbgs() << "LV: Found an ordered reduction: Phi: " << *Phi

214 << ", ExitInst: " << *Exit << "\n");

215

216 return true;

217}

218

219

220

221

225 if (!Latch)

226 return false;

227

228 assert(Phi->getNumIncomingValues() == 2 && "phi must have 2 incoming values");

229 Value *Inc = Phi->getIncomingValueForBlock(Latch);

230 if (Phi->hasOneUse() || !Inc->hasOneUse() ||

232 return false;

233

235 bool IsMinMax = [&]() {

236 switch (Kind) {

245 default:

247 }

248 }();

249 if (!IsMinMax)

250 return false;

251

252 if (A == B || (A != Phi && B != Phi))

253 return false;

254

257 RedDes =

259 FastMathFlags(), nullptr, Phi->getType(),

260 false, false, CastInsts,

261 -1U, true);

262 return true;

263}

264

269 if (Phi->getNumIncomingValues() != 2)

270 return false;

271

272

273 if (Phi->getParent() != TheLoop->getHeader())

274 return false;

275

276

278 RedDes))

279 return true;

280

281

282

284

285

286

287

288

290

291

292

293

295

296

297 bool FoundReduxOp = false;

298

299

300

301

302

303 bool FoundStartPHI = false;

304

305

306

307

308 unsigned NumCmpSelectPatternInst = 0;

309 InstDesc ReduxDesc(false, nullptr);

310

311

312 Type *RecurrenceType = Phi->getType();

314 unsigned MinWidthCastToRecurrenceType;

316 bool IsSigned = false;

317

320

321

322

323

324

325

326

330 return false;

333 return false;

335 Start = lookThroughAnd(Phi, RecurrenceType, VisitedInsts, CastInsts);

336 } else {

337

338 return false;

339 }

340

342 VisitedInsts.insert(Start);

343

344

345

347

348

349

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371 while (!Worklist.empty()) {

373

374

375

377 if (!SE) {

378 LLVM_DEBUG(dbgs() << "Store instructions are not processed without "

379 << "Scalar Evolution Analysis\n");

380 return false;

381 }

382

383 const SCEV *PtrScev = SE->getSCEV(SI->getPointerOperand());

384

386 const SCEV *OtherScev =

388

389 if (OtherScev != PtrScev) {

390 LLVM_DEBUG(dbgs() << "Storing reduction value to different addresses "

391 << "inside the loop: " << *SI->getPointerOperand()

392 << " and "

394 return false;

395 }

396 }

397

398

400 LLVM_DEBUG(dbgs() << "Storing reduction value to non-uniform address "

401 << "inside the loop: " << *SI->getPointerOperand()

402 << '\n');

403 return false;

404 }

405

406

408 continue;

409 }

410

411

412

413

415 return false;

416

418

419

420 if (Cur != Phi && IsAPhi && Cur->getParent() == Phi->getParent())

421 return false;

422

423

424

428 return false;

429

430

431

432

433 if (Cur != Start) {

434 ReduxDesc =

435 isRecurrenceInstr(TheLoop, Phi, Cur, Kind, ReduxDesc, FuncFMF, SE);

436 ExactFPMathInst = ExactFPMathInst == nullptr

438 : ExactFPMathInst;

440 return false;

441

445

446

447

448

450 CurFMF |= FCmp->getFastMathFlags();

451 }

452 FMF &= CurFMF;

453 }

454

455

456

459 }

460

462

463

464

467 return false;

468

469

472 return false;

473

474

475 if (IsAPhi && Cur != Phi && areAllUsesIn(Cur, VisitedInsts))

476 return false;

477

479 ++NumCmpSelectPatternInst;

481 ++NumCmpSelectPatternInst;

483 ++NumCmpSelectPatternInst;

484

485

486 FoundReduxOp |= !IsAPhi && Cur != Start;

487

488

489

490

495

496

497

500 return false;

501

502

504 if (!TheLoop->contains(Parent)) {

505

506

507 if (ExitInstruction == Cur)

508 continue;

509

510

511

512

513

514 if (ExitInstruction != nullptr || Cur == Phi)

515 return false;

516

517

518

519

521 return false;

522

523 ExitInstruction = Cur;

524 continue;

525 }

526

527

528

529

530 InstDesc IgnoredVal(false, nullptr);

531 if (VisitedInsts.insert(UI).second) {

534 } else {

536 if (SI && SI->getPointerOperand() == Cur) {

537

538

539 return false;

540 }

542 }

548 .isRecurrence() &&

550 return false;

551

552

553 if (UI == Phi)

554 FoundStartPHI = true;

555 }

558 }

559

560

561

562

564 NumCmpSelectPatternInst != 0)

565 return false;

566

568 return false;

569

571

572

573

575 LLVM_DEBUG(dbgs() << "Not a final reduction value stored: "

577 return false;

578 }

579

580

581

582 if (ExitInstruction &&

584 LLVM_DEBUG(dbgs() << "Last store Instruction of reduction value does not "

585 "store last calculated value of the reduction: "

587 return false;

588 }

589

590

591

592 if (!ExitInstruction)

594 }

595

596 if (!FoundStartPHI || !FoundReduxOp || !ExitInstruction)

597 return false;

598

599 const bool IsOrdered =

601

602 if (Start != Phi) {

603

604

605

606

607

608

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627 Type *ComputedType;

628 std::tie(ComputedType, IsSigned) =

630 if (ComputedType != RecurrenceType)

631 return false;

632 }

633

634

635

636

637

638

639

640

641

642

643

644

645

646

647 collectCastInstrs(TheLoop, ExitInstruction, RecurrenceType, CastInsts,

648 MinWidthCastToRecurrenceType);

649

650

651

652

653

654

655

656

658 FMF, ExactFPMathInst, RecurrenceType, IsSigned,

659 IsOrdered, CastInsts, MinWidthCastToRecurrenceType);

660 RedDes = RD;

661

662 return true;

663}

664

665

666

667

668

669

670

671

672

673

674

675

676

677

678

679

680

681

682

683

684

685

689

690

694 }

695

698

700 Value *NonPhi = nullptr;

701

703 NonPhi = SI->getFalseValue();

705 NonPhi = SI->getTrueValue();

706 else

708

709

710

711

714

716}

717

718

719

720

721

722

723

724

725

726

727

728

729

730

731

732

733

734

735

736

737

738

739

740

741

742

743

744

745

746

747

752

753

754

755

758

759

760

761

762

763 Value *NonRdxPhi = nullptr;

769

770

771

772 auto GetRecurKind = [&](Value *V) -> std::optional {

773 Type *Ty = V->getType();

775 return std::nullopt;

776

777 auto *AR = SE.getSCEV(V);

778 const SCEV *Step;

781 return std::nullopt;

782

785 return std::nullopt;

786

787

788

789

790

791

792

793

794

795 auto CheckRange = [&](bool IsSigned) {

798 unsigned NumBits = Ty->getIntegerBitWidth();

799 ConstantRange ValidRange = ConstantRange::getEmpty(NumBits);

804 } else {

805 if (IsSigned)

806 ValidRange =

809 else

812 }

813

816 : "FindFirstIV")

817 << " valid range is " << ValidRange

818 << ", and the range of " << *AR << " is " << IVRange

819 << "\n");

820

821

822

823 return ValidRange.contains(IVRange);

824 };

826 if (CheckRange(true))

828 if (CheckRange(false))

830 return std::nullopt;

831 }

833 "Kind must either be a FindLastIV or FindFirstIV");

834

835 if (CheckRange(true))

837 if (CheckRange(false))

839 return std::nullopt;

840 };

841

842 if (auto RK = GetRecurKind(NonRdxPhi))

844

846}

847

852 "Expected a cmp or select or call instruction");

855

856

857

861 }

862

863

867

868

893

895}

896

897

898

899

900

901

902

903

904

905

908 Value *TrueVal, *FalseVal;

909

913

914

915

919

922 if (!I1 || !I1->isBinaryOp())

924

925 Value *Op1, *Op2;

928 I1->isFast()) ||

934

937 if (!IPhi || IPhi != FalseVal)

939

941}

942

947 switch (I->getOpcode()) {

948 default:

950 case Instruction::PHI:

952 case Instruction::Sub:

955 case Instruction::Add:

958 case Instruction::Mul:

960 case Instruction::And:

962 case Instruction::Or:

964 case Instruction::Xor:

966 case Instruction::FDiv:

967 case Instruction::FMul:

969 I->hasAllowReassoc() ? nullptr : I);

970 case Instruction::FSub:

971 case Instruction::FAdd:

973 I->hasAllowReassoc() ? nullptr : I);

974 case Instruction::Select:

981 [[fallthrough]];

982 case Instruction::FCmp:

983 case Instruction::ICmp:

984 case Instruction::Call:

987 auto HasRequiredFMF = [&]() {

989 return true;

991 return true;

992

993

994

1000 };

1007 if (HasRequiredFMF())

1008 return Res;

1009

1010

1011

1014 "unexpected recurrence kind for maxnum");

1016 }

1019 "unexpected recurrence kind for minnum");

1021 }

1023 }

1026 I->hasAllowReassoc() ? nullptr : I);

1028 }

1029}

1030

1033 unsigned MaxNumUses) {

1034 unsigned NumUses = 0;

1035 for (const Use &U : I->operands()) {

1037 ++NumUses;

1038 if (NumUses > MaxNumUses)

1039 return true;

1040 }

1041

1042 return false;

1043}

1044

1051 Function &F = *Header->getParent();

1054 F.getFnAttribute("no-nans-fp-math").getValueAsBool());

1055 FMF.setNoSignedZeros(

1056 F.getFnAttribute("no-signed-zeros-fp-math").getValueAsBool());

1057

1059 SE)) {

1060 LLVM_DEBUG(dbgs() << "Found an ADD reduction PHI." << *Phi << "\n");

1061 return true;

1062 }

1064 SE)) {

1065 LLVM_DEBUG(dbgs() << "Found a SUB reduction PHI." << *Phi << "\n");

1066 return true;

1067 }

1069 DB, AC, DT, SE)) {

1070 LLVM_DEBUG(dbgs() << "Found a chained ADD-SUB reduction PHI." << *Phi

1071 << "\n");

1072 return true;

1073 }

1075 SE)) {

1076 LLVM_DEBUG(dbgs() << "Found a MUL reduction PHI." << *Phi << "\n");

1077 return true;

1078 }

1080 SE)) {

1081 LLVM_DEBUG(dbgs() << "Found an OR reduction PHI." << *Phi << "\n");

1082 return true;

1083 }

1085 SE)) {

1086 LLVM_DEBUG(dbgs() << "Found an AND reduction PHI." << *Phi << "\n");

1087 return true;

1088 }

1090 SE)) {

1091 LLVM_DEBUG(dbgs() << "Found a XOR reduction PHI." << *Phi << "\n");

1092 return true;

1093 }

1095 SE)) {

1096 LLVM_DEBUG(dbgs() << "Found a SMAX reduction PHI." << *Phi << "\n");

1097 return true;

1098 }

1100 SE)) {

1101 LLVM_DEBUG(dbgs() << "Found a SMIN reduction PHI." << *Phi << "\n");

1102 return true;

1103 }

1105 SE)) {

1106 LLVM_DEBUG(dbgs() << "Found a UMAX reduction PHI." << *Phi << "\n");

1107 return true;

1108 }

1110 SE)) {

1111 LLVM_DEBUG(dbgs() << "Found a UMIN reduction PHI." << *Phi << "\n");

1112 return true;

1113 }

1115 SE)) {

1116 LLVM_DEBUG(dbgs() << "Found a conditional select reduction PHI." << *Phi

1117 << "\n");

1118 return true;

1119 }

1121 AC, DT, SE)) {

1122 LLVM_DEBUG(dbgs() << "Found a FindLastIV reduction PHI." << *Phi << "\n");

1123 return true;

1124 }

1126 AC, DT, SE)) {

1127 LLVM_DEBUG(dbgs() << "Found a FindFirstIV reduction PHI." << *Phi << "\n");

1128 return true;

1129 }

1131 SE)) {

1132 LLVM_DEBUG(dbgs() << "Found an FMult reduction PHI." << *Phi << "\n");

1133 return true;

1134 }

1136 SE)) {

1137 LLVM_DEBUG(dbgs() << "Found an FAdd reduction PHI." << *Phi << "\n");

1138 return true;

1139 }

1141 SE)) {

1142 LLVM_DEBUG(dbgs() << "Found a float MAX reduction PHI." << *Phi << "\n");

1143 return true;

1144 }

1146 SE)) {

1147 LLVM_DEBUG(dbgs() << "Found a float MIN reduction PHI." << *Phi << "\n");

1148 return true;

1149 }

1151 SE)) {

1152 LLVM_DEBUG(dbgs() << "Found an FMulAdd reduction PHI." << *Phi << "\n");

1153 return true;

1154 }

1156 SE)) {

1157 LLVM_DEBUG(dbgs() << "Found a float MAXIMUM reduction PHI." << *Phi << "\n");

1158 return true;

1159 }

1161 SE)) {

1162 LLVM_DEBUG(dbgs() << "Found a float MINIMUM reduction PHI." << *Phi << "\n");

1163 return true;

1164 }

1166 DT, SE)) {

1167 LLVM_DEBUG(dbgs() << "Found a float MAXIMUMNUM reduction PHI." << *Phi

1168 << "\n");

1169 return true;

1170 }

1172 DT, SE)) {

1173 LLVM_DEBUG(dbgs() << "Found a float MINIMUMNUM reduction PHI." << *Phi

1174 << "\n");

1175 return true;

1176 }

1177

1178

1179 return false;

1180}

1181

1184

1185

1186 if (Phi->getParent() != TheLoop->getHeader() ||

1187 Phi->getNumIncomingValues() != 2)

1188 return false;

1189

1190

1191

1194 if (!Preheader || !Latch)

1195 return false;

1196

1197

1198 if (Phi->getBasicBlockIndex(Preheader) < 0 ||

1199 Phi->getBasicBlockIndex(Latch) < 0)

1200 return false;

1201

1202

1203

1205

1206

1207

1208

1209

1212 if (PrevPhi->getParent() != Phi->getParent())

1213 return false;

1214 if (!SeenPhis.insert(PrevPhi).second)

1215 return false;

1217 }

1218

1220 return false;

1221

1222

1223

1224

1225

1226

1227

1229 BasicBlock *PhiBB = Phi->getParent();

1231 auto TryToPushSinkCandidate = [&](Instruction *SinkCandidate) {

1232

1233 if (Previous == SinkCandidate)

1234 return false;

1235

1236 if (!Seen.insert(SinkCandidate).second)

1237 return true;

1239 SinkCandidate))

1240 return true;

1241

1242 if (SinkCandidate->getParent() != PhiBB ||

1243 SinkCandidate->mayHaveSideEffects() ||

1244 SinkCandidate->mayReadFromMemory() || SinkCandidate->isTerminator())

1245 return false;

1246

1247

1248

1250 return true;

1251

1252

1253 WorkList.push_back(SinkCandidate);

1254 return true;

1255 };

1256

1258

1259 while (!WorkList.empty()) {

1263 return false;

1264 }

1265 }

1266

1267 return true;

1268}

1269

1271 switch (Kind) {

1273 return Instruction::Sub;

1276 return Instruction::Add;

1278 return Instruction::Mul;

1280 return Instruction::Or;

1282 return Instruction::And;

1284 return Instruction::Xor;

1286 return Instruction::FMul;

1289 return Instruction::FAdd;

1294 return Instruction::ICmp;

1301 return Instruction::FCmp;

1307

1308

1309 default:

1311 }

1312}

1313

1318

1319

1320

1321

1322

1323

1324

1325

1326

1327

1328

1329

1330

1331

1332

1333

1334 unsigned ExpectedUses = 1;

1335 if (IsMinMax)

1336 ExpectedUses = 2;

1337

1339 for (auto *User : Cur->users()) {

1342 continue;

1343 if (IsMinMax) {

1344

1345

1347 return UI;

1348 continue;

1349 }

1350 return UI;

1351 }

1352 return nullptr;

1353 };

1354 auto isCorrectOpcode = [&](Instruction *Cur) {

1355 if (IsMinMax) {

1356 Value *LHS, *RHS;

1359 }

1360

1362 return true;

1363

1364 if (Cur->getOpcode() == Instruction::Sub &&

1366 return true;

1367

1368 return Cur->getOpcode() == getOpcode();

1369 };

1370

1371

1372 unsigned ExtraPhiUses = 0;

1375 if (ExitPhi->getNumIncomingValues() != 2)

1376 return {};

1377

1380

1382 if (Inc0 == Phi)

1383 Chain = Inc1;

1384 else if (Inc1 == Phi)

1385 Chain = Inc0;

1386 else

1387 return {};

1388

1389 RdxInstr = Chain;

1390 ExtraPhiUses = 1;

1391 }

1392

1393

1394

1395

1396

1397 if (!isCorrectOpcode(RdxInstr) || !LoopExitInstr->hasNUses(2))

1398 return {};

1399

1400

1401

1402 if (!Phi->hasNUses(ExpectedUses + ExtraPhiUses))

1403 return {};

1404

1405 Instruction *Cur = getNextInstruction(Phi);

1406

1407

1408

1409 while (Cur != RdxInstr) {

1410 if (!Cur || !isCorrectOpcode(Cur) || !Cur->hasNUses(ExpectedUses))

1411 return {};

1412

1413 ReductionOperations.push_back(Cur);

1414 Cur = getNextInstruction(Cur);

1415 }

1416

1417 ReductionOperations.push_back(Cur);

1418 return ReductionOperations;

1419}

1420

1424 : StartValue(Start), IK(K), Step(Step), InductionBinOp(BOp) {

1425 assert(IK != IK_NoInduction && "Not an induction");

1426

1427

1428

1429 assert(StartValue && "StartValue is null");

1430 assert((IK != IK_PtrInduction || StartValue->getType()->isPointerTy()) &&

1431 "StartValue is not a pointer for pointer induction");

1432 assert((IK != IK_IntInduction || StartValue->getType()->isIntegerTy()) &&

1433 "StartValue is not an integer for integer induction");

1434

1435

1436 assert((!getConstIntStepValue() || !getConstIntStepValue()->isZero()) &&

1437 "Step value is zero");

1438

1440 "StepValue is not an integer");

1441

1443 "StepValue is not FP for FpInduction");

1444 assert((IK != IK_FpInduction ||

1445 (InductionBinOp &&

1446 (InductionBinOp->getOpcode() == Instruction::FAdd ||

1447 InductionBinOp->getOpcode() == Instruction::FSub))) &&

1448 "Binary opcode should be specified for FP induction");

1449

1450 if (Casts)

1452}

1453

1457 return nullptr;

1458}

1459

1463

1464

1465 assert(Phi->getType()->isFloatingPointTy() && "Unexpected Phi type");

1466

1467 if (TheLoop->getHeader() != Phi->getParent())

1468 return false;

1469

1470

1471

1472 if (Phi->getNumIncomingValues() != 2)

1473 return false;

1474 Value *BEValue = nullptr, *StartValue = nullptr;

1475 if (TheLoop->contains(Phi->getIncomingBlock(0))) {

1476 BEValue = Phi->getIncomingValue(0);

1477 StartValue = Phi->getIncomingValue(1);

1478 } else {

1479 assert(TheLoop->contains(Phi->getIncomingBlock(1)) &&

1480 "Unexpected Phi node in the loop");

1481 BEValue = Phi->getIncomingValue(1);

1482 StartValue = Phi->getIncomingValue(0);

1483 }

1484

1486 if (!BOp)

1487 return false;

1488

1489 Value *Addend = nullptr;

1490 if (BOp->getOpcode() == Instruction::FAdd) {

1495 } else if (BOp->getOpcode() == Instruction::FSub)

1498

1499 if (!Addend)

1500 return false;

1501

1502

1505 return false;

1506

1507

1510 return true;

1511}

1512

1513

1514

1515

1516

1517

1518

1519

1520

1521

1522

1523

1524

1525

1526

1527

1528

1529

1530

1531

1532

1533

1534

1535

1536

1537

1538

1539

1540

1541

1542

1543

1544

1549

1550 assert(CastInsts.empty() && "CastInsts is expected to be empty.");

1552 assert(PSE.getSCEV(PN) == AR && "Unexpected phi node SCEV expression");

1554

1555

1556

1557

1558

1559

1560

1561

1562

1565 if (!BinOp)

1566 return nullptr;

1569 Value *Def = nullptr;

1570 if (L->isLoopInvariant(Op0))

1571 Def = Op1;

1572 else if (L->isLoopInvariant(Op1))

1573 Def = Op0;

1574 return Def;

1575 };

1576

1577

1578

1579 BasicBlock *Latch = L->getLoopLatch();

1580 if (!Latch)

1581 return false;

1582 Value *Val = PN->getIncomingValueForBlock(Latch);

1583 if (!Val)

1584 return false;

1585

1586

1587

1588

1589

1590 bool InCastSequence = false;

1592 while (Val != PN) {

1593

1594

1595 if (!Inst || !L->contains(Inst)) {

1596 return false;

1597 }

1600 InCastSequence = true;

1601 if (InCastSequence) {

1602

1603

1604 if (!CastInsts.empty())

1605 if (!Inst->hasOneUse())

1606 return false;

1608 }

1610 if (!Val)

1611 return false;

1613 }

1614

1615 return InCastSequence;

1616}

1617

1621 Type *PhiTy = Phi->getType();

1622

1623

1624

1625

1626

1629 return false;

1630

1633

1636

1637

1638 if (Assume && !AR)

1640

1641 if (!AR) {

1642 LLVM_DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n");

1643 return false;

1644 }

1645

1646

1648

1649

1650

1651

1652

1653 if (PhiScev != AR && SymbolicPhi) {

1657 }

1658

1660}

1661

1666 Type *PhiTy = Phi->getType();

1667

1669 return false;

1670

1671

1672 const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi);

1673 const SCEV *Step;

1674

1675

1676

1677

1681 dbgs() << "LV: PHI is not a poly recurrence for requested loop.\n");

1682 return false;

1683 }

1684

1685

1686

1687

1689 "Invalid Phi node, not present in loop header");

1690

1691 Value *StartValue =

1693

1695 if (!Latch)

1696 return false;

1697

1702 CastsToIgnore);

1703 return true;

1704 }

1705

1707

1708

1710 return true;

1711}

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

AMDGPU Register Bank Select

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

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

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

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

static bool getCastsForInductionPHI(PredicatedScalarEvolution &PSE, const SCEVUnknown *PhiScev, const SCEVAddRecExpr *AR, SmallVectorImpl< Instruction * > &CastInsts)

This function is called when we suspect that the update-chain of a phi node (whose symbolic SCEV expr...

Definition IVDescriptors.cpp:1545

static bool isMinMaxReductionPhiWithUsersOutsideReductionChain(PHINode *Phi, RecurKind Kind, Loop *TheLoop, RecurrenceDescriptor &RedDes)

Returns true if Phi is a min/max reduction matching Kind where Phi is used outside the reduction chai...

Definition IVDescriptors.cpp:222

static void collectCastInstrs(Loop *TheLoop, Instruction *Exit, Type *RecurrenceType, SmallPtrSetImpl< Instruction * > &Casts, unsigned &MinWidthCastToRecurTy)

Collect cast instructions that can be ignored in the vectorizer's cost model, given a reduction exit ...

Definition IVDescriptors.cpp:145

static bool checkOrderedReduction(RecurKind Kind, Instruction *ExactFPMathInst, Instruction *Exit, PHINode *Phi)

Definition IVDescriptors.cpp:187

static Instruction * lookThroughAnd(PHINode *Phi, Type *&RT, SmallPtrSetImpl< Instruction * > &Visited, SmallPtrSetImpl< Instruction * > &CI)

Determines if Phi may have been type-promoted.

Definition IVDescriptors.cpp:74

static std::pair< Type *, bool > computeRecurrenceType(Instruction *Exit, DemandedBits *DB, AssumptionCache *AC, DominatorTree *DT)

Compute the minimal bit width needed to represent a reduction whose exit instruction is given by Exit...

Definition IVDescriptors.cpp:99

static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)

Class for arbitrary precision integers.

static APInt getMaxValue(unsigned numBits)

Gets maximum unsigned value of APInt for specific bit width.

static APInt getSignedMaxValue(unsigned numBits)

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

static APInt getMinValue(unsigned numBits)

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

static APInt getSignedMinValue(unsigned numBits)

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

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

LLVM Basic Block Representation.

BinaryOps getOpcode() const

This is the shared class of boolean and integer constants.

This class represents a range of values.

LLVM_ABI bool contains(const APInt &Val) const

Return true if the specified value is in the set.

static ConstantRange getNonEmpty(APInt Lower, APInt Upper)

Create non-empty constant range with the given bounds.

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

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

LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const

Return true if the (end of the) basic block BB dominates the use U.

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

bool noSignedZeros() const

void setNoNaNs(bool B=true)

static FastMathFlags getFast()

@ IK_FpInduction

Floating point induction variable.

@ IK_PtrInduction

Pointer induction var. Step = C.

@ IK_IntInduction

Integer induction variable. Step = C.

static LLVM_ABI bool isInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, InductionDescriptor &D, const SCEV *Expr=nullptr, SmallVectorImpl< Instruction * > *CastsToIgnore=nullptr)

Returns true if Phi is an induction in the loop L.

Definition IVDescriptors.cpp:1662

static LLVM_ABI bool isFPInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, InductionDescriptor &D)

Returns true if Phi is a floating point induction in the loop L.

Definition IVDescriptors.cpp:1460

InductionDescriptor()=default

Default constructor - creates an invalid induction.

LLVM_ABI ConstantInt * getConstIntStepValue() const

Definition IVDescriptors.cpp:1454

LLVM_ABI bool isCommutative() const LLVM_READONLY

Return true if the instruction is commutative:

LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY

Convenience function for getting all the fast-math flags, which must be an operator which supports th...

static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)

This static method is the primary way of constructing an IntegerType.

bool contains(const LoopT *L) const

Return true if the specified loop is contained within in this loop.

BlockT * getLoopLatch() const

If there is a single latch block for this loop, return it.

BlockT * getHeader() const

BlockT * getLoopPreheader() const

If there is a preheader for this loop, return it.

Represents a single loop in the control flow graph.

bool isLoopInvariant(const Value *V) const

Return true if the specified value is loop invariant.

An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...

ScalarEvolution * getSE() const

Returns the ScalarEvolution analysis used.

LLVM_ABI bool areAddRecsEqualWithPreds(const SCEVAddRecExpr *AR1, const SCEVAddRecExpr *AR2) const

Check if AR1 and AR2 are equal, while taking into account Equal predicates in Preds.

LLVM_ABI const SCEVAddRecExpr * getAsAddRec(Value *V)

Attempts to produce an AddRecExpr for V by adding additional SCEV predicates.

LLVM_ABI const SCEV * getSCEV(Value *V)

Returns the SCEV expression of V, in the context of the current SCEV predicate.

This POD struct holds information about a potential recurrence operation.

RecurKind getRecKind() const

Instruction * getPatternInst() const

bool isRecurrence() const

Instruction * getExactFPMathInst() const

The RecurrenceDescriptor is used to identify recurrences variables in a loop.

static bool isFPMinMaxRecurrenceKind(RecurKind Kind)

Returns true if the recurrence kind is a floating-point min/max kind.

static bool isFMulAddIntrinsic(Instruction *I)

Returns true if the instruction is a call to the llvm.fmuladd intrinsic.

static bool isFindFirstIVRecurrenceKind(RecurKind Kind)

Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...

static LLVM_ABI bool isFixedOrderRecurrence(PHINode *Phi, Loop *TheLoop, DominatorTree *DT)

Returns true if Phi is a fixed-order recurrence.

Definition IVDescriptors.cpp:1182

unsigned getOpcode() const

static LLVM_ABI InstDesc isConditionalRdxPattern(Instruction *I)

Returns a struct describing if the instruction is a Select(FCmp(X, Y), (Z = X op PHINode),...

Definition IVDescriptors.cpp:907

static LLVM_ABI bool hasMultipleUsesOf(Instruction *I, SmallPtrSetImpl< Instruction * > &Insts, unsigned MaxNumUses)

Returns true if instruction I has multiple uses in Insts.

Definition IVDescriptors.cpp:1031

static LLVM_ABI bool isReductionPHI(PHINode *Phi, Loop *TheLoop, RecurrenceDescriptor &RedDes, DemandedBits *DB=nullptr, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr, ScalarEvolution *SE=nullptr)

Returns true if Phi is a reduction in TheLoop.

Definition IVDescriptors.cpp:1045

static LLVM_ABI bool areAllUsesIn(Instruction *I, SmallPtrSetImpl< Instruction * > &Set)

Returns true if all uses of the instruction I is within the Set.

Definition IVDescriptors.cpp:33

RecurrenceDescriptor()=default

LLVM_ABI SmallVector< Instruction *, 4 > getReductionOpChain(PHINode *Phi, Loop *L) const

Attempts to find a chain of operations from Phi to LoopExitInst that can be treated as a set of reduc...

Definition IVDescriptors.cpp:1315

static bool isAnyOfRecurrenceKind(RecurKind Kind)

Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...

static LLVM_ABI InstDesc isAnyOfPattern(Loop *Loop, PHINode *OrigPhi, Instruction *I, InstDesc &Prev)

Returns a struct describing whether the instruction is either a Select(ICmp(A, B),...

Definition IVDescriptors.cpp:687

static bool isFindLastIVRecurrenceKind(RecurKind Kind)

Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...

StoreInst * IntermediateStore

Reductions may store temporary or final result to an invariant address.

static LLVM_ABI InstDesc isRecurrenceInstr(Loop *L, PHINode *Phi, Instruction *I, RecurKind Kind, InstDesc &Prev, FastMathFlags FuncFMF, ScalarEvolution *SE)

Returns a struct describing if the instruction 'I' can be a recurrence variable of type 'Kind' for a ...

Definition IVDescriptors.cpp:943

static LLVM_ABI InstDesc isFindIVPattern(RecurKind Kind, Loop *TheLoop, PHINode *OrigPhi, Instruction *I, ScalarEvolution &SE)

Returns a struct describing whether the instruction is either a Select(ICmp(A, B),...

Definition IVDescriptors.cpp:749

static LLVM_ABI bool isFloatingPointRecurrenceKind(RecurKind Kind)

Returns true if the recurrence kind is a floating point kind.

Definition IVDescriptors.cpp:66

static bool isFindIVRecurrenceKind(RecurKind Kind)

Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...

static LLVM_ABI InstDesc isMinMaxPattern(Instruction *I, RecurKind Kind, const InstDesc &Prev)

Returns a struct describing if the instruction is a llvm.

Definition IVDescriptors.cpp:849

static LLVM_ABI bool AddReductionVar(PHINode *Phi, RecurKind Kind, Loop *TheLoop, FastMathFlags FuncFMF, RecurrenceDescriptor &RedDes, DemandedBits *DB=nullptr, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr, ScalarEvolution *SE=nullptr)

Returns true if Phi is a reduction of type Kind and adds it to the RecurrenceDescriptor.

Definition IVDescriptors.cpp:265

static LLVM_ABI bool isIntegerRecurrenceKind(RecurKind Kind)

Returns true if the recurrence kind is an integer kind.

Definition IVDescriptors.cpp:41

static bool isIntMinMaxRecurrenceKind(RecurKind Kind)

Returns true if the recurrence kind is an integer min/max kind.

static bool isMinMaxRecurrenceKind(RecurKind Kind)

Returns true if the recurrence kind is any min/max kind.

This node represents a polynomial recurrence on the trip count of the specified loop.

const Loop * getLoop() const

This means that we are dealing with an entirely unknown SCEV value, and only represent it as its LLVM...

This class represents an analyzed expression in the program.

LLVM_ABI Type * getType() const

Return the LLVM type of this SCEV expression.

The main scalar evolution driver.

LLVM_ABI bool isKnownNegative(const SCEV *S)

Test if the given expression is known to be negative.

LLVM_ABI const SCEV * getSCEV(Value *V)

Return a SCEV expression for the full generality of the specified expression.

ConstantRange getSignedRange(const SCEV *S)

Determine the signed range for a particular SCEV.

LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)

Return true if the value of the given SCEV is unchanging in the specified loop.

LLVM_ABI bool isKnownPositive(const SCEV *S)

Test if the given expression is known to be positive.

LLVM_ABI bool isSCEVable(Type *Ty) const

Test if values of the given type are analyzable within the SCEV framework.

ConstantRange getUnsignedRange(const SCEV *S)

Determine the unsigned range for a particular SCEV.

LLVM_ABI const SCEV * getUnknown(Value *V)

This class represents the LLVM 'select' instruction.

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

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.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

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.

The instances of the Type class are immutable: once they are created, they are never changed.

bool isPointerTy() const

True if this is an instance of PointerType.

bool isFloatTy() const

Return true if this is 'float', a 32-bit IEEE fp type.

Type * getScalarType() const

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

bool isHalfTy() const

Return true if this is 'half', a 16-bit IEEE fp type.

bool isDoubleTy() const

Return true if this is 'double', a 64-bit IEEE fp type.

bool isFloatingPointTy() const

Return true if this is one of the floating-point types.

bool isIntegerTy() const

True if this is an instance of IntegerType.

static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)

A Use represents the edge between a Value definition and its users.

Value * getOperand(unsigned i) const

LLVM Value Representation.

bool hasOneUse() const

Return true if there is exactly one use of this value.

iterator_range< user_iterator > users()

LLVM_ABI bool hasNUses(unsigned N) const

Return true if this Value has exactly N uses.

const ParentTy * getParent() const

#define llvm_unreachable(msg)

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

OneUse_match< SubPat > m_OneUse(const SubPat &SP)

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

BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)

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

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

BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)

bool match(Val *V, const Pattern &P)

bind_ty< Instruction > m_Instruction(Instruction *&I)

Match an instruction, capturing it if we match.

m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMaxNum(const Opnd0 &Op0, const Opnd1 &Op1)

specificval_ty m_Specific(const Value *V)

Match if we have a specific specified value.

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.

m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMinimum(const Opnd0 &Op0, const Opnd1 &Op1)

match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmin_pred_ty > > m_OrdOrUnordFMin(const LHS &L, const RHS &R)

Match an 'ordered' or 'unordered' floating point minimum function.

MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)

m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMaximum(const Opnd0 &Op0, const Opnd1 &Op1)

BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)

BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)

m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMaximumNum(const Opnd0 &Op0, const Opnd1 &Op1)

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

class_match< CmpInst > m_Cmp()

Matches any compare instruction and ignore it.

m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMinimumNum(const Opnd0 &Op0, const Opnd1 &Op1)

match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmax_pred_ty > > m_OrdOrUnordFMax(const LHS &L, const RHS &R)

Match an 'ordered' or 'unordered' floating point maximum function.

MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)

class_match< Value > m_Value()

Match an arbitrary value and ignore it.

m_Intrinsic_Ty< Opnd0, Opnd1 >::Ty m_FMinNum(const Opnd0 &Op0, const Opnd1 &Op1)

BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)

MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)

match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)

Combine two pattern matchers matching L || R.

specificloop_ty m_SpecificLoop(const Loop *L)

SCEVAffineAddRec_match< Op0_t, Op1_t, class_match< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)

class_match< const SCEV > m_SCEV()

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

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

MachineInstr * getDef(const MachineOperand &MO, const MachineRegisterInfo *MRI)

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

T bit_ceil(T Value)

Returns the smallest integral power of two no smaller than Value if Value is nonzero.

auto dyn_cast_or_null(const Y &Val)

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

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

LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)

Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

bool isa(const From &Val)

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

RecurKind

These are the kinds of recurrences that we support.

@ UMin

Unsigned integer min implemented in terms of select(cmp()).

@ FMinimumNum

FP min with llvm.minimumnum semantics.

@ FindLastIVUMax

FindLast reduction with select(cmp(),x,y) where one of (x,y) is increasing loop induction,...

@ FindFirstIVUMin

FindFirst reduction with select(icmp(),x,y) where one of (x,y) is a decreasing loop induction,...

@ Or

Bitwise or logical OR of integers.

@ FMinimum

FP min with llvm.minimum semantics.

@ FMaxNum

FP max with llvm.maxnum semantics including NaNs.

@ FindLastIVSMax

FindFirst reduction with select(icmp(),x,y) where one of (x,y) is a decreasing loop induction,...

@ Mul

Product of integers.

@ AnyOf

AnyOf reduction with select(cmp(),x,y) where one of (x,y) is loop invariant, and both x and y are int...

@ Xor

Bitwise or logical XOR of integers.

@ FMax

FP max implemented in terms of select(cmp()).

@ FMaximum

FP max with llvm.maximum semantics.

@ FMulAdd

Sum of float products with llvm.fmuladd(a * b + sum).

@ SMax

Signed integer max implemented in terms of select(cmp()).

@ And

Bitwise or logical AND of integers.

@ SMin

Signed integer min implemented in terms of select(cmp()).

@ FMin

FP min implemented in terms of select(cmp()).

@ FMinNum

FP min with llvm.minnum semantics including NaNs.

@ Sub

Subtraction of integers.

@ AddChainWithSubs

A chain of adds and subs.

@ FMaximumNum

FP max with llvm.maximumnum semantics.

@ UMax

Unsigned integer max implemented in terms of select(cmp()).

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

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

decltype(auto) cast(const From &Val)

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

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

Returns true if Element is found in Range.

static bool isMinOrMax(SelectPatternFlavor SPF)

When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?