LLVM 24.0.0git
VPlanConstruction.cpp
Go to the documentation of this file.
1//===-- VPlanConstruction.cpp - Transforms for initial VPlan construction -===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file implements transforms for initial VPlan construction.
11///
12//===----------------------------------------------------------------------===//
13
15#include "VPlan.h"
16#include "VPlanAnalysis.h"
17#include "VPlanCFG.h"
18#include "VPlanDominatorTree.h"
19#include "VPlanHelpers.h"
20#include "VPlanPatternMatch.h"
21#include "VPlanTransforms.h"
22#include "VPlanUtils.h"
23#include "llvm/ADT/Sequence.h"
26#include "llvm/Analysis/Loads.h"
33#include "llvm/IR/InstrTypes.h"
34#include "llvm/IR/MDBuilder.h"
35#include "llvm/Support/Debug.h"
39
40#define DEBUG_TYPE "vplan"
41
42using namespace llvm;
43using namespace LoopVectorizationUtils;
44using namespace VPlanPatternMatch;
45
46namespace {
47// Class that is used to build the plain CFG for the incoming IR.
48class PlainCFGBuilder {
49 // The outermost loop of the input loop nest considered for vectorization.
50 Loop *TheLoop;
51
52 // Loop Info analysis.
53 LoopInfo *LI;
54
55 // Loop versioning for alias metadata.
56 LoopVersioning *LVer;
57
58 // Lazily provides branch probabilities for the incoming IR.
59 function_ref<const BranchProbabilityInfo &()> GetBPI;
60
61 // The BranchProbabilityInfo returned by GetBPI, cached on first use.
62 const BranchProbabilityInfo *BPI = nullptr;
63
64 // Vectorization plan that we are working on.
65 std::unique_ptr<VPlan> Plan;
66
67 // Builder of the VPlan instruction-level representation.
68 VPBuilder VPIRBuilder;
69
70 // NOTE: The following maps are intentionally destroyed after the plain CFG
71 // construction because subsequent VPlan-to-VPlan transformation may
72 // invalidate them.
73 // Map incoming BasicBlocks to their newly-created VPBasicBlocks.
75 // Map incoming Value definitions to their newly-created VPValues.
76 DenseMap<Value *, VPValue *> IRDef2VPValue;
77
78 // Hold phi node's that need to be fixed once the plain CFG has been built.
80
81 // Utility functions.
82 void setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB);
83 void fixHeaderPhis();
84 VPBasicBlock *getOrCreateVPBB(BasicBlock *BB);
85#ifndef NDEBUG
86 bool isExternalDef(Value *Val);
87#endif
88 VPValue *getOrCreateVPOperand(Value *IRVal);
89 void createVPInstructionsForVPBB(VPBasicBlock *VPBB, BasicBlock *BB);
90 VPIRMetadata getTerminatorMetadata(Instruction &Term);
91
92public:
93 PlainCFGBuilder(Loop *Lp, LoopInfo *LI, LoopVersioning *LVer, Type *IdxTy,
94 function_ref<const BranchProbabilityInfo &()> GetBPI)
95 : TheLoop(Lp), LI(LI), LVer(LVer), GetBPI(GetBPI),
96 Plan(std::make_unique<VPlan>(Lp, IdxTy)) {}
97
98 /// Build plain CFG for TheLoop and connect it to Plan's entry.
99 std::unique_ptr<VPlan> buildPlainCFG();
100};
101} // anonymous namespace
102
103// Set predecessors of \p VPBB in the same order as they are in \p BB. \p VPBB
104// must have no predecessors.
105void PlainCFGBuilder::setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB) {
106 // Collect VPBB predecessors.
108 for (BasicBlock *Pred : predecessors(BB))
109 VPBBPreds.push_back(getOrCreateVPBB(Pred));
110 VPBB->setPredecessors(VPBBPreds);
111}
112
113static bool isHeaderBB(BasicBlock *BB, Loop *L) {
114 return L && BB == L->getHeader();
115}
116
117// Add operands to VPInstructions representing phi nodes from the input IR.
118void PlainCFGBuilder::fixHeaderPhis() {
119 for (auto *Phi : PhisToFix) {
120 assert(IRDef2VPValue.count(Phi) && "Missing VPInstruction for PHINode.");
121 VPValue *VPVal = IRDef2VPValue[Phi];
122 assert(isa<VPPhi>(VPVal) && "Expected VPPhi for phi node.");
123 auto *PhiR = cast<VPPhi>(VPVal);
124 assert(PhiR->getNumOperands() == 0 && "Expected VPPhi with no operands.");
125 assert(isHeaderBB(Phi->getParent(), LI->getLoopFor(Phi->getParent())) &&
126 "Expected Phi in header block.");
127 assert(Phi->getNumOperands() == 2 &&
128 "header phi must have exactly 2 operands");
129 for (BasicBlock *Pred : predecessors(Phi->getParent()))
130 PhiR->addIncoming(
131 getOrCreateVPOperand(Phi->getIncomingValueForBlock(Pred)));
132 }
133}
134
135// Create a new empty VPBasicBlock for an incoming BasicBlock or retrieve an
136// existing one if it was already created.
137VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
138 if (auto *VPBB = BB2VPBB.lookup(BB)) {
139 // Retrieve existing VPBB.
140 return VPBB;
141 }
142
143 // Create new VPBB.
144 StringRef Name = BB->getName();
145 LLVM_DEBUG(dbgs() << "Creating VPBasicBlock for " << Name << "\n");
146 VPBasicBlock *VPBB = Plan->createVPBasicBlock(Name);
147 BB2VPBB[BB] = VPBB;
148 return VPBB;
149}
150
151#ifndef NDEBUG
152// Return true if \p Val is considered an external definition. An external
153// definition is either:
154// 1. A Value that is not an Instruction. This will be refined in the future.
155// 2. An Instruction that is outside of the IR region represented in VPlan,
156// i.e., is not part of the loop nest.
157bool PlainCFGBuilder::isExternalDef(Value *Val) {
158 // All the Values that are not Instructions are considered external
159 // definitions for now.
161 if (!Inst)
162 return true;
163
164 // Check whether Instruction definition is in loop body.
165 return !TheLoop->contains(Inst);
166}
167#endif
168
169// Create a new VPValue or retrieve an existing one for the Instruction's
170// operand \p IRVal. This function must only be used to create/retrieve VPValues
171// for *Instruction's operands* and not to create regular VPInstruction's. For
172// the latter, please, look at 'createVPInstructionsForVPBB'.
173VPValue *PlainCFGBuilder::getOrCreateVPOperand(Value *IRVal) {
174 auto VPValIt = IRDef2VPValue.find(IRVal);
175 if (VPValIt != IRDef2VPValue.end())
176 // Operand has an associated VPInstruction or VPValue that was previously
177 // created.
178 return VPValIt->second;
179
180 // Operand doesn't have a previously created VPInstruction/VPValue. This
181 // means that operand is:
182 // A) a definition external to VPlan,
183 // B) any other Value without specific representation in VPlan.
184 // For now, we use VPValue to represent A and B and classify both as external
185 // definitions. We may introduce specific VPValue subclasses for them in the
186 // future.
187 assert(isExternalDef(IRVal) && "Expected external definition as operand.");
188
189 // A and B: Create VPValue and add it to the pool of external definitions and
190 // to the Value->VPValue map.
191 VPValue *NewVPVal = Plan->getOrAddLiveIn(IRVal);
192 IRDef2VPValue[IRVal] = NewVPVal;
193 return NewVPVal;
194}
195
196// Returns the metadata to preserve for terminator \p Term.
197VPIRMetadata PlainCFGBuilder::getTerminatorMetadata(Instruction &Term) {
198 VPIRMetadata MD(Term);
199 if (MD.getMetadata(LLVMContext::MD_prof))
200 return MD;
201 // Estimates are only read for edges inside the loop region.
202 if (!TheLoop->isInnermost() || Term.getParent() == TheLoop->getLoopLatch())
203 return MD;
204 // The weights describe the edges leaving Term in the order of its successors,
205 // matching the successor order of the VPBasicBlock created for Term's parent.
206 if (!BPI)
207 BPI = &GetBPI();
208 auto Weights = map_to_vector(seq(Term.getNumSuccessors()), [&](unsigned I) {
209 return BPI->getEdgeProbability(Term.getParent(), I).getNumerator();
210 });
211 MD.setEstimatedBranchWeights(
212 MDBuilder(Plan->getContext()).createBranchWeights(Weights));
213 return MD;
214}
215
216// Create new VPInstructions in a VPBasicBlock, given its BasicBlock
217// counterpart. This function must be invoked in RPO so that the operands of a
218// VPInstruction in \p BB have been visited before (except for Phi nodes).
219void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
220 BasicBlock *BB) {
221 VPIRBuilder.setInsertPoint(VPBB);
222 // TODO: Model and preserve debug intrinsics in VPlan.
223 for (Instruction &InstRef : *BB) {
224 Instruction *Inst = &InstRef;
225
226 // There shouldn't be any VPValue for Inst at this point. Otherwise, we
227 // visited Inst when we shouldn't, breaking the RPO traversal order.
228 assert(!IRDef2VPValue.count(Inst) &&
229 "Instruction shouldn't have been visited.");
230
231 if (isa<UncondBrInst>(Inst))
232 // Skip the rest of the Instruction processing for Branch instructions.
233 continue;
234
235 if (auto *Br = dyn_cast<CondBrInst>(Inst)) {
236 // Conditional branch instruction are represented using BranchOnCond
237 // recipes.
238 VPValue *Cond = getOrCreateVPOperand(Br->getCondition());
239 VPIRBuilder.createNaryOp(VPInstruction::BranchOnCond, {Cond}, Inst, {},
240 getTerminatorMetadata(*Inst),
241 Inst->getDebugLoc());
242 continue;
243 }
244
245 if (auto *SI = dyn_cast<SwitchInst>(Inst)) {
246 // Don't emit recipes for unconditional switch instructions.
247 if (SI->getNumCases() == 0)
248 continue;
249 SmallVector<VPValue *> Ops = {getOrCreateVPOperand(SI->getCondition())};
250 for (auto Case : SI->cases())
251 Ops.push_back(getOrCreateVPOperand(Case.getCaseValue()));
252 VPIRBuilder.createNaryOp(Instruction::Switch, Ops, Inst, {},
253 getTerminatorMetadata(*Inst),
254 Inst->getDebugLoc());
255 continue;
256 }
257
258 VPSingleDefRecipe *NewR;
259 if (auto *Phi = dyn_cast<PHINode>(Inst)) {
260 // Phi node's operands may not have been visited at this point. We create
261 // an empty VPInstruction that we will fix once the whole plain CFG has
262 // been built.
263 NewR = VPIRBuilder.createScalarPhi({}, Phi->getDebugLoc(), "vec.phi",
264 *Phi, Phi->getType());
265 NewR->setUnderlyingValue(Phi);
266 if (isHeaderBB(Phi->getParent(), LI->getLoopFor(Phi->getParent()))) {
267 // Header phis need to be fixed after the VPBB for the latch has been
268 // created.
269 PhisToFix.push_back(Phi);
270 } else {
271 // Add operands for VPPhi in the order matching its predecessors in
272 // VPlan.
273 DenseMap<const VPBasicBlock *, VPValue *> VPPredToIncomingValue;
274 for (unsigned I = 0; I != Phi->getNumOperands(); ++I) {
275 VPPredToIncomingValue[BB2VPBB[Phi->getIncomingBlock(I)]] =
276 getOrCreateVPOperand(Phi->getIncomingValue(I));
277 }
278 for (VPBlockBase *Pred : VPBB->getPredecessors())
279 cast<VPPhi>(NewR)->addIncoming(
280 VPPredToIncomingValue.lookup(Pred->getExitingBasicBlock()));
281 }
282 } else {
283 // Build VPIRMetadata from the instruction and add loop versioning
284 // metadata for loads and stores.
285 VPIRMetadata MD(*Inst);
286 if (isa<LoadInst, StoreInst>(Inst) && LVer) {
287 const auto &[AliasScopeMD, NoAliasMD] =
288 LVer->getNoAliasMetadataFor(Inst);
289 if (AliasScopeMD)
290 MD.setMetadata(LLVMContext::MD_alias_scope, AliasScopeMD);
291 if (NoAliasMD)
292 MD.setMetadata(LLVMContext::MD_noalias, NoAliasMD);
293 }
294
296 "legality must reject aggregate-producing insertvalue");
297 // Translate LLVM-IR operands into VPValue operands and set them in the
298 // new VPInstruction.
299 SmallVector<VPValue *, 4> VPOperands;
300 for (Value *Op : Inst->operands())
301 VPOperands.push_back(getOrCreateVPOperand(Op));
302 if (auto *EVI = dyn_cast<ExtractValueInst>(Inst))
303 for (unsigned Idx : EVI->indices())
304 VPOperands.push_back(Plan->getConstantInt(32, Idx));
305 VPIRAttributes Attrs;
306 if (auto *CI = dyn_cast<CallInst>(Inst))
307 Attrs = VPIRAttributes(CI->getAttributes());
308 NewR = VPIRBuilder.createNaryOp(Inst->getOpcode(), VPOperands, Inst,
309 VPIRFlags(*Inst), MD, Inst->getDebugLoc(),
310 "", Inst->getType(), Attrs);
311 }
312
313 IRDef2VPValue[Inst] = NewR;
314 }
315}
316
317// Main interface to build the plain CFG.
318std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG() {
319 VPIRBasicBlock *Entry = cast<VPIRBasicBlock>(Plan->getEntry());
320 BB2VPBB[Entry->getIRBasicBlock()] = Entry;
321 for (VPIRBasicBlock *ExitVPBB : Plan->getExitBlocks())
322 BB2VPBB[ExitVPBB->getIRBasicBlock()] = ExitVPBB;
323
324 // 1. Scan the body of the loop in a topological order to visit each basic
325 // block after having visited its predecessor basic blocks. Create a VPBB for
326 // each BB and link it to its successor and predecessor VPBBs. Note that
327 // predecessors must be set in the same order as they are in the incomming IR.
328 // Otherwise, there might be problems with existing phi nodes and algorithm
329 // based on predecessors traversal.
330
331 // Loop PH needs to be explicitly visited since it's not taken into account by
332 // LoopBlocksDFS.
333 BasicBlock *ThePreheaderBB = TheLoop->getLoopPreheader();
334 assert((ThePreheaderBB->getTerminator()->getNumSuccessors() == 1) &&
335 "Unexpected loop preheader");
336 for (auto &I : *ThePreheaderBB) {
337 if (I.getType()->isVoidTy())
338 continue;
339 IRDef2VPValue[&I] = Plan->getOrAddLiveIn(&I);
340 }
341
342 LoopBlocksRPO RPO(TheLoop);
343 RPO.perform(LI);
344
345 for (BasicBlock *BB : RPO) {
346 // Create or retrieve the VPBasicBlock for this BB.
347 VPBasicBlock *VPBB = getOrCreateVPBB(BB);
348 // Set VPBB predecessors in the same order as they are in the incoming BB.
349 setVPBBPredsFromBB(VPBB, BB);
350
351 // Create VPInstructions for BB.
352 createVPInstructionsForVPBB(VPBB, BB);
353
354 // Set VPBB successors. We create empty VPBBs for successors if they don't
355 // exist already. Recipes will be created when the successor is visited
356 // during the RPO traversal.
357 if (auto *SI = dyn_cast<SwitchInst>(BB->getTerminator())) {
359 getOrCreateVPBB(SI->getDefaultDest())};
360 for (auto Case : SI->cases())
361 Succs.push_back(getOrCreateVPBB(Case.getCaseSuccessor()));
362 VPBB->setSuccessors(Succs);
363 continue;
364 }
365 if (auto *BI = dyn_cast<UncondBrInst>(BB->getTerminator())) {
366 VPBB->setOneSuccessor(getOrCreateVPBB(BI->getSuccessor()));
367 continue;
368 }
369 auto *BI = cast<CondBrInst>(BB->getTerminator());
370 BasicBlock *IRSucc0 = BI->getSuccessor(0);
371 BasicBlock *IRSucc1 = BI->getSuccessor(1);
372 VPBasicBlock *Successor0 = getOrCreateVPBB(IRSucc0);
373 VPBasicBlock *Successor1 = getOrCreateVPBB(IRSucc1);
374 VPBB->setTwoSuccessors(Successor0, Successor1);
375 }
376
377 for (auto *EB : Plan->getExitBlocks())
378 setVPBBPredsFromBB(EB, EB->getIRBasicBlock());
379
380 // 2. The whole CFG has been built at this point so all the input Values must
381 // have a VPlan counterpart. Fix VPlan header phi by adding their
382 // corresponding VPlan operands.
383 fixHeaderPhis();
384
385 Plan->getEntry()->setOneSuccessor(getOrCreateVPBB(TheLoop->getHeader()));
386 Plan->getEntry()->setPlan(&*Plan);
387
388 // Fix VPlan loop-closed-ssa exit phi's by adding incoming operands to the
389 // VPIRInstructions wrapping them.
390 // // Note that the operand order corresponds to IR predecessor order, and may
391 // need adjusting when VPlan predecessors are added, if an exit block has
392 // multiple predecessor.
393 for (auto *EB : Plan->getExitBlocks()) {
394 for (VPRecipeBase &R : EB->phis()) {
395 auto *PhiR = cast<VPIRPhi>(&R);
396 PHINode &Phi = PhiR->getIRPhi();
397 assert(PhiR->getNumOperands() == 0 &&
398 "no phi operands should be added yet");
399 for (BasicBlock *Pred : predecessors(EB->getIRBasicBlock()))
400 PhiR->addIncoming(
401 getOrCreateVPOperand(Phi.getIncomingValueForBlock(Pred)));
402 }
403 }
404
405 LLVM_DEBUG(Plan->setName("Plain CFG\n"); dbgs() << *Plan);
406 return std::move(Plan);
407}
408
409/// Checks if \p HeaderVPB is a loop header block in the plain CFG; that is, it
410/// has exactly 2 predecessors (preheader and latch), where the block
411/// dominates the latch and the preheader dominates the block. If it is a
412/// header block return true and canonicalize the predecessors of the header
413/// (making sure the preheader appears first and the latch second) and the
414/// successors of the latch (making sure the loop exit comes first). Otherwise
415/// return false.
417 const VPDominatorTree &VPDT) {
418 ArrayRef<VPBlockBase *> Preds = HeaderVPB->getPredecessors();
419 if (Preds.size() != 2)
420 return false;
421
422 auto *PreheaderVPBB = Preds[0];
423 auto *LatchVPBB = Preds[1];
424 if (!VPDT.dominates(PreheaderVPBB, HeaderVPB) ||
425 !VPDT.dominates(HeaderVPB, LatchVPBB)) {
426 std::swap(PreheaderVPBB, LatchVPBB);
427
428 if (!VPDT.dominates(PreheaderVPBB, HeaderVPB) ||
429 !VPDT.dominates(HeaderVPB, LatchVPBB))
430 return false;
431
432 // Canonicalize predecessors of header so that preheader is first and
433 // latch second.
434 HeaderVPB->swapPredecessors();
435 for (VPRecipeBase &R : cast<VPBasicBlock>(HeaderVPB)->phis())
436 R.swapOperands();
437 }
438
439 // The two successors of conditional branch match the condition, with the
440 // first successor corresponding to true and the second to false. We
441 // canonicalize the successors of the latch when introducing the region, such
442 // that the latch exits the region when its condition is true; invert the
443 // original condition if the original CFG branches to the header on true.
444 // Note that the exit edge is not yet connected for top-level loops.
445 if (LatchVPBB->getSingleSuccessor() ||
446 LatchVPBB->getSuccessors()[0] != HeaderVPB)
447 return true;
448
449 assert(LatchVPBB->getNumSuccessors() == 2 && "Must have 2 successors");
450 auto *Term = cast<VPBasicBlock>(LatchVPBB)->getTerminator();
451 assert(cast<VPInstruction>(Term)->getOpcode() ==
453 "terminator must be a BranchOnCond");
454 auto *Not = new VPInstruction(VPInstruction::Not, {Term->getOperand(0)});
455 Not->insertBefore(Term);
456 Term->setOperand(0, Not);
457 LatchVPBB->swapSuccessors();
458
459 return true;
460}
461
462/// Create a new VPRegionBlock for the loop starting at \p HeaderVPB. For the
463/// outermost loop adjust the regions exiting terminator to be based on the
464/// canonical IV.
465static void createLoopRegion(VPlan &Plan, VPBlockBase *HeaderVPB, DebugLoc DL) {
466 auto *PreheaderVPBB = HeaderVPB->getPredecessors()[0];
467 auto *LatchVPBB = cast<VPBasicBlock>(HeaderVPB->getPredecessors()[1]);
468 auto *OutermostHeaderVPBB =
470
471 VPBlockUtils::disconnectBlocks(PreheaderVPBB, HeaderVPB);
472 VPBlockUtils::disconnectBlocks(LatchVPBB, HeaderVPB);
473
474 // Create an empty region first and insert it between PreheaderVPBB and
475 // the exit blocks, taking care to preserve the original predecessor &
476 // successor order of blocks. Set region entry and exiting after both
477 // HeaderVPB and LatchVPBB have been disconnected from their
478 // predecessors/successors. Only the outermost loop has a canonical IV. Nested
479 // loops are assigned a canonical IV of null type and unknown debug location.
480 bool IsOutermost = HeaderVPB == OutermostHeaderVPBB;
481 Type *CanIVTy = nullptr;
482 if (IsOutermost)
483 CanIVTy = Plan.getVectorTripCount().getType();
484 else
486 auto *R = Plan.createLoopRegion(CanIVTy, DL);
487
488 // Transfer latch's successors to the region.
490
491 VPBlockUtils::connectBlocks(PreheaderVPBB, R);
492 R->setEntry(HeaderVPB);
493 R->setExiting(LatchVPBB);
494
495 // All VPBB's reachable shallowly from HeaderVPB belong to the current region.
496 for (VPBlockBase *VPBB : vp_depth_first_shallow(HeaderVPB))
497 VPBB->setParent(R);
498
499 if (!IsOutermost)
500 return;
501
502 auto *LatchTerm = LatchVPBB->getTerminator();
503 VPBuilder Builder(LatchTerm);
504 // Add a VPInstruction to increment the scalar canonical IV by VF * UF.
505 // Initially the induction increment is guaranteed to not wrap, but that may
506 // change later, e.g. when tail-folding, when the flags need to be dropped.
507 auto *CanonicalIVIncrement = Builder.createAdd(
508 R->getCanonicalIV(), &Plan.getVFxUF(), DL, "index.next", {true, false});
509
510 if (match(LatchTerm, m_BranchOnTwoConds())) {
511 auto *IsLatchExitTaken = Builder.createICmp(
512 CmpInst::ICMP_EQ, CanonicalIVIncrement, &Plan.getVectorTripCount());
513 LatchTerm->setOperand(1, IsLatchExitTaken);
514 } else {
515 // We are replacing the branch to exit the region. Remove the original
516 // BranchOnCond.
517 assert(match(LatchTerm, m_BranchOnCond()) && "Unexpected terminator");
518 DebugLoc LatchDL = LatchTerm->getDebugLoc();
519 Builder.createNaryOp(VPInstruction::BranchOnCount,
520 {CanonicalIVIncrement, &Plan.getVectorTripCount()},
521 LatchDL);
522 LatchTerm->eraseFromParent();
523 }
524}
525
526/// Creates extracts for values in \p Plan defined in a loop region and used
527/// outside a loop region.
528static void createExtractsForLiveOuts(VPlan &Plan, VPBasicBlock *MiddleVPBB) {
529 VPBuilder B(MiddleVPBB->getFirstNonPhi());
530 for (VPBasicBlock *EB : Plan.getExitBlocks()) {
531 if (!is_contained(EB->predecessors(), MiddleVPBB))
532 continue;
533
534 for (VPRecipeBase &R : EB->phis()) {
535 auto *ExitIRI = cast<VPIRPhi>(&R);
536 VPValue *Exiting = ExitIRI->getIncomingValueForBlock(MiddleVPBB);
537 if (isa<VPIRValue>(Exiting))
538 continue;
539 Exiting = B.createNaryOp(VPInstruction::ExtractLastPart, Exiting);
540 Exiting = B.createNaryOp(VPInstruction::ExtractLastLane, Exiting);
541 ExitIRI->setIncomingValueForBlock(MiddleVPBB, Exiting);
542 }
543 }
544}
545
546static void addInitialSkeleton(VPlan &Plan, Type *InductionTy,
547 PredicatedScalarEvolution &PSE, Loop *TheLoop) {
548 VPDominatorTree VPDT(Plan);
549
550 auto *HeaderVPBB = cast<VPBasicBlock>(Plan.getEntry()->getSingleSuccessor());
551 if (TheLoop->isInnermost()) {
552 canonicalHeaderAndLatch(HeaderVPBB, VPDT);
553 } else {
554 // When vectorizing outer loops, canonicalize all loops up front.
556 for (VPBlockBase *VPB : Blocks)
557 canonicalHeaderAndLatch(VPB, VPDT);
558 }
559 auto *LatchVPBB = cast<VPBasicBlock>(HeaderVPBB->getPredecessors()[1]);
560
561 VPBasicBlock *VecPreheader = Plan.createVPBasicBlock("vector.ph");
562 VPBlockUtils::insertBlockAfter(VecPreheader, Plan.getEntry());
563
564 VPBasicBlock *MiddleVPBB = Plan.createVPBasicBlock("middle.block");
565 // The canonical LatchVPBB has the header block as last successor. If it has
566 // another successor, this successor is an exit block - insert middle block on
567 // its edge. Otherwise, add middle block as another successor retaining header
568 // as last. In the latter case, the latch has no conditional terminator yet,
569 // so insert a placeholder BranchOnCond that always continues to the header.
570 // It will be canonicalized to a BranchOnCount later
571 if (LatchVPBB->getNumSuccessors() == 2) {
572 VPBlockBase *LatchExitVPB = LatchVPBB->getSuccessors()[0];
573 VPBlockUtils::insertOnEdge(LatchVPBB, LatchExitVPB, MiddleVPBB);
574 } else {
575 VPBlockUtils::connectBlocks(LatchVPBB, MiddleVPBB);
576 LatchVPBB->swapSuccessors();
578 {Plan.getFalse()});
579 }
580
581 // Create SCEV and VPValue for the trip count.
582 // We use the symbolic max backedge-taken-count, which works also when
583 // vectorizing loops with uncountable early exits.
584 const SCEV *BackedgeTakenCountSCEV = PSE.getSymbolicMaxBackedgeTakenCount();
585 assert(!isa<SCEVCouldNotCompute>(BackedgeTakenCountSCEV) &&
586 "Invalid backedge-taken count");
587 ScalarEvolution &SE = *PSE.getSE();
588 const SCEV *TripCount = SE.getTripCountFromExitCount(BackedgeTakenCountSCEV,
589 InductionTy, TheLoop);
591
592 VPBasicBlock *ScalarPH = Plan.createVPBasicBlock("scalar.ph");
594
595 // The connection order corresponds to the operands of the conditional branch,
596 // with the middle block already connected to the exit block.
597 VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
598 // Also connect the entry block to the scalar preheader.
599 // TODO: Also introduce a branch recipe together with the minimum trip count
600 // check.
601 VPBlockUtils::connectBlocks(Plan.getEntry(), ScalarPH);
602 Plan.getEntry()->swapSuccessors();
603
604 createExtractsForLiveOuts(Plan, MiddleVPBB);
605
606 // Create resume phis in the scalar preheader for each phi in the scalar loop.
607 // Their incoming value from the vector loop will be the last lane of the
608 // corresponding vector loop header phi.
609 VPBuilder MiddleBuilder(MiddleVPBB->getFirstNonPhi());
610 VPBuilder ScalarPHBuilder(ScalarPH);
611 assert(equal(ScalarPH->getPredecessors(),
612 ArrayRef<VPBlockBase *>({MiddleVPBB, Plan.getEntry()})) &&
613 "unexpected predecessor order of scalar ph");
614 for (const auto &[PhiR, ScalarPhiR] :
615 zip_equal(HeaderVPBB->phis(), Plan.getScalarHeader()->phis())) {
616 auto *VectorPhiR = cast<VPPhi>(&PhiR);
617 VPValue *BackedgeVal = VectorPhiR->getOperand(1);
618 VPValue *ResumeFromVectorLoop =
619 MiddleBuilder.createNaryOp(VPInstruction::ExtractLastPart, BackedgeVal);
620 ResumeFromVectorLoop = MiddleBuilder.createNaryOp(
621 VPInstruction::ExtractLastLane, ResumeFromVectorLoop);
622 // Create scalar resume phi, with the first operand being the incoming value
623 // from the middle block and the second operand coming from the entry block.
624 auto *ResumePhiR = ScalarPHBuilder.createScalarPhi(
625 {ResumeFromVectorLoop, VectorPhiR->getOperand(0)},
626 VectorPhiR->getDebugLoc());
627 cast<VPIRPhi>(&ScalarPhiR)->addIncoming(ResumePhiR);
628 }
629}
630
631/// To make RUN_VPLAN_PASS print initial VPlan.
633
634std::unique_ptr<VPlan> VPlanTransforms::buildVPlan0(
635 Loop *TheLoop, LoopInfo &LI, Type *InductionTy,
637 function_ref<const BranchProbabilityInfo &()> GetBPI) {
638 PlainCFGBuilder Builder(TheLoop, &LI, LVer, InductionTy, GetBPI);
639 std::unique_ptr<VPlan> VPlan0 = Builder.buildPlainCFG();
640 addInitialSkeleton(*VPlan0, InductionTy, PSE, TheLoop);
641 simplifyLiveInsWithSCEV(*VPlan0, PSE);
642
644 return VPlan0;
645}
646
650 auto Frequencies = vputils::computeExecutionFrequencies(Blocks);
651 LLVMContext &Ctx = Plan.getContext();
652 for (VPBasicBlock *VPBB : Blocks) {
653 std::optional<VPExecutionFrequency> Freq = Frequencies.lookup(VPBB);
655 VPI.setExecutionFrequency(Freq, Ctx);
656 }
657}
658
659/// Creates a VPWidenIntOrFpInductionRecipe or VPWidenPointerInductionRecipe
660/// for \p Phi based on \p IndDesc.
661static VPHeaderPHIRecipe *
663 const InductionDescriptor &IndDesc, VPlan &Plan,
664 PredicatedScalarEvolution &PSE, Loop &OrigLoop,
665 DebugLoc DL) {
666 [[maybe_unused]] ScalarEvolution &SE = *PSE.getSE();
667 assert(SE.isLoopInvariant(IndDesc.getStep(), &OrigLoop) &&
668 "step must be loop invariant");
669 assert((Plan.getLiveIn(IndDesc.getStartValue()) == Start ||
670 (SE.isSCEVable(IndDesc.getStartValue()->getType()) &&
671 PSE.getSCEV(IndDesc.getStartValue()) ==
672 vputils::getSCEVExprForVPValue(Start, PSE))) &&
673 "Start VPValue must match IndDesc's start value");
674
675 VPValue *Step =
677
678 VPValue *BackedgeVal = PhiR->getOperand(1);
679 // Replace live-out extracts of WideIV's backedge value by ExitingIVValue
680 // recipes. optimizeInductionLiveOutUsers will later compute the proper
681 // DerivedIV.
682 //
683 // For an IV that requires SCEV predicate, keep extracting the exit values
684 // from the loop directly, as the pre-computed exit value as-is would be
685 // incorrect outside the loop.
686 auto ReplaceExtractsWithExitingIVValueIfPossible = [&](VPWidenInductionRecipe
687 *WideIV) {
688 bool IsPredicated = !WideIV->getNoWrapPredicates().empty();
689 for (VPUser *U : to_vector(BackedgeVal->users())) {
691 continue;
692 auto *ExtractLastPart = cast<VPInstruction>(U);
693 VPUser *ExtractLastPartUser = ExtractLastPart->getSingleUser();
694 assert(ExtractLastPartUser && "must have a single user");
695 if (!match(ExtractLastPartUser, m_ExtractLastLane(m_VPValue())))
696 continue;
697 auto *ExtractLastLane = cast<VPInstruction>(ExtractLastPartUser);
698 assert(is_contained(ExtractLastLane->getParent()->successors(),
699 Plan.getScalarPreheader()) &&
700 "last lane must be extracted in the middle block");
701 // Keep the vector extract for exit-block live-out uses of a predicated
702 // IV.
703 if (IsPredicated &&
704 any_of(ExtractLastLane->users(), [&](VPUser *LaneUser) {
705 auto *R = cast<VPRecipeBase>(LaneUser);
706 return Plan.isExitBlock(R->getParent());
707 }))
708 continue;
709 VPBuilder Builder(ExtractLastLane);
710 ExtractLastLane->replaceAllUsesWith(
711 Builder.createNaryOp(VPInstruction::ExitingIVValue, {WideIV}));
712 ExtractLastLane->eraseFromParent();
713 ExtractLastPart->eraseFromParent();
714 }
715 };
716
718 auto *WideIV = new VPWidenPointerInductionRecipe(
719 Phi, Start, Step, &Plan.getVFxUF(), IndDesc, DL);
720 ReplaceExtractsWithExitingIVValueIfPossible(WideIV);
721 return WideIV;
722 }
723
726 "must have an integer or float induction at this point");
727
728 // Update wide induction increments to use the same step as the corresponding
729 // wide induction. This enables detecting induction increments directly in
730 // VPlan and removes redundant splats.
731 if (match(BackedgeVal, m_Add(m_Specific(PhiR), m_VPValue())))
732 BackedgeVal->getDefiningRecipe()->setOperand(1, Step);
733
734 // It is always safe to copy over the NoWrap and FastMath flags. In
735 // particular, when folding tail by masking, the masked-off lanes are never
736 // used, so it is safe.
737 VPIRFlags Flags = vputils::getFlagsForInduction(IndDesc, PhiR);
738
739 auto *WideIV = new VPWidenIntOrFpInductionRecipe(
740 Phi, Start, Step, &Plan.getVF(), IndDesc, Flags, DL);
741
742 ReplaceExtractsWithExitingIVValueIfPossible(WideIV);
743 return WideIV;
744}
745
746/// Try to sink users of \p FOR after \p Previous. \returns true if sinking
747/// succeeded or was not necessary, and false otherwise.
748static bool
750 VPRecipeBase *Previous,
751 const VPDominatorTree &VPDT) {
752 // Collect recipes that need sinking.
755 Seen.insert(Previous);
756 auto TryToPushSinkCandidate = [&](VPRecipeBase *SinkCandidate) {
757 // The previous value must not depend on the users of the recurrence phi.
758 // In that case, FOR is not a fixed order recurrence.
759 if (SinkCandidate == Previous)
760 return false;
761
762 if (isa<VPHeaderPHIRecipe>(SinkCandidate) ||
763 !Seen.insert(SinkCandidate).second ||
764 VPDT.properlyDominates(Previous, SinkCandidate))
765 return true;
766
767 if (vputils::cannotHoistOrSinkRecipe(*SinkCandidate, /*Sinking=*/true))
768 return false;
769
770 WorkList.push_back(SinkCandidate);
771 return true;
772 };
773
774 // Recursively sink users of FOR after Previous.
775 WorkList.push_back(FOR);
776 for (unsigned I = 0; I != WorkList.size(); ++I) {
777 VPRecipeBase *Current = WorkList[I];
778 assert(Current->getNumDefinedValues() == 1 &&
779 "only recipes with a single defined value expected");
780
781 for (VPUser *User : Current->getVPSingleValue()->users()) {
782 if (!TryToPushSinkCandidate(cast<VPRecipeBase>(User)))
783 return false;
784 }
785 }
786
787 // Keep recipes to sink ordered by dominance so earlier instructions are
788 // processed first.
789 sort(WorkList, [&VPDT](const VPRecipeBase *A, const VPRecipeBase *B) {
790 return VPDT.properlyDominates(A, B);
791 });
792
793 for (VPRecipeBase *SinkCandidate : WorkList) {
794 if (SinkCandidate == FOR)
795 continue;
796
797 SinkCandidate->moveAfter(Previous);
798 Previous = SinkCandidate;
799 }
800 return true;
801}
802
803/// Try to hoist \p Previous and its operands before all users of \p FOR.
804/// \returns true if hoisting succeeded or was not necessary, and false
805/// otherwise.
807 VPRecipeBase *Previous,
808 const VPDominatorTree &VPDT) {
810 return false;
811
812 // Collect recipes that need hoisting.
813 SmallVector<VPRecipeBase *> HoistCandidates;
815 // Find the closest hoist point by looking at all users of FOR and selecting
816 // the recipe dominating all other users.
817 VPRecipeBase *HoistPoint = nullptr;
818 for (VPUser *U : FOR->users()) {
819 auto *R = cast<VPRecipeBase>(U);
820 if (!HoistPoint || VPDT.properlyDominates(R, HoistPoint))
821 HoistPoint = R;
822 }
823 // Dominance is only a partial order, so the users of FOR may not have a
824 // single user dominating all others. Bail out in that case.
825 if (!HoistPoint || HoistPoint->isPhi() ||
826 any_of(FOR->users(), [&VPDT, HoistPoint](VPUser *U) {
827 auto *R = cast<VPRecipeBase>(U);
828 return HoistPoint != R && !VPDT.properlyDominates(HoistPoint, R);
829 }))
830 return false;
831
832 auto NeedsHoisting = [HoistPoint, &VPDT,
833 &Visited](VPValue *HoistCandidateV) -> VPRecipeBase * {
834 VPRecipeBase *HoistCandidate = HoistCandidateV->getDefiningRecipe();
835 if (!HoistCandidate)
836 return nullptr;
837 // Hoist candidate was already visited, no need to hoist.
838 if (!Visited.insert(HoistCandidate).second)
839 return nullptr;
840 // If we reached a recipe that dominates HoistPoint, we don't need to
841 // hoist the recipe.
842 if (VPDT.properlyDominates(HoistCandidate, HoistPoint))
843 return nullptr;
844 return HoistCandidate;
845 };
846
847 if (!NeedsHoisting(Previous->getVPSingleValue()))
848 return true;
849
850 // Recursively try to hoist Previous and its operands before all users of
851 // FOR.
852 HoistCandidates.push_back(Previous);
853
854 for (unsigned I = 0; I != HoistCandidates.size(); ++I) {
855 VPRecipeBase *Current = HoistCandidates[I];
856 assert(Current->getNumDefinedValues() == 1 &&
857 "only recipes with a single defined value expected");
859 return false;
860
861 for (VPValue *Op : Current->operands()) {
862 // If we reach FOR, it means the original Previous depends on some other
863 // recurrence that in turn depends on FOR. If that is the case, we would
864 // also need to hoist recipes involving the other FOR, which may break
865 // dependencies.
866 if (Op == FOR)
867 return false;
868
869 if (auto *R = NeedsHoisting(Op)) {
870 // Bail out if the recipe defines multiple values.
871 // TODO: Hoisting such recipes requires additional handling.
872 if (R->getNumDefinedValues() != 1)
873 return false;
874 HoistCandidates.push_back(R);
875 }
876 }
877 }
878
879 // Moving a candidate to HoistPoint keeps it dominating its other users only
880 // if HoistPoint dominates the candidate's current position.
881 if (any_of(HoistCandidates, [&VPDT, HoistPoint](VPRecipeBase *R) {
882 return !VPDT.properlyDominates(HoistPoint, R);
883 }))
884 return false;
885
886 // Order recipes to hoist by dominance so earlier instructions are processed
887 // first.
888 sort(HoistCandidates, [&VPDT](const VPRecipeBase *A, const VPRecipeBase *B) {
889 return VPDT.properlyDominates(A, B);
890 });
891
892 for (VPRecipeBase *HoistCandidate : HoistCandidates) {
893 HoistCandidate->moveBefore(HoistPoint->getIterator());
894 }
895
896 return true;
897}
898
899/// Sink users of fixed-order recurrences past or hoist before the recipe
900/// defining the previous value, introduce FirstOrderRecurrenceSplice
901/// VPInstructions, and replace FOR uses. Returns false if hoisting or sinking
902/// fails.
904 const VPDominatorTree &VPDT) {
905 auto FORs =
908 [](VPRecipeBase &R) {
909 return cast<VPFirstOrderRecurrencePHIRecipe>(&R);
910 });
911 for (VPFirstOrderRecurrencePHIRecipe *FOR : FORs) {
912 // Follow through FOR phi chains to find the actual Previous recipe.
913 // Fixed-order recurrences do not contain cycles, so this loop is
914 // guaranteed to terminate.
915#ifndef NDEBUG
917#endif
918 VPRecipeBase *Previous = FOR->getBackedgeValue()->getDefiningRecipe();
919 while (auto *PrevPhi =
921 assert(PrevPhi->getParent() == FOR->getParent() &&
922 "PrevPhi must be in same block as FOR");
923 assert(SeenPhis.insert(PrevPhi).second &&
924 "PrevPhi must not be visited multiple times");
925 Previous = PrevPhi->getBackedgeValue()->getDefiningRecipe();
926 }
927
928 VPBasicBlock::iterator InsertPt = FOR->getParent()->getFirstNonPhi();
929 if (Previous) {
930 // Sink FOR users after Previous or hoist Previous before FOR users.
931 if (!sinkRecurrenceUsersAfterPrevious(FOR, Previous, VPDT) &&
932 !hoistPreviousBeforeFORUsers(FOR, Previous, VPDT))
933 return false;
934 InsertPt = isa<VPHeaderPHIRecipe>(Previous)
935 ? Previous->getParent()->getFirstNonPhi()
936 : std::next(Previous->getIterator());
937 }
938
939 // Create FirstOrderRecurrenceSplice and replace FOR uses.
940 VPBuilder LoopBuilder(InsertPt);
941 auto *RecurSplice =
943 {FOR, FOR->getBackedgeValue()});
944 FOR->replaceUsesWithIf(RecurSplice, not_equal_to(RecurSplice));
945 }
946
947 return true;
948}
949
951 VPlan &Plan, PredicatedScalarEvolution &PSE, Loop &OrigLoop,
956 &ConditionalInductions,
957 const SmallPtrSetImpl<const PHINode *> &FixedOrderRecurrences,
958 const SmallPtrSetImpl<PHINode *> &InLoopReductions, bool AllowReordering) {
959 // Retrieve the header manually from the intial plain-CFG VPlan.
960 auto [HeaderVPBB, LatchVPBB] = VPBlockUtils::getPlainCFGHeaderAndLatch(Plan);
961 assert(VPDT.dominates(HeaderVPBB, LatchVPBB) &&
962 "header must dominate its latch");
963
964 auto CreateHeaderPhiRecipe = [&](VPPhi *PhiR) -> VPHeaderPHIRecipe * {
965 // TODO: Gradually replace uses of underlying instruction by analyses on
966 // VPlan.
967 auto *Phi = cast<PHINode>(PhiR->getUnderlyingInstr());
968 assert(PhiR->getNumOperands() == 2 &&
969 "Must have 2 operands for header phis");
970
971 // Extract common values once.
972 VPIRValue *Start = cast<VPIRValue>(PhiR->getOperand(0));
973 VPValue *BackedgeValue = PhiR->getOperand(1);
974
975 if (FixedOrderRecurrences.contains(Phi)) {
976 // TODO: Currently fixed-order recurrences are modeled as chains of
977 // first-order recurrences. If there are no users of the intermediate
978 // recurrences in the chain, the fixed order recurrence should be
979 // modeled directly, enabling more efficient codegen.
980 return new VPFirstOrderRecurrencePHIRecipe(Phi, *Start, *BackedgeValue);
981 }
982
983 auto InductionIt = Inductions.find(Phi);
984 if (InductionIt != Inductions.end())
985 return createWidenInductionRecipe(Phi, PhiR, Start, InductionIt->second,
986 Plan, PSE, OrigLoop,
987 PhiR->getDebugLoc());
988
989 auto ConditionalInductionIt = ConditionalInductions.find(Phi);
990 if (ConditionalInductionIt != ConditionalInductions.end()) {
991 const ConditionalInductionDescriptor &CondID =
992 ConditionalInductionIt->second;
993 return new VPConditionalInductionPHIRecipe(*Phi, *Start, *BackedgeValue,
994 CondID.getStepSCEV());
995 }
996
997 assert(Reductions.contains(Phi) && "only reductions are expected now");
998 const RecurrenceDescriptor &RdxDesc = Reductions.lookup(Phi);
1000 Phi->getIncomingValueForBlock(OrigLoop.getLoopPreheader()) &&
1001 "incoming value must match start value");
1002 // Will be updated later to >1 if reduction is partial.
1003 unsigned ScaleFactor = 1;
1004 bool UseOrderedReductions = !AllowReordering && RdxDesc.isOrdered();
1005 return new VPReductionPHIRecipe(
1006 Phi, RdxDesc.getRecurrenceKind(), *Start, *BackedgeValue,
1007 getReductionStyle(InLoopReductions.contains(Phi), UseOrderedReductions,
1008 ScaleFactor),
1009 Phi->getType()->isFloatingPointTy() ? RdxDesc.getFastMathFlags()
1010 : VPIRFlags(),
1012 };
1013
1014 for (VPRecipeBase &R : make_early_inc_range(HeaderVPBB->phis())) {
1015 auto *PhiR = cast<VPPhi>(&R);
1016 VPHeaderPHIRecipe *HeaderPhiR = CreateHeaderPhiRecipe(PhiR);
1017 HeaderPhiR->insertBefore(PhiR);
1018 PhiR->replaceAllUsesWith(HeaderPhiR);
1019 PhiR->eraseFromParent();
1020 }
1021
1022 if (!tryToSinkOrHoistRecurrenceUsers(HeaderVPBB, VPDT)) {
1024 "Failed to sink or hoist user of first-order recurrence",
1025 "CannotSinkHoistFORUser", ORE, &OrigLoop);
1026 return false;
1027 }
1028
1029 // Skip renaming resume phi recipes, if any header phi has been removed.
1030 if (range_size(HeaderVPBB->phis()) !=
1032 return true;
1033 for (const auto &[HeaderPhiR, ScalarPhiR] :
1034 zip_equal(HeaderVPBB->phis(), Plan.getScalarPreheader()->phis())) {
1035 auto *ResumePhiR = cast<VPPhi>(&ScalarPhiR);
1036 if (isa<VPFirstOrderRecurrencePHIRecipe>(&HeaderPhiR)) {
1037 ResumePhiR->setName("scalar.recur.init");
1038 auto *ExtractLastLane = cast<VPInstruction>(ResumePhiR->getOperand(0));
1039 ExtractLastLane->setName("vector.recur.extract");
1040 continue;
1041 }
1042 ResumePhiR->setName(isa<VPWidenInductionRecipe>(HeaderPhiR)
1043 ? "bc.resume.val"
1044 : "bc.merge.rdx");
1045 }
1046 return true;
1047}
1048
1051 bool OptForSize,
1052 unsigned SCEVCheckThreshold,
1054 Loop *TheLoop) {
1055 // Collect which wide IVs have predicates and add them to PSE.
1056 auto [HeaderVPBB, _] = VPBlockUtils::getPlainCFGHeaderAndLatch(Plan);
1058 for (VPWidenInductionRecipe &WideIV :
1059 make_isa_range<VPWidenInductionRecipe>(HeaderVPBB->phis())) {
1060 if (WideIV.getNoWrapPredicates().empty())
1061 continue;
1062 PredicatedIVs.insert(&WideIV);
1063 for (const auto *P : WideIV.getNoWrapPredicates())
1064 PSE.addPredicate(*P);
1065 }
1066
1067 unsigned TotalComplexity = PSE.getPredicate().getComplexity();
1068 if (TotalComplexity && OptForSize) {
1069 LLVM_DEBUG(
1070 dbgs() << "LV: Not vectorizing: SCEV predicates needed for induction "
1071 "but optimizing for size\n");
1073 "Runtime SCEV check is required with -Os/-Oz",
1074 "runtime SCEV checks needed but optimizing for size",
1075 "CantVersionLoopWithOptForSize", ORE, TheLoop);
1076 return false;
1077 }
1078
1079 if (TotalComplexity > SCEVCheckThreshold) {
1080 LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Too many SCEV checks needed ("
1081 << TotalComplexity << " > " << SCEVCheckThreshold
1082 << ")\n");
1084 "Too many SCEV checks needed",
1085 "Too many SCEV assumptions need to be made and checked at runtime",
1086 "TooManySCEVRunTimeChecks", ORE, TheLoop);
1087 return false;
1088 }
1089
1090 return true;
1091}
1092
1094 ElementCount MinVF) {
1097
1098 for (VPRecipeBase &R : Header->phis()) {
1099 auto *PhiR = dyn_cast<VPReductionPHIRecipe>(&R);
1100 if (!PhiR || !PhiR->isInLoop() || (MinVF.isScalar() && !PhiR->isOrdered()))
1101 continue;
1102
1103 RecurKind Kind = PhiR->getRecurrenceKind();
1107 "AnyOf and Find reductions are not allowed for in-loop reductions");
1108
1109 bool IsFPRecurrence =
1111 FastMathFlags FMFs =
1112 IsFPRecurrence ? FastMathFlags::getFast() : FastMathFlags();
1113
1114 // Collect the chain of "link" recipes for the reduction starting at PhiR.
1116 Worklist.insert(PhiR);
1117 for (unsigned I = 0; I != Worklist.size(); ++I) {
1118 VPSingleDefRecipe *Cur = Worklist[I];
1119 for (VPUser *U : Cur->users()) {
1120 auto *UserRecipe = cast<VPSingleDefRecipe>(U);
1121 if (!UserRecipe->getParent()->getEnclosingLoopRegion()) {
1122 assert((UserRecipe->getParent() == Plan.getMiddleBlock() ||
1123 UserRecipe->getParent() == Plan.getScalarPreheader()) &&
1124 "U must be either in the loop region, the middle block or the "
1125 "scalar preheader.");
1126 continue;
1127 }
1128
1129 // Stores using instructions will be sunk later.
1130 if (match(UserRecipe, m_VPInstruction<Instruction::Store>()))
1131 continue;
1132 Worklist.insert(UserRecipe);
1133 }
1134 }
1135
1136 // Visit operation "Links" along the reduction chain top-down starting from
1137 // the phi until LoopExitValue. We keep track of the previous item
1138 // (PreviousLink) to tell which of the two operands of a Link will remain
1139 // scalar and which will be reduced. For minmax by select(cmp), Link will be
1140 // the select instructions. Blend recipes of in-loop reduction phi's will
1141 // get folded to their non-phi operand, as the reduction recipe handles the
1142 // condition directly.
1143 VPSingleDefRecipe *PreviousLink = PhiR; // Aka Worklist[0].
1144 for (VPSingleDefRecipe *CurrentLink : drop_begin(Worklist)) {
1145 if (auto *Blend = dyn_cast<VPBlendRecipe>(CurrentLink)) {
1146 assert(Blend->getNumIncomingValues() == 2 &&
1147 "Blend must have 2 incoming values");
1148 unsigned PhiRIdx = Blend->getIncomingValue(0) == PhiR ? 0 : 1;
1149 assert(Blend->getIncomingValue(PhiRIdx) == PhiR &&
1150 "PhiR must be an operand of the blend");
1151 Blend->replaceAllUsesWith(Blend->getIncomingValue(1 - PhiRIdx));
1152 continue;
1153 }
1154
1155 if (IsFPRecurrence) {
1156 FastMathFlags CurFMF =
1157 cast<VPRecipeWithIRFlags>(CurrentLink)->getFastMathFlagsOrNone();
1158 if (match(CurrentLink, m_Select(m_VPValue(), m_VPValue(), m_VPValue())))
1159 CurFMF |= cast<VPRecipeWithIRFlags>(CurrentLink->getOperand(0))
1160 ->getFastMathFlagsOrNone();
1161 FMFs &= CurFMF;
1162 }
1163
1164 Instruction *CurrentLinkI = CurrentLink->getUnderlyingInstr();
1165
1166 // Recognize a call to the llvm.fmuladd intrinsic.
1167 bool IsFMulAdd = Kind == RecurKind::FMulAdd;
1168 VPValue *VecOp;
1169 VPBasicBlock *LinkVPBB = CurrentLink->getParent();
1170 if (IsFMulAdd) {
1172 "Expected current VPInstruction to be a call to the "
1173 "llvm.fmuladd intrinsic");
1174 assert(CurrentLink->getOperand(2) == PreviousLink &&
1175 "expected a call where the previous link is the added operand");
1176
1177 // If the instruction is a call to the llvm.fmuladd intrinsic then we
1178 // need to create an fmul recipe (multiplying the first two operands of
1179 // the fmuladd together) to use as the vector operand for the fadd
1180 // reduction.
1181 auto *FMulRecipe = new VPInstruction(
1182 Instruction::FMul,
1183 {CurrentLink->getOperand(0), CurrentLink->getOperand(1)},
1184 CurrentLinkI->getFastMathFlags());
1185 FMulRecipe->insertBefore(CurrentLink);
1186 VecOp = FMulRecipe;
1187 } else if (Kind == RecurKind::AddChainWithSubs &&
1188 match(CurrentLink, m_Sub(m_VPValue(), m_VPValue()))) {
1189 Type *PhiTy = PhiR->getScalarType();
1190 auto *Zero = Plan.getConstantInt(PhiTy, 0);
1191 VPBuilder Builder(CurrentLink);
1192 auto *Sub = Builder.createSub(Zero, CurrentLink->getOperand(1),
1193 CurrentLinkI->getDebugLoc());
1194 Sub->setUnderlyingValue(CurrentLinkI);
1195 VecOp = Sub;
1196 } else {
1197 // Index of the first operand which holds a non-mask vector operand.
1198 unsigned IndexOfFirstOperand = 0;
1200 if (match(CurrentLink, m_Cmp(m_VPValue(), m_VPValue())))
1201 continue;
1202 assert(match(CurrentLink,
1204 "must be a select recipe");
1205 IndexOfFirstOperand = 1;
1206 }
1207 // Note that for non-commutable operands (cmp-selects), the semantics of
1208 // the cmp-select are captured in the recurrence kind.
1209 unsigned VecOpId =
1210 CurrentLink->getOperand(IndexOfFirstOperand) == PreviousLink
1211 ? IndexOfFirstOperand + 1
1212 : IndexOfFirstOperand;
1213 VecOp = CurrentLink->getOperand(VecOpId);
1214 assert(
1215 VecOp != PreviousLink &&
1216 CurrentLink->getOperand(
1217 cast<VPInstruction>(CurrentLink)->getNumOperandsWithoutMask() -
1218 1 - (VecOpId - IndexOfFirstOperand)) == PreviousLink &&
1219 "PreviousLink must be the operand other than VecOp");
1220 }
1221
1222 assert(PhiR->getVFScaleFactor() == 1 &&
1223 "inloop reductions must be unscaled");
1224 VPValue *CondOp = cast<VPInstruction>(CurrentLink)->getMask();
1225 auto *RedRecipe = new VPReductionRecipe(
1226 Kind, FMFs, CurrentLinkI, PreviousLink, VecOp, CondOp,
1227 getReductionStyle(/*IsInLoop=*/true, PhiR->isOrdered(), 1),
1228 CurrentLinkI->getDebugLoc());
1229 // Append the recipe to the end of the VPBasicBlock because we need to
1230 // ensure that it comes after all of it's inputs, including CondOp.
1231 // Delete CurrentLink as it will be invalid if its operand is replaced
1232 // with a reduction defined at the bottom of the block in the next link.
1233 if (LinkVPBB->getNumSuccessors() == 0)
1234 RedRecipe->insertBefore(&*std::prev(std::prev(LinkVPBB->end())));
1235 else
1236 LinkVPBB->appendRecipe(RedRecipe);
1237
1238 CurrentLink->replaceAllUsesWith(RedRecipe);
1239 // Move any store recipes using the RedRecipe that appear before it in the
1240 // same block to just after the RedRecipe.
1241 for (VPRecipeBase *UserR : make_early_inc_range(
1242 make_isa_range<VPRecipeBase>(RedRecipe->users()))) {
1243 if (UserR->getParent() != LinkVPBB)
1244 continue;
1246 continue;
1247 UserR->moveAfter(RedRecipe);
1248 }
1249 ToDelete.push_back(CurrentLink);
1250 PreviousLink = RedRecipe;
1251 }
1252 }
1253
1254 for (VPRecipeBase *R : ToDelete)
1255 R->eraseFromParent();
1256}
1257
1259 Loop *TheLoop,
1261 DominatorTree &DT,
1262 AssumptionCache *AC) {
1263 ScalarEvolution &SE = *PSE.getSE();
1264 const DataLayout &DL = TheLoop->getHeader()->getDataLayout();
1265 for (VPBasicBlock *VPBB : vp_rpo_plain_cfg_loop_body(HeaderVPBB)) {
1266 for (VPRecipeBase &R : *VPBB) {
1267 // Pseudo-probes are profiling placeholders with side effects but no real
1268 // memory access. They are modeled as reading inaccessible memory, so skip
1269 // them here to stay consistent with isReadOnlyLoop(), which classifies
1270 // such loops as read-only.
1272 continue;
1273 auto *VPI = dyn_cast<VPInstruction>(&R);
1274 if (!VPI || VPI->getOpcode() != Instruction::Load) {
1275 assert(!R.mayReadFromMemory() && "unexpected recipe reading memory");
1276 continue;
1277 }
1278
1279 // Get the pointer SCEV for dereferenceability checking.
1280 VPValue *Ptr = VPI->getOperand(0);
1281 const SCEV *PtrSCEV = vputils::getSCEVExprForVPValue(Ptr, PSE, TheLoop);
1282 if (isa<SCEVCouldNotCompute>(PtrSCEV)) {
1283 LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Found non-dereferenceable "
1284 "load with SCEVCouldNotCompute pointer\n");
1285 return false;
1286 }
1287
1288 // Check dereferenceability using the SCEV-based version.
1289 Type *LoadTy = VPI->getScalarType();
1290 const SCEV *SizeSCEV =
1291 SE.getStoreSizeOfExpr(DL.getIndexType(PtrSCEV->getType()), LoadTy);
1292 auto *Load = cast<LoadInst>(VPI->getUnderlyingValue());
1294 if (isDereferenceableAndAlignedInLoop(PtrSCEV, Load->getAlign(), SizeSCEV,
1295 TheLoop, SE, DT, AC, &Preds))
1296 continue;
1297
1298 return false;
1299 }
1300 }
1301 return true;
1302}
1303
1305 auto *MiddleVPBB = VPBlockUtils::getPlainCFGMiddleBlock(Plan);
1306 // Disconnect countable early exits from the loop, leaving it with a single
1307 // exit from the latch. Countable early exits are left for a scalar epilog.
1308 for (auto [EarlyExitingVPBB, EB] : vputils::getEarlyExits(Plan, MiddleVPBB)) {
1309 // Remove phi operands for the early exiting block.
1310 for (VPRecipeBase &R : EB->phis())
1311 cast<VPIRPhi>(&R)->removeIncomingValueFor(EarlyExitingVPBB);
1312 EarlyExitingVPBB->getTerminator()->eraseFromParent();
1313 VPBlockUtils::disconnectBlocks(EarlyExitingVPBB, EB);
1314 }
1315}
1316
1318 auto *MiddleVPBB = VPBlockUtils::getPlainCFGMiddleBlock(Plan);
1319 // If MiddleVPBB has a single successor then the original loop does not exit
1320 // via the latch and the single successor must be the scalar preheader.
1321 // There's no need to add a runtime check to MiddleVPBB.
1322 if (MiddleVPBB->getNumSuccessors() == 1) {
1323 assert(MiddleVPBB->getSingleSuccessor() == Plan.getScalarPreheader() &&
1324 "must have ScalarPH as single successor");
1325 return;
1326 }
1327
1328 assert(MiddleVPBB->getNumSuccessors() == 2 && "must have 2 successors");
1329
1330 // Add a check in the middle block to see if we have completed all of the
1331 // iterations in the first vector loop.
1332 //
1333 // Three cases:
1334 // 1) If we require a scalar epilogue, the scalar ph must execute. Set the
1335 // condition to false.
1336 // 2) If (N - N%VF) == N, then we *don't* need to run the
1337 // remainder. Thus if tail is to be folded, we know we don't need to run
1338 // the remainder and we can set the condition to true.
1339 // 3) Otherwise, construct a runtime check.
1340
1341 // We use the same DebugLoc as the scalar loop latch terminator instead of
1342 // the corresponding compare because they may have ended up with different
1343 // line numbers and we want to avoid awkward line stepping while debugging.
1344 // E.g., if the compare has got a line number inside the loop.
1345 auto *LatchVPBB = cast<VPBasicBlock>(MiddleVPBB->getSinglePredecessor());
1346 DebugLoc LatchDL = LatchVPBB->getTerminator()->getDebugLoc();
1347 VPBuilder Builder(MiddleVPBB);
1348 VPValue *Cmp =
1349 Builder.createICmp(CmpInst::ICMP_EQ, Plan.getTripCount(),
1350 &Plan.getVectorTripCount(), LatchDL, "cmp.n");
1351 Builder.createNaryOp(VPInstruction::BranchOnCond, {Cmp}, LatchDL);
1352}
1353
1355 VPDominatorTree VPDT(Plan);
1357 Plan.getEntry());
1358 // Headers and latches have been canonicalized by addInitialSkeleton.
1359 for (VPBlockBase *HeaderVPB : POT) {
1360 if (!VPBlockUtils::isHeader(HeaderVPB, VPDT))
1361 continue;
1362 assert(HeaderVPB->getPredecessors()[1]->getSuccessors().back() ==
1363 HeaderVPB &&
1364 "latch must have the header as last successor");
1365 createLoopRegion(Plan, HeaderVPB, DL);
1366 }
1367
1368 VPRegionBlock *TopRegion = Plan.getVectorLoopRegion();
1369 TopRegion->setName("vector loop");
1370 TopRegion->getEntryBasicBlock()->setName("vector.body");
1371}
1372
1374 assert(Plan.getExitBlocks().size() == 1 &&
1375 "only a single-exit block is supported currently");
1376 assert(Plan.getExitBlocks().front()->getSinglePredecessor() ==
1377 Plan.getMiddleBlock() &&
1378 "the exit block must have middle block as single predecessor");
1379
1380 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
1381 assert(LoopRegion->getSingleSuccessor() == Plan.getMiddleBlock() &&
1382 "The vector loop region must have the middle block as its single "
1383 "successor for now");
1384 VPBasicBlock *Header = LoopRegion->getEntryBasicBlock();
1385
1386 Header->splitAt(Header->getFirstNonPhi());
1387
1388 // Abstract header mask, materialized into concrete recipes later.
1389 VPValue *HeaderMask = LoopRegion->createHeaderMask();
1390 VPBuilder Builder(Header->getFirstNonPhi());
1391 Builder.createNaryOp(VPInstruction::BranchOnCond, HeaderMask);
1392
1393 VPBasicBlock *OrigLatch = LoopRegion->getExitingBasicBlock();
1394 VPValue *IVInc;
1395 [[maybe_unused]] bool TermBranchOnCount =
1396 match(OrigLatch->getTerminator(),
1398 m_Specific(&Plan.getVectorTripCount())));
1399 assert(TermBranchOnCount &&
1400 match(IVInc, m_Add(m_Specific(LoopRegion->getCanonicalIV()),
1401 m_Specific(&Plan.getVFxUF()))) &&
1402 std::next(IVInc->getDefiningRecipe()->getIterator()) ==
1403 OrigLatch->getTerminator()->getIterator() &&
1404 "Unexpected canonical iv increment");
1405
1406 // Split the latch at the IV update, and branch to it from the header mask.
1407 VPBasicBlock *Latch =
1408 OrigLatch->splitAt(IVInc->getDefiningRecipe()->getIterator());
1409 Latch->setName("vector.latch");
1410 VPBlockUtils::connectBlocks(Header, Latch);
1411
1412 // Collect any values defined in the loop that need a phi, that is header phis
1413 // and any value defined n the loop and used in the middle block.
1414 // TODO: Handle early exits via Plan.getExitBlocks()
1416 auto CollectBypassedOperands = [&](VPRecipeBase &R) {
1417 for (VPValue *Op : R.operands()) {
1418 auto *DefR = Op->getDefiningRecipe();
1419 if (DefR && DefR->getParent()->getEnclosingLoopRegion() == LoopRegion &&
1420 !is_contained({Header, Latch}, DefR->getParent()))
1421 NeedsPhi[Op].push_back(&R);
1422 }
1423 };
1424 for (VPRecipeBase &R : Header->phis())
1425 CollectBypassedOperands(R);
1426 for (VPRecipeBase &R : *Plan.getMiddleBlock())
1427 CollectBypassedOperands(R);
1428
1429 // Insert phis for values coming past the end of the tail.
1430 Builder.setInsertPoint(Latch->begin());
1431 for (const auto &[V, Users] : NeedsPhi) {
1432 VPValue *TailVal = Plan.getPoison(V->getScalarType());
1433 std::optional<VPIRFlags> Flags;
1435 "Value used by more than two reduction phis?");
1437 auto *RdxPhi =
1438 RedIt != Users.end() ? cast<VPReductionPHIRecipe>(*RedIt) : nullptr;
1439 if (RdxPhi && !RdxPhi->isInLoop()) {
1440 TailVal = RdxPhi;
1441 Flags = *RdxPhi;
1442 }
1443
1444 VPInstruction *Phi = Builder.createScalarPhi({V, TailVal}, {}, "", Flags);
1445 for (VPUser *U : Users)
1446 U->replaceUsesOfWith(V, Phi);
1447 }
1448
1449 // Any extract of the last element must be updated to extract from the last
1450 // active lane of the header mask instead (i.e., the lane corresponding to the
1451 // last active iteration).
1452 Builder.setInsertPoint(Plan.getMiddleBlock()->getTerminator());
1453 for (VPRecipeBase &R : *Plan.getMiddleBlock()) {
1454 VPValue *Op;
1456 continue;
1457
1458 // Compute the index of the last active lane.
1459 VPValue *LastActiveLane = Builder.createLastActiveLane(HeaderMask);
1460 auto *Ext =
1461 Builder.createNaryOp(VPInstruction::ExtractLane, {LastActiveLane, Op});
1462 R.getVPSingleValue()->replaceAllUsesWith(Ext);
1463 }
1464
1465 // VectorTripCount now equals TripCount so simplify the MiddleVPBB branch.
1469 m_Specific(&Plan.getVectorTripCount())))) &&
1470 "Unexpected MiddleVPBB branch");
1471 Plan.getMiddleBlock()->getTerminator()->setOperand(0, Plan.getTrue());
1472}
1473
1474/// Add an incoming value to all phis in \p VPBB for its just-added last
1475/// predecessor, re-using the value of the previously last one.
1477 for (VPRecipeBase &R : VPBB->phis()) {
1478 auto *Phi = cast<VPPhi>(&R);
1479 assert(Phi->getNumIncoming() == VPBB->getNumPredecessors() - 1 &&
1480 "must have incoming values for all predecessors but the new one");
1481 Phi->addIncoming(Phi->getIncomingValue(Phi->getNumIncoming() - 1));
1482 }
1483}
1484
1485/// Insert \p CheckBlockVPBB on the edge leading to the vector preheader,
1486/// connecting it to both vector and scalar preheaders. Updates scalar
1487/// preheader phis to account for the new predecessor.
1489 VPBasicBlock *CheckBlockVPBB) {
1490 VPBlockBase *VectorPH = Plan.getVectorPreheader();
1491 auto *ScalarPH = cast<VPBasicBlock>(Plan.getScalarPreheader());
1492 VPBlockBase *PreVectorPH = VectorPH->getSinglePredecessor();
1493 VPBlockUtils::insertOnEdge(PreVectorPH, VectorPH, CheckBlockVPBB);
1494 VPBlockUtils::connectBlocks(CheckBlockVPBB, ScalarPH);
1495 CheckBlockVPBB->swapSuccessors();
1497}
1498
1499VPIRBasicBlock *
1501 VPBasicBlock *MainCheck) {
1502 VPBasicBlock *VectorPH = EpiPlan.getVectorPreheader();
1503 assert(VectorPH && VectorPH->phis().empty() &&
1504 "vector preheader must exist and have no phis to update");
1505 auto *MainScalarPH = cast<VPIRBasicBlock>(MainPlan.getScalarPreheader());
1506 assert(MainScalarPH->getIRBasicBlock()->phis().empty() &&
1507 "MainPlan must not have generated phis in its scalar preheader");
1508 auto *EpilogueCheck =
1509 EpiPlan.createEmptyVPIRBasicBlock(MainScalarPH->getIRBasicBlock());
1510 VPBlockUtils::reassociateBlocks(EpiPlan.getEntry(), EpilogueCheck);
1511
1512 // Map blocks from MainPlan to new, empty VPIRBasicBlocks in EpiPlan, so the
1513 // skeleton CFG can be modeled explicitly. MainPlan's entry maps to EpiPlan's
1514 // now-disconnected entry and its scalar PH to EpilogueCheck.
1515 VPBlockBase *MainEntry = MainPlan.getEntry();
1517 MainToEpiVPBB[MainEntry] = EpiPlan.getEntry();
1519 MainEntry);
1521 // Skip entry block and exit blocks/scalar loop header; they are already
1522 // modeled in the epilogue plan.
1523 if (VPBB != MainEntry && VPBB != MainScalarPH && VPBB->hasSuccessors())
1524 MainToEpiVPBB[VPBB] =
1525 EpiPlan.createEmptyVPIRBasicBlock(VPBB->getIRBasicBlock());
1526 MainToEpiVPBB[MainScalarPH] = EpilogueCheck;
1527
1528 // First, connect the edges from the bypass blocks (minimum iteration checks,
1529 // runtime checks) to the scalar preheader, in reverse order, to preserve the
1530 // predecessor order of the generated IR. The middle block is the first
1531 // predecessor. MainCheck only bypasses the main vector loop; connect it to
1532 // the epilogue vector preheader instead.
1533 VPBasicBlock *EpiScalarPH = EpiPlan.getScalarPreheader();
1534 for (VPBlockBase *MainVPBB :
1535 reverse(drop_begin(MainScalarPH->predecessors()))) {
1536 VPBlockBase *EpiVPBB = MainToEpiVPBB.lookup(MainVPBB);
1537 if (MainVPBB == MainCheck) {
1538 VPBlockUtils::connectBlocks(EpiVPBB, VectorPH);
1539 continue;
1540 }
1541 VPBlockUtils::connectBlocks(EpiVPBB, EpiScalarPH);
1542 addIncomingForLastPredecessor(EpiScalarPH);
1543 }
1544
1545 // Mirror MainPlan's CFG, skipping the bypass edges connected above, which
1546 // come first, edges to blocks not modeled in EpiPlan and the main vector
1547 // loop's back-edge (to a block earlier in RPO), so EpiPlan contains no loop
1548 // it does not own.
1550 for (auto &[MainVPBB, EpiVPBB] : drop_end(MainToEpiVPBB)) {
1551 Visited.insert(MainVPBB);
1552 for (VPBlockBase *Succ :
1553 drop_begin(MainVPBB->getSuccessors(), EpiVPBB->getNumSuccessors()))
1554 if (auto *SuccVPBB = MainToEpiVPBB.lookup(Succ);
1555 SuccVPBB && !Visited.contains(Succ))
1556 VPBlockUtils::connectBlocks(EpiVPBB, SuccVPBB);
1557 }
1558 return EpilogueCheck;
1559}
1560
1561// Likelyhood of bypassing the vectorized loop due to a runtime check block,
1562// including memory overlap checks block and wrapping/unit-stride checks block.
1563static constexpr uint32_t CheckBypassWeights[] = {1, 127};
1564
1565/// Create a BranchOnCond terminator in \p CheckBlockVPBB. Optionally adds
1566/// branch weights.
1567static void addBypassBranch(VPlan &Plan, VPBasicBlock *CheckBlockVPBB,
1568 VPValue *Cond, bool AddBranchWeights) {
1570 auto *Term = VPBuilder(CheckBlockVPBB)
1572 if (AddBranchWeights) {
1573 MDBuilder MDB(Plan.getContext());
1574 MDNode *BranchWeights =
1575 MDB.createBranchWeights(CheckBypassWeights, /*IsExpected=*/false);
1576 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
1577 }
1578}
1579
1581 VPBasicBlock *CheckBlock,
1582 bool AddBranchWeights) {
1583 insertCheckBlockBeforeVectorLoop(Plan, CheckBlock);
1584 addBypassBranch(Plan, CheckBlock, Cond, AddBranchWeights);
1585}
1586
1588 BasicBlock *CheckBlock,
1589 bool AddBranchWeights) {
1590 VPValue *CondVPV = Plan.getOrAddLiveIn(Cond);
1591 VPBasicBlock *CheckBlockVPBB = Plan.createVPIRBasicBlock(CheckBlock);
1592 attachVPCheckBlock(Plan, CondVPV, CheckBlockVPBB, AddBranchWeights);
1593}
1594
1595/// Generate recipes for the memory runtime checks \p Checks of \p TheLoop
1596/// using \p Builder and return the condition that is true if any check fails.
1598 VPSCEVExpander &Expander,
1600 const Loop *TheLoop, ScalarEvolution &SE,
1601 DebugLoc DL) {
1602 // Expand each group's bounds once so all checks reuse the same frozen values.
1604 std::tuple<VPValue *, VPValue *, const SCEV *>, 8>
1605 GroupToBounds;
1606 for (const auto &[A, B] : Checks) {
1607 for (const RuntimeCheckingPtrGroup *CG : {A, B}) {
1608 if (GroupToBounds.contains(CG))
1609 continue;
1610 auto [Low, High, Stride] = getRuntimeCheckBounds(
1611 CG, TheLoop, SE, VectorizerParams::HoistRuntimeChecks);
1612 VPValue *Start = Expander.expand(Low);
1613 VPValue *End = Expander.expand(High);
1614 if (CG->NeedsFreeze) {
1615 Start = Builder.createFreeze(Start, DL);
1616 End = Builder.createFreeze(End, DL);
1617 }
1618 GroupToBounds[CG] = {Start, End, Stride};
1619 }
1620 }
1621
1622 VPValue *Cond = Plan.getFalse();
1623 SmallPtrSet<const SCEV *, 4> CheckedStrides;
1624 for (const auto &[A, B] : Checks) {
1625 auto [AStart, AEnd, AStride] = GroupToBounds[A];
1626 auto [BStart, BEnd, BStride] = GroupToBounds[B];
1627 VPValue *Bound0 =
1628 Builder.createICmp(CmpInst::ICMP_ULT, AStart, BEnd, DL, "bound0");
1629 VPValue *Bound1 =
1630 Builder.createICmp(CmpInst::ICMP_ULT, BStart, AEnd, DL, "bound1");
1631 VPValue *IsConflict =
1632 Builder.createAnd(Bound0, Bound1, DL, "found.conflict");
1633 for (const SCEV *Stride : {AStride, BStride}) {
1634 if (!Stride || !CheckedStrides.insert(Stride).second)
1635 continue;
1636 VPValue *StrideV = Expander.expand(Stride);
1637 VPValue *IsNegative = Builder.createICmp(
1638 CmpInst::ICMP_SLT, StrideV, Plan.getZero(StrideV->getScalarType()),
1639 DL, "stride.check");
1640 IsConflict = Builder.createOr(IsConflict, IsNegative, DL);
1641 }
1642 Cond = Builder.createOr(Cond, IsConflict, DL, "conflict.rdx");
1643 }
1644 return Cond;
1645}
1646
1647/// Generate recipes for the memory runtime difference checks \p Checks using
1648/// \p Builder and return the condition that is true if any check fails. Each
1649/// difference is compared against a threshold derived from \p VF and \p UF.
1651 VPSCEVExpander &Expander,
1654 unsigned UF, DebugLoc DL) {
1655 // Set of operand pairs of already created compares, to allow detecting and
1656 // re-using redundant compares.
1658 VPValue *Cond = Plan.getFalse();
1659 for (const auto &[SrcStart, SinkStart, AccessSize, NeedsFreeze] : Checks) {
1660 assert(UF * AccessSize > 0 &&
1661 "Threshold must be non-zero to use diff-check");
1662 Type *Ty = SinkStart->getType();
1663 const SCEV *TotalAccessSize = SE.getElementCount(Ty, VF * UF * AccessSize);
1664 const SCEV *ThresholdMinusOneSCEV =
1665 SE.getMinusSCEV(TotalAccessSize, SE.getOne(Ty));
1666 const SCEV *DiffSCEV = SE.getMinusSCEV(SinkStart, SrcStart);
1667
1668 // If the same compare has already been created earlier, there is no need to
1669 // check it again.
1670 if (!SeenCompares.insert({DiffSCEV, ThresholdMinusOneSCEV}).second)
1671 continue;
1672
1673 VPValue *ThresholdMinusOne = Expander.expand(ThresholdMinusOneSCEV);
1674 VPValue *Diff = Expander.expand(DiffSCEV);
1675 // Use (Diff - 1) <u (Threshold - 1), equivalent to 0 <u Diff <u Threshold,
1676 // to exclude Diff == 0 (equal pointers are safe).
1677 VPValue *DiffMinusOne =
1678 Builder.createSub(Diff, Plan.getConstantInt(Ty, 1), DL);
1679 VPValue *IsConflict = Builder.createICmp(
1680 CmpInst::ICMP_ULT, DiffMinusOne, ThresholdMinusOne, DL, "diff.check");
1681 if (NeedsFreeze)
1682 IsConflict = Builder.createFreeze(IsConflict, DL, "diff.check.fr");
1683 Cond = Builder.createOr(Cond, IsConflict, DL, "conflict.rdx");
1684 }
1685 return Cond;
1686}
1687
1689 VPlan &Plan, const RuntimePointerChecking &RtPtrChecking,
1690 const Loop *TheLoop, ScalarEvolution &SE, ElementCount VF, unsigned UF,
1691 bool AddBranchWeights) {
1692 assert(!RtPtrChecking.getChecks().empty() && "No checks to generate");
1693
1694 DebugLoc DL = TheLoop->getStartLoc();
1695 auto *MemCheckVPBB = Plan.createVPBasicBlock("vector.memcheck");
1696 VPBuilder Builder(MemCheckVPBB);
1697 VPSCEVExpander Expander(Builder, SE, DL, TheLoop->getParentLoop());
1698 auto DiffChecks = RtPtrChecking.getDiffChecks();
1699 VPValue *Cond =
1700 DiffChecks
1701 ? createDiffRuntimeChecks(Plan, Builder, Expander, *DiffChecks, SE,
1702 VF, UF, DL)
1703 : createRuntimeChecks(Plan, Builder, Expander,
1704 RtPtrChecking.getChecks(), TheLoop, SE, DL);
1705 attachVPCheckBlock(Plan, Cond, MemCheckVPBB, AddBranchWeights);
1706}
1707
1709 VPlan &Plan, ElementCount VF, unsigned UF,
1710 ElementCount MinProfitableTripCount, bool RequiresScalarEpilogue,
1711 bool TailFolded, Loop *OrigLoop, const uint32_t *MinItersBypassWeights,
1713 // Generate code to check if the loop's trip count is less than VF * UF, or
1714 // equal to it in case a scalar epilogue is required; this implies that the
1715 // vector trip count is zero. This check also covers the case where adding one
1716 // to the backedge-taken count overflowed leading to an incorrect trip count
1717 // of zero. In this case we will also jump to the scalar loop.
1718 CmpInst::Predicate CmpPred =
1719 RequiresScalarEpilogue ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
1720 // If tail is to be folded, vector loop takes care of all iterations.
1721 VPValue *TripCountVPV = Plan.getTripCount();
1722 const SCEV *TripCount = vputils::getSCEVExprForVPValue(TripCountVPV, PSE);
1723 Type *TripCountTy = TripCount->getType();
1724 ScalarEvolution &SE = *PSE.getSE();
1725 auto GetMinTripCount = [&]() -> const SCEV * {
1726 // Compute max(MinProfitableTripCount, UF * VF) and return it.
1727 const SCEV *VFxUF =
1728 SE.getElementCount(TripCountTy, (VF * UF), SCEV::FlagNUW);
1729 if (UF * VF.getKnownMinValue() >=
1730 MinProfitableTripCount.getKnownMinValue()) {
1731 // TODO: SCEV should be able to simplify test.
1732 return VFxUF;
1733 }
1734 const SCEV *MinProfitableTripCountSCEV =
1735 SE.getElementCount(TripCountTy, MinProfitableTripCount, SCEV::FlagNUW);
1736 return SE.getUMaxExpr(MinProfitableTripCountSCEV, VFxUF);
1737 };
1738
1739 VPBuilder Builder(CheckBlock);
1740 VPValue *TripCountCheck = Plan.getFalse();
1741 const SCEV *Step = GetMinTripCount();
1742 // TripCountCheck = false, folding tail implies positive vector trip
1743 // count.
1744 if (!TailFolded) {
1745 // TODO: Emit unconditional branch to vector preheader instead of
1746 // conditional branch with known condition.
1747 TripCount = SE.applyLoopGuards(TripCount, OrigLoop);
1748 // Check if the trip count is < the step.
1749 if (SE.isKnownPredicate(CmpPred, TripCount, Step)) {
1750 // TODO: Ensure step is at most the trip count when determining max VF and
1751 // UF, w/o tail folding.
1752 TripCountCheck = Plan.getTrue();
1753 } else if (!SE.isKnownPredicate(CmpInst::getInversePredicate(CmpPred),
1754 TripCount, Step)) {
1755 // Generate the minimum iteration check only if we cannot prove the
1756 // check is known to be true, or known to be false.
1757 VPValue *MinTripCountVPV =
1758 VPSCEVExpander(Builder, *PSE.getSE(), DL).expand(Step);
1759 TripCountCheck = Builder.createICmp(
1760 CmpPred, TripCountVPV, MinTripCountVPV, DL, "min.iters.check");
1761 } // else step known to be < trip count, use TripCountCheck preset to false.
1762 }
1763 VPInstruction *Term =
1764 Builder.createNaryOp(VPInstruction::BranchOnCond, {TripCountCheck}, DL);
1766 MDBuilder MDB(Plan.getContext());
1767 MDNode *BranchWeights = MDB.createBranchWeights(
1768 ArrayRef(MinItersBypassWeights, 2), /*IsExpected=*/false);
1769 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
1770 }
1771}
1772
1774 VPlan &Plan, ElementCount VF, unsigned UF, bool RequiresScalarEpilogue,
1775 Loop *OrigLoop, const uint32_t *MinItersBypassWeights, DebugLoc DL,
1777 auto *CheckBlock = Plan.createVPBasicBlock("vector.main.loop.iter.check");
1778 insertCheckBlockBeforeVectorLoop(Plan, CheckBlock);
1780 RequiresScalarEpilogue, /*TailFolded=*/false,
1781 OrigLoop, MinItersBypassWeights, DL, PSE,
1782 CheckBlock);
1783}
1784
1786 VPlan &Plan, VPValue *MainVectorTripCount, bool RequiresScalarEpilogue,
1787 ElementCount EpilogueVF, unsigned MainLoopStep, unsigned EpilogueLoopStep,
1788 ScalarEvolution &SE) {
1789 // Add the minimum iteration check for the epilogue vector loop.
1790 auto *EpilogueCheck =
1792
1793 // A tail-folded epilogue handles any number of remaining iterations, so the
1794 // epilogue check never branches to the scalar preheader.
1795 if (Plan.hasTailFolded()) {
1796 assert(!RequiresScalarEpilogue &&
1797 "Expected no scalar epilogue for tail-folded plan");
1798 VPBuilder(EpilogueCheck)
1800 return;
1801 }
1802
1803 VPBuilder Builder(cast<VPBasicBlock>(Plan.getEntry()));
1804 VPValue *TC = Plan.getTripCount();
1805 VPValue *VFxUF = Builder.createExpandSCEV(
1806 SE.getElementCount(TC->getScalarType(), EpilogueVF, SCEV::FlagNUW));
1807 Builder.setInsertPoint(EpilogueCheck);
1808 VPValue *Count = Builder.createSub(TC, MainVectorTripCount,
1809 DebugLoc::getUnknown(), "n.vec.remaining");
1810
1811 // Generate code to check if the loop's trip count is less than VF * UF of
1812 // the vector epilogue loop.
1813 auto P = RequiresScalarEpilogue ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
1814 auto *CheckMinIters = Builder.createICmp(
1815 P, Count, VFxUF, DebugLoc::getUnknown(), "min.epilog.iters.check");
1816 VPInstruction *Branch =
1817 Builder.createNaryOp(VPInstruction::BranchOnCond, CheckMinIters);
1818
1819 // We assume the remaining `Count` is equally distributed in
1820 // [0, MainLoopStep)
1821 // So the probability for `Count < EpilogueLoopStep` should be
1822 // min(MainLoopStep, EpilogueLoopStep) / MainLoopStep
1823 // TODO: Improve the estimate by taking the estimated trip count into
1824 // consideration.
1825 unsigned EstimatedSkipCount = std::min(MainLoopStep, EpilogueLoopStep);
1826 const uint32_t Weights[] = {EstimatedSkipCount,
1827 MainLoopStep - EstimatedSkipCount};
1828 MDBuilder MDB(Plan.getContext());
1829 MDNode *BranchWeights =
1830 MDB.createBranchWeights(Weights, /*IsExpected=*/false);
1831 Branch->setMetadata(LLVMContext::MD_prof, BranchWeights);
1832}
1833
1834/// Find and return the final select instruction of the FindIV result pattern
1835/// for the given \p BackedgeVal:
1836/// select(icmp ne ComputeReductionResult(ReducedIV), Sentinel),
1837/// ComputeReductionResult(ReducedIV), Start.
1839 return cast<VPInstruction>(
1840 vputils::findRecipe(BackedgeVal, [BackedgeVal](VPRecipeBase *R) {
1841 auto *VPI = dyn_cast<VPInstruction>(R);
1842 return VPI &&
1843 matchFindIVResult(VPI, m_Specific(BackedgeVal), m_VPValue());
1844 }));
1845}
1846
1848 auto GetMinOrMaxCompareValue =
1849 [](VPReductionPHIRecipe *RedPhiR) -> VPValue * {
1850 auto *MinOrMaxR =
1851 dyn_cast_or_null<VPRecipeWithIRFlags>(RedPhiR->getBackedgeValue());
1852 if (!MinOrMaxR)
1853 return nullptr;
1854
1855 // Check that MinOrMaxR is a VPWidenIntrinsicRecipe or VPReplicateRecipe
1856 // with an intrinsic that matches the reduction kind.
1857 Intrinsic::ID ExpectedIntrinsicID =
1858 getMinMaxReductionIntrinsicOp(RedPhiR->getRecurrenceKind());
1859 if (!match(MinOrMaxR, m_Intrinsic(ExpectedIntrinsicID)))
1860 return nullptr;
1861
1862 // MinOrMaxR must combine RedPhiR directly with the new element, as the NaN
1863 // check added below only covers the other operand.
1864 // TODO: Support multi-step min/max chains (e.g. maxnum(l, maxnum(k, phi)))
1865 // by checking all operands feeding the chain for NaNs.
1866 if (MinOrMaxR->getOperand(0) == RedPhiR)
1867 return MinOrMaxR->getOperand(1);
1868 if (MinOrMaxR->getOperand(1) == RedPhiR)
1869 return MinOrMaxR->getOperand(0);
1870 return nullptr;
1871 };
1872
1873 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
1875 MinOrMaxNumReductionsToHandle;
1876 bool HasUnsupportedPhi = false;
1877 for (auto &R : LoopRegion->getEntryBasicBlock()->phis()) {
1879 continue;
1880 auto *Cur = dyn_cast<VPReductionPHIRecipe>(&R);
1881 if (!Cur) {
1882 // TODO: Also support fixed-order recurrence phis.
1883 HasUnsupportedPhi = true;
1884 continue;
1885 }
1887 Cur->getRecurrenceKind())) {
1888 HasUnsupportedPhi = true;
1889 continue;
1890 }
1891
1892 VPValue *MinOrMaxOp = GetMinOrMaxCompareValue(Cur);
1893 if (!MinOrMaxOp)
1894 return false;
1895
1896 MinOrMaxNumReductionsToHandle.emplace_back(Cur, MinOrMaxOp);
1897 }
1898
1899 if (MinOrMaxNumReductionsToHandle.empty())
1900 return true;
1901
1902 // We won't be able to resume execution in the scalar tail, if there are
1903 // unsupported header phis or there is no scalar tail at all, due to
1904 // tail-folding.
1905 if (HasUnsupportedPhi || !Plan.hasScalarTail())
1906 return false;
1907
1908 // TODO: Support loops with uncountable early exits; their latch is not
1909 // terminated by BranchOnCount.
1910 VPBasicBlock *LatchVPBB = LoopRegion->getExitingBasicBlock();
1911 if (!match(LatchVPBB->getTerminator(), m_BranchOnCount()))
1912 return false;
1913
1914 /// Check if the vector loop of \p Plan can early exit and restart
1915 /// execution of last vector iteration in the scalar loop. This requires all
1916 /// recipes up to early exit point be side-effect free as they are
1917 /// re-executed. Currently we check that the loop is free of any recipe that
1918 /// may write to memory. Expected to operate on an early VPlan w/o nested
1919 /// regions.
1922 auto *VPBB = cast<VPBasicBlock>(VPB);
1923 for (auto &R : *VPBB) {
1924 if (R.mayWriteToMemory() && !match(&R, m_BranchOnCount()))
1925 return false;
1926 }
1927 }
1928
1929 // Freeze MinOrMaxOps since:
1930 // * multiple uses are introduced and the value may be undef
1931 // * they feed into a branch condition, so block poison propagation to
1932 // prevent immediate UB
1933 for (auto &[Phi, MinOrMaxOp] : MinOrMaxNumReductionsToHandle) {
1934 VPRecipeBase *MinOrMaxR = Phi->getBackedgeValue()->getDefiningRecipe();
1935 VPInstruction *Freeze = VPBuilder(MinOrMaxR).createFreeze(MinOrMaxOp);
1936 MinOrMaxR->replaceUsesOfWith(MinOrMaxOp, Freeze);
1937 MinOrMaxOp = Freeze;
1938 }
1939
1940 VPBuilder LatchBuilder(LatchVPBB->getTerminator());
1941 VPValue *AllNaNLanes = nullptr;
1942 SmallPtrSet<VPValue *, 2> RdxResults;
1943 for (const auto &[_, MinOrMaxOp] : MinOrMaxNumReductionsToHandle) {
1944 VPValue *RedNaNLanes =
1945 LatchBuilder.createFCmp(CmpInst::FCMP_UNO, MinOrMaxOp, MinOrMaxOp);
1946 AllNaNLanes = AllNaNLanes ? LatchBuilder.createOr(AllNaNLanes, RedNaNLanes)
1947 : RedNaNLanes;
1948 }
1949
1950 VPValue *AnyNaNLane =
1951 LatchBuilder.createNaryOp(VPInstruction::AnyOf, {AllNaNLanes});
1952 VPBasicBlock *MiddleVPBB = Plan.getMiddleBlock();
1953 VPBuilder MiddleBuilder(MiddleVPBB->begin());
1954 for (const auto &[RedPhiR, _] : MinOrMaxNumReductionsToHandle) {
1956 RedPhiR->getRecurrenceKind()) &&
1957 "unsupported reduction");
1958
1959 // If we exit early due to NaNs, compute the final reduction result based on
1960 // the reduction phi at the beginning of the last vector iteration.
1961 auto *RdxResult = vputils::findComputeReductionResult(RedPhiR);
1962 assert(RdxResult && "must find a ComputeReductionResult");
1963
1964 auto *NewSel = MiddleBuilder.createSelect(AnyNaNLane, RedPhiR,
1965 RdxResult->getOperand(0));
1966 RdxResult->setOperand(0, NewSel);
1967 assert(!RdxResults.contains(RdxResult) && "RdxResult already used");
1968 RdxResults.insert(RdxResult);
1969 }
1970
1971 auto *LatchExitingBranch = LatchVPBB->getTerminator();
1972 assert(match(LatchExitingBranch, m_BranchOnCount(m_VPValue(), m_VPValue())) &&
1973 "Unexpected terminator");
1974 auto *IsLatchExitTaken = LatchBuilder.createICmp(
1975 CmpInst::ICMP_EQ, LatchExitingBranch->getOperand(0),
1976 LatchExitingBranch->getOperand(1));
1977 auto *AnyExitTaken = LatchBuilder.createOr(AnyNaNLane, IsLatchExitTaken);
1978 LatchBuilder.createNaryOp(VPInstruction::BranchOnCond, AnyExitTaken);
1979 LatchExitingBranch->eraseFromParent();
1980
1981 // Update resume phis for inductions in the scalar preheader. If AnyNaNLane is
1982 // true, the resume from the start of the last vector iteration via the
1983 // canonical IV, otherwise from the original value.
1984 auto IsTC = [&Plan](VPValue *V) {
1985 return V == &Plan.getVectorTripCount() || V == Plan.getTripCount();
1986 };
1987 for (auto &R : Plan.getScalarPreheader()->phis()) {
1988 auto *ResumeR = cast<VPPhi>(&R);
1989 VPValue *VecV = ResumeR->getOperand(0);
1990 if (RdxResults.contains(VecV))
1991 continue;
1992 if (auto *DerivedIV = dyn_cast<VPDerivedIVRecipe>(VecV)) {
1993 VPValue *DIVTC = DerivedIV->getOperand(1);
1994 if (DerivedIV->hasOneUse() && IsTC(DIVTC)) {
1995 auto *NewSel = MiddleBuilder.createSelect(
1996 AnyNaNLane, LoopRegion->getCanonicalIV(), DIVTC);
1997 DerivedIV->moveAfter(MiddleBuilder.getRecipeAtInsertPoint());
1998 DerivedIV->setOperand(1, NewSel);
1999 continue;
2000 }
2001 }
2002 // Bail out and abandon the current, partially modified, VPlan if we
2003 // encounter resume phi that cannot be updated yet.
2004 if (!IsTC(VecV)) {
2005 LLVM_DEBUG(dbgs() << "Found resume phi we cannot update for VPlan with "
2006 "FMaxNum/FMinNum reduction.\n");
2007 return false;
2008 }
2009 auto *NewSel = MiddleBuilder.createSelect(
2010 AnyNaNLane, LoopRegion->getCanonicalIV(), VecV);
2011 ResumeR->setOperand(0, NewSel);
2012 }
2013
2014 auto *MiddleTerm = MiddleVPBB->getTerminator();
2015 MiddleBuilder.setInsertPoint(MiddleTerm);
2016 VPValue *MiddleCond = MiddleTerm->getOperand(0);
2017 VPValue *NewCond =
2018 MiddleBuilder.createAnd(MiddleCond, MiddleBuilder.createNot(AnyNaNLane));
2019 MiddleTerm->setOperand(0, NewCond);
2020 return true;
2021}
2022
2024 if (Plan.hasScalarVFOnly())
2025 return false;
2026
2027 // We want to create the following nodes:
2028 // vector.body:
2029 // ...new WidenPHI recipe introduced to keep the mask value for the latest
2030 // iteration where any lane was active.
2031 // mask.phi = phi [ ir<false>, vector.ph ], [ vp<new.mask>, vector.body ]
2032 // ...data.phi (a VPReductionPHIRecipe for a FindLast reduction) already
2033 // exists, but needs updating to use 'new.data' for the backedge value.
2034 // data.phi = phi ir<default.val>, vp<new.data>
2035 //
2036 // ...'data' and 'compare' created by existing nodes...
2037 //
2038 // ...new recipes introduced to determine whether to update the reduction
2039 // values or keep the current one.
2040 // any.active = i1 any-of ir<compare>
2041 // new.mask = select vp<any.active>, ir<compare>, vp<mask.phi>
2042 // new.data = select vp<any.active>, ir<data>, ir<data.phi>
2043 //
2044 // middle.block:
2045 // ...extract-last-active replaces compute-reduction-result.
2046 // result = extract-last-active vp<new.data>, vp<new.mask>, ir<default.val>
2047
2052 PhiR.getRecurrenceKind()))
2053 Phis.push_back(&PhiR);
2054 }
2055
2056 if (Phis.empty())
2057 return true;
2058
2059 VPValue *HeaderMask = Plan.getVectorLoopRegion()->getHeaderMask();
2060 for (VPReductionPHIRecipe *PhiR : Phis) {
2061 // Find the condition for the select/blend.
2062 VPValue *BackedgeSelect = PhiR->getBackedgeValue();
2063 VPValue *CondSelect = BackedgeSelect;
2064
2065 // If there's a header mask, the backedge select will not be the find-last
2066 // select.
2067 if (HeaderMask &&
2068 !match(BackedgeSelect,
2069 m_SelectLike(m_Specific(HeaderMask), m_VPValue(CondSelect),
2070 m_Specific(PhiR))))
2071 return false;
2072
2073 VPValue *Cond = nullptr, *Op1 = nullptr, *Op2 = nullptr;
2074
2075 // If we're matching a blend rather than a select, there should be one
2076 // incoming value which is the data, then all other incoming values should
2077 // be the phi.
2078 auto MatchBlend = [&](VPRecipeBase *R) {
2079 auto *Blend = dyn_cast<VPBlendRecipe>(R);
2080 if (!Blend)
2081 return false;
2082 assert(!Blend->isNormalized() && "must run before blend normalizaion");
2083 unsigned NumIncomingDataValues = 0;
2084 for (unsigned I = 0; I < Blend->getNumIncomingValues(); ++I) {
2085 VPValue *Incoming = Blend->getIncomingValue(I);
2086 if (Incoming != PhiR) {
2087 ++NumIncomingDataValues;
2088 Cond = Blend->getMask(I);
2089 Op1 = Incoming;
2090 Op2 = PhiR;
2091 }
2092 }
2093 return NumIncomingDataValues == 1;
2094 };
2095
2096 VPSingleDefRecipe *SelectR =
2098 if (!match(SelectR,
2099 m_Select(m_VPValue(Cond), m_VPValue(Op1), m_VPValue(Op2))) &&
2100 !MatchBlend(SelectR))
2101 return false;
2102
2103 // Bail out if PhiR has users other than the find-last select/blend and the
2104 // header mask select, e.g. nested blends. Then the data operand may be PhiR
2105 // on some paths and Cond does not determine the lanes to update.
2106 if (any_of(PhiR->users(), [&](VPUser *U) {
2107 return U != SelectR && U != BackedgeSelect->getDefiningRecipe();
2108 }))
2109 return false;
2110
2111 assert(Cond != HeaderMask && "Cond must not be HeaderMask");
2112
2113 // Find final reduction computation and replace it with an
2114 // extract.last.active intrinsic.
2115 auto *RdxResult =
2117 assert(RdxResult && "Could not find reduction result");
2118
2119 // Add mask phi.
2120 VPBuilder Builder = VPBuilder::getToInsertAfter(PhiR);
2121 auto *MaskPHI = Builder.createWidenPhi(Plan.getFalse());
2122
2123 // Add select for mask.
2124 Builder.setInsertPoint(SelectR);
2125
2126 if (Op1 == PhiR) {
2127 // Normalize to selecting the data operand when the condition is true by
2128 // swapping operands and negating the condition.
2129 std::swap(Op1, Op2);
2130 Cond = Builder.createNot(Cond);
2131 }
2132 assert(Op2 == PhiR && "data value must be selected if Cond is true");
2133
2134 if (HeaderMask)
2135 Cond = Builder.createLogicalAnd(HeaderMask, Cond);
2136
2137 Cond = Builder.createFreeze(Cond);
2138 VPValue *AnyOf = Builder.createNaryOp(VPInstruction::AnyOf, Cond);
2139 VPValue *MaskSelect = Builder.createSelect(AnyOf, Cond, MaskPHI);
2140 MaskPHI->addIncoming(MaskSelect);
2141
2142 // Replace select for data.
2143 VPValue *DataSelect =
2144 Builder.createSelect(AnyOf, Op1, Op2, SelectR->getDebugLoc());
2145 SelectR->replaceAllUsesWith(DataSelect);
2146 PhiR->setBackedgeValue(DataSelect);
2147 SelectR->eraseFromParent();
2148
2149 Builder.setInsertPoint(RdxResult);
2150 auto *ExtractLastActive =
2151 Builder.createNaryOp(VPInstruction::ExtractLastActive,
2152 {PhiR->getStartValue(), DataSelect, MaskSelect},
2153 RdxResult->getDebugLoc());
2154 RdxResult->replaceAllUsesWith(ExtractLastActive);
2155 RdxResult->eraseFromParent();
2156 }
2157
2158 return true;
2159}
2160
2161/// Given a first argmin/argmax pattern with strict predicate consisting of
2162/// 1) a MinOrMax reduction \p MinOrMaxPhiR producing \p MinOrMaxResult,
2163/// 2) a wide induction \p WideIV,
2164/// 3) a FindLastIV reduction \p FindLastIVPhiR using \p WideIV,
2165/// return the smallest index of the FindLastIV reduction result using UMin,
2166/// unless \p MinOrMaxResult equals the start value of its MinOrMax reduction.
2167/// In that case, return the start value of the FindLastIV reduction instead.
2168/// If \p WideIV is not canonical, a new canonical wide IV is added, and the
2169/// final result is scaled back to the non-canonical \p WideIV.
2170/// The final value of the FindLastIV reduction is originally computed using
2171/// \p FindIVSelect, \p FindIVCmp, and \p FindIVRdxResult, which are replaced
2172/// and removed.
2173/// Returns true if the pattern was handled successfully, false otherwise.
2175 VPlan &Plan, VPReductionPHIRecipe *MinOrMaxPhiR,
2176 VPReductionPHIRecipe *FindLastIVPhiR, VPWidenIntOrFpInductionRecipe *WideIV,
2177 VPInstruction *MinOrMaxResult, VPInstruction *FindIVSelect,
2178 VPRecipeBase *FindIVCmp, VPInstruction *FindIVRdxResult) {
2179 assert(!FindLastIVPhiR->isInLoop() && !FindLastIVPhiR->isOrdered() &&
2180 "inloop and ordered reductions not supported");
2181 assert(FindLastIVPhiR->getVFScaleFactor() == 1 &&
2182 "FindIV reduction must not be scaled");
2183
2184 // TODO: support for FP in handleFirstArgMinOrMax
2186 MinOrMaxPhiR->getRecurrenceKind()))
2187 return false;
2188
2190 // TODO: Support non (i.e., narrower than) canonical IV types.
2191 // TODO: Emit remarks for failed transformations.
2192 if (Ty != WideIV->getScalarType())
2193 return false;
2194
2195 VPValue *HeaderMask = Plan.getVectorLoopRegion()->getHeaderMask();
2196 auto *BackedgeVal = FindLastIVPhiR->getBackedgeValue();
2197 auto *FindIVSelectVal = BackedgeVal;
2198 if (HeaderMask && !match(BackedgeVal, m_Select(m_Specific(HeaderMask),
2199 m_VPValue(FindIVSelectVal),
2200 m_Specific(FindLastIVPhiR))))
2201 return false;
2202 auto *FindIVSelectR =
2203 cast<VPSingleDefRecipe>(FindIVSelectVal->getDefiningRecipe());
2204
2205 assert(
2206 match(FindIVSelectR, m_Select(m_VPValue(), m_VPValue(), m_VPValue())) &&
2207 "backedge value must be a select");
2208 if (FindIVSelectR->getOperand(1) != WideIV &&
2209 FindIVSelectR->getOperand(2) != WideIV)
2210 return false;
2211
2212 // If the original wide IV is not canonical, create a new one. The canonical
2213 // wide IV is guaranteed to not wrap for all lanes that are active in the
2214 // vector loop.
2215 if (!WideIV->isCanonical()) {
2216 VPIRValue *Zero = Plan.getConstantInt(Ty, 0);
2217 VPIRValue *One = Plan.getConstantInt(Ty, 1);
2218 auto *WidenCanIV = new VPWidenIntOrFpInductionRecipe(
2219 nullptr, Zero, One, WideIV->getVFValue(),
2220 WideIV->getInductionDescriptor(),
2221 VPIRFlags::WrapFlagsTy(/*HasNUW=*/true, /*HasNSW=*/false),
2222 WideIV->getDebugLoc());
2223 WidenCanIV->insertBefore(WideIV);
2224
2225 // Update the select to use the wide canonical IV.
2226 FindIVSelectR->setOperand(FindIVSelectR->getOperand(1) == WideIV ? 1 : 2,
2227 WidenCanIV);
2228 }
2229 FindLastIVPhiR->setOperand(0, Plan.getPoison(Ty));
2230
2231 // The reduction using MinOrMaxPhiR needs adjusting to compute the correct
2232 // result:
2233 // 1. Find the first canonical indices corresponding to partial min/max
2234 // values, using loop reductions.
2235 // 2. Find which of the partial min/max values are equal to the overall
2236 // min/max value.
2237 // 3. Select among the canonical indices those corresponding to the overall
2238 // min/max value.
2239 // 4. Find the first canonical index of overall min/max and scale it back to
2240 // the original IV using VPDerivedIVRecipe.
2241 // 5. If the overall min/max equals the starting min/max, the condition in
2242 // the loop was always false, due to being strict; return the start value
2243 // of FindLastIVPhiR in that case.
2244 //
2245 // For example, we transforms two independent reduction result computations
2246 // for
2247 //
2248 // <x1> vector loop: {
2249 // vector.body:
2250 // ...
2251 // ir<%iv> = WIDEN-INDUCTION nuw nsw ir<10>, ir<1>, vp<%0>
2252 // WIDEN-REDUCTION-PHI ir<%min.idx> = phi ir<sentinel.min.start>,
2253 // ir<%min.idx.next>
2254 // WIDEN-REDUCTION-PHI ir<%min.val> = phi ir<100>, ir<%min.val.next>
2255 // ....
2256 // WIDEN-INTRINSIC ir<%min.val.next> = call llvm.umin(ir<%min.val>, ir<%l>)
2257 // WIDEN ir<%min.idx.next> = select ir<%cmp>, ir<%iv>, ir<%min.idx>
2258 // ...
2259 // }
2260 // Successor(s): middle.block
2261 //
2262 // middle.block:
2263 // vp<%iv.rdx> = compute-reduction-result (smax) vp<%min.idx.next>
2264 // vp<%min.result> = compute-reduction-result (umin) ir<%min.val.next>
2265 // vp<%cmp> = icmp ne vp<%iv.rdx>, ir<sentinel.min.start>
2266 // vp<%find.iv.result> = select vp<%cmp>, vp<%iv.rdx>, ir<10>
2267 //
2268 //
2269 // Into:
2270 //
2271 // vp<%reduced.min> = compute-reduction-result (umin) ir<%min.val.next>
2272 // vp<%reduced.mins.mask> = icmp eq ir<%min.val.next>, vp<%reduced.min>
2273 // vp<%idxs2reduce> = select vp<%reduced.mins.mask>, ir<%min.idx.next>,
2274 // ir<MaxUInt>
2275 // vp<%reduced.idx> = compute-reduction-result (umin) vp<%idxs2reduce>
2276 // vp<%scaled.idx> = DERIVED-IV ir<20> + vp<%reduced.idx> * ir<1>
2277 // vp<%always.false> = icmp eq vp<%reduced.min>, ir<100>
2278 // vp<%final.idx> = select vp<%always.false>, ir<10>,
2279 // vp<%scaled.idx>
2280
2281 VPBuilder Builder(FindIVRdxResult);
2282 VPValue *MinOrMaxExiting = MinOrMaxResult->getOperand(0);
2283 auto *FinalMinOrMaxCmp =
2284 Builder.createICmp(CmpInst::ICMP_EQ, MinOrMaxExiting, MinOrMaxResult);
2285 VPValue *LastIVExiting = FindIVRdxResult->getOperand(0);
2286 VPValue *MaxIV =
2287 Plan.getConstantInt(APInt::getMaxValue(Ty->getIntegerBitWidth()));
2288 auto *FinalIVSelect =
2289 Builder.createSelect(FinalMinOrMaxCmp, LastIVExiting, MaxIV);
2290 VPIRFlags RdxFlags(RecurKind::UMin, false, false, FastMathFlags());
2291 VPSingleDefRecipe *FinalCanIV = Builder.createNaryOp(
2292 VPInstruction::ComputeReductionResult, {FinalIVSelect}, RdxFlags,
2293 FindIVRdxResult->getDebugLoc());
2294
2295 // If we used a new wide canonical IV convert the reduction result back to the
2296 // original IV scale before the final select.
2297 if (!WideIV->isCanonical()) {
2298 auto *DerivedIVRecipe = new VPDerivedIVRecipe(
2300 nullptr, // No FPBinOp for integer induction
2301 WideIV->getStartValue(), FinalCanIV, WideIV->getStepValue());
2302 DerivedIVRecipe->insertBefore(Builder.getRecipeAtInsertPoint());
2303 FinalCanIV = DerivedIVRecipe;
2304 }
2305
2306 // If the final min/max value matches its start value, the condition in the
2307 // loop was always false, i.e. no induction value has been selected. If that's
2308 // the case, set the result of the IV reduction to its start value.
2309 VPValue *AlwaysFalse = Builder.createICmp(CmpInst::ICMP_EQ, MinOrMaxResult,
2310 MinOrMaxPhiR->getStartValue());
2311 VPValue *FinalIV = Builder.createSelect(
2312 AlwaysFalse, FindIVSelect->getOperand(2), FinalCanIV);
2313 FindIVSelect->replaceAllUsesWith(FinalIV);
2314
2315 // Erase the old FindIV result pattern which is now dead.
2316 FindIVSelect->eraseFromParent();
2317 FindIVCmp->eraseFromParent();
2318 FindIVRdxResult->eraseFromParent();
2319 return true;
2320}
2321
2324 Loop *TheLoop) {
2325 for (auto &PhiR : make_early_inc_range(
2327 auto *MinOrMaxPhiR = dyn_cast<VPReductionPHIRecipe>(&PhiR);
2328 // TODO: check for multi-uses in VPlan directly.
2329 if (!MinOrMaxPhiR || !MinOrMaxPhiR->hasUsesOutsideReductionChain())
2330 continue;
2331
2332 // MinOrMaxPhiR has users outside the reduction cycle in the loop. Check if
2333 // the only other user is a FindLastIV reduction. MinOrMaxPhiR must have
2334 // exactly 2 users if not tailfolded:
2335 // 1) the min/max operation of the reduction cycle, and
2336 // 2) the compare of a FindLastIV reduction cycle. This compare must match
2337 // the min/max operation - comparing MinOrMaxPhiR with the operand of the
2338 // min/max operation, and be used only by the select of the FindLastIV
2339 // reduction cycle.
2340 // There is an additional user if the tail was folded:
2341 // 3) the select operation of the vector.latch block. This select uses the
2342 // original MinOrMaxPhiR if the mask is zero.
2343 RecurKind RdxKind = MinOrMaxPhiR->getRecurrenceKind();
2344 assert(
2346 "only min/max recurrences support users outside the reduction chain");
2347
2348 auto *MinOrMaxBackedgeR =
2349 dyn_cast<VPRecipeWithIRFlags>(MinOrMaxPhiR->getBackedgeValue());
2350 if (!MinOrMaxBackedgeR)
2351 return false;
2352
2353 // If the tail was folded then the backedge won't be the
2354 // reduction-intrinsic but the select in the vector.latch block that wraps
2355 // the reduction-intrinsic.
2356 auto *MinOrMaxOp = MinOrMaxBackedgeR;
2357 VPValue *HeaderMask = Plan.getVectorLoopRegion()->getHeaderMask();
2358 VPValue *MinOrMaxTailfold;
2359 if (HeaderMask) {
2360 if (!match(MinOrMaxBackedgeR, m_SelectLike(m_Specific(HeaderMask),
2361 m_VPValue(MinOrMaxTailfold),
2362 m_Specific(MinOrMaxPhiR))))
2363 return false;
2364
2365 MinOrMaxOp = dyn_cast<VPRecipeWithIRFlags>(MinOrMaxTailfold);
2366 if (!MinOrMaxOp)
2367 return false;
2368 }
2369
2370 // Check that MinOrMaxOp is a VPWidenIntrinsicRecipe or
2371 // VPReplicateRecipe with an intrinsic that matches the reduction kind.
2372 Intrinsic::ID ExpectedIntrinsicID = getMinMaxReductionIntrinsicOp(RdxKind);
2373 if (!match(MinOrMaxOp, m_Intrinsic(ExpectedIntrinsicID)))
2374 return false;
2375
2376 // Tailfolded MinOrMaxOp should only feed into the predicated
2377 // select MinOrMaxBackedgeR.
2378 assert((!HeaderMask || MinOrMaxOp->getNumUsers() == 1) &&
2379 "Tailfolded MinOrMaxOp must have exactly 1 user");
2380 // MinOrMaxBackedgeR must have 2 users: 1) MinOrMaxPhiR and 2)
2381 // ComputeReductionResult.
2382 assert(MinOrMaxBackedgeR->getNumUsers() == 2 &&
2383 "MinOrMaxBackedgeR must have exactly 2 users");
2384 // MinOrMaxOp must combine MinOrMaxPhiR directly with the new element;
2385 // reject multi-step min/max chains (e.g. max(l, max(k, phi))), which
2386 // this transform does not handle.
2387 VPValue *MinOrMaxOpValue;
2388 if (MinOrMaxOp->getOperand(0) == MinOrMaxPhiR)
2389 MinOrMaxOpValue = MinOrMaxOp->getOperand(1);
2390 else if (MinOrMaxOp->getOperand(1) == MinOrMaxPhiR)
2391 MinOrMaxOpValue = MinOrMaxOp->getOperand(0);
2392 else
2393 return false;
2394
2395 VPValue *CmpOpA;
2396 VPValue *CmpOpB;
2397 CmpPredicate Pred;
2399 MinOrMaxPhiR, m_Cmp(Pred, m_VPValue(CmpOpA), m_VPValue(CmpOpB)));
2400 if (!Cmp || Cmp->getNumUsers() != 1 ||
2401 (CmpOpA != MinOrMaxOpValue && CmpOpB != MinOrMaxOpValue))
2402 return false;
2403
2404 if (MinOrMaxOpValue != CmpOpB)
2405 Pred = CmpInst::getSwappedPredicate(Pred);
2406
2407 // MinOrMaxPhiR must have exactly 2 users if not tailfolded:
2408 // * MinOrMaxOp,
2409 // * Cmp (that's part of a FindLastIV chain).
2410 // Also an additional third user if it is tailfolded:
2411 // * Predicated HEADER-MASK select in the vector.latch block.
2412 if (MinOrMaxPhiR->getNumUsers() != (HeaderMask ? 3 : 2))
2413 return false;
2414
2415 VPInstruction *MinOrMaxResult =
2417 MinOrMaxBackedgeR);
2418 assert(MinOrMaxResult &&
2419 "MinOrMaxResult must be a user of MinOrMaxBackedgeR");
2420
2421 // Cmp must be used by the select of a FindLastIV chain.
2422 VPValue *Sel = dyn_cast<VPSingleDefRecipe>(Cmp->getSingleUser());
2423 VPValue *IVOp, *FindIV;
2424 if (!Sel || (Sel->getNumUsers() != (HeaderMask ? 1 : 2)) ||
2425 !match(Sel,
2427 return false;
2428
2430 std::swap(FindIV, IVOp);
2431 Pred = CmpInst::getInversePredicate(Pred);
2432 }
2433
2434 auto *FindIVPhiR = dyn_cast<VPReductionPHIRecipe>(FindIV);
2436 FindIVPhiR->getRecurrenceKind()))
2437 return false;
2438
2439 assert(!FindIVPhiR->isInLoop() && !FindIVPhiR->isOrdered() &&
2440 "cannot handle inloop/ordered reductions yet");
2441
2442 // Check if FindIVPhiR is a FindLast pattern by checking the MinMaxKind
2443 // on its ComputeReductionResult. SMax/UMax indicates FindLast.
2444 VPInstruction *FindIVResult =
2446 FindIVPhiR->getBackedgeValue());
2447 assert(FindIVResult &&
2448 "must be able to retrieve the FindIVResult VPInstruction");
2449 RecurKind FindIVMinMaxKind = FindIVResult->getRecurKind();
2450 if (FindIVMinMaxKind != RecurKind::SMax &&
2451 FindIVMinMaxKind != RecurKind::UMax)
2452 return false;
2453
2454 // TODO: Support cases where IVOp is the IV increment.
2455 if (!match(IVOp, m_TruncOrSelf(m_VPValue(IVOp))) ||
2457 return false;
2458
2459 // Check if the predicate is compatible with the reduction kind.
2460 bool IsValidKindPred = [RdxKind, Pred]() {
2461 switch (RdxKind) {
2462 case RecurKind::UMin:
2463 return Pred == CmpInst::ICMP_UGE || Pred == CmpInst::ICMP_UGT;
2464 case RecurKind::UMax:
2465 return Pred == CmpInst::ICMP_ULE || Pred == CmpInst::ICMP_ULT;
2466 case RecurKind::SMax:
2467 return Pred == CmpInst::ICMP_SLE || Pred == CmpInst::ICMP_SLT;
2468 case RecurKind::SMin:
2469 return Pred == CmpInst::ICMP_SGE || Pred == CmpInst::ICMP_SGT;
2470 case RecurKind::FMax:
2472 return Pred == CmpInst::FCMP_OLE || Pred == CmpInst::FCMP_OLT;
2473 case RecurKind::FMin:
2475 return Pred == CmpInst::FCMP_OGE || Pred == CmpInst::FCMP_OGT;
2476 // minnum and maxnum need special handling due to expected sNaN behaviour
2477 // minimum and maximum return NaN if either input is a NAN
2478 case RecurKind::FMinNum:
2479 case RecurKind::FMaxNum:
2482 return false;
2483 default:
2484 llvm_unreachable("unhandled recurrence kind");
2485 }
2486 }();
2487 if (!IsValidKindPred) {
2488 ORE->emit([&]() {
2490 DEBUG_TYPE, "VectorizationMultiUseReductionPredicate",
2491 TheLoop->getStartLoc(), TheLoop->getHeader())
2492 << "Multi-use reduction with predicate "
2494 << " incompatible with reduction kind";
2495 });
2496 return false;
2497 }
2498
2499 if (RdxKind == RecurKind::FMaximumNum ||
2500 RdxKind == RecurKind::FMinimumNum) {
2501 auto *StartC = dyn_cast<VPConstant>(MinOrMaxPhiR->getStartValue());
2502 if (!StartC || StartC->getConstant()->isNaN())
2503 return false;
2504 }
2505
2506 auto *FindIVSelect = findFindIVSelect(FindIVPhiR->getBackedgeValue());
2507 auto *FindIVCmp = FindIVSelect->getOperand(0)->getDefiningRecipe();
2508 auto *FindIVRdxResult = cast<VPInstruction>(FindIVCmp->getOperand(0));
2509 assert(FindIVSelect->getParent() == MinOrMaxResult->getParent() &&
2510 "both results must be computed in the same block");
2511 // Reducing to a scalar min or max value is placed right before reducing to
2512 // its scalar iteration, in order to generate instructions that use both
2513 // their operands.
2514 MinOrMaxResult->moveBefore(FindIVRdxResult->getIterator());
2515
2516 bool IsStrictPredicate = CmpInst::isStrictPredicate(Pred);
2517 if (IsStrictPredicate) {
2518 if (!handleFirstArgMinOrMax(Plan, MinOrMaxPhiR, FindIVPhiR,
2520 MinOrMaxResult, FindIVSelect, FindIVCmp,
2521 FindIVRdxResult))
2522 return false;
2523 continue;
2524 }
2525
2526 // The reduction using MinOrMaxPhiR needs adjusting to compute the correct
2527 // result:
2528 // 1. We need to find the last IV for which the condition based on the
2529 // min/max recurrence is true,
2530 // 2. Compare the partial min/max reduction result to its final value and,
2531 // 3. Select the lanes of the partial FindLastIV reductions which
2532 // correspond to the lanes matching the min/max reduction result.
2533 //
2534 // For example, this transforms
2535 // vp<%min.result> = compute-reduction-result ir<%min.val.next>
2536 // vp<%iv.rdx> = compute-reduction-result (smax) vp<%min.idx.next>
2537 // vp<%cmp> = icmp ne vp<%iv.rdx>, SENTINEL
2538 // vp<%find.iv.result> = select vp<%cmp>, vp<%iv.rdx>, ir<0>
2539 //
2540 // into:
2541 //
2542 // vp<min.result> = compute-reduction-result ir<%min.val.next>
2543 // vp<%final.min.cmp> = icmp eq ir<%min.val.next>, vp<min.result>
2544 // vp<%final.iv> = select vp<%final.min.cmp>, vp<%min.idx.next>, SENTINEL
2545 // vp<%iv.rdx> = compute-reduction-result (smax) vp<%final.iv>
2546 // vp<%cmp> = icmp ne vp<%iv.rdx>, SENTINEL
2547 // vp<%find.iv.result> = select vp<%cmp>, vp<%iv.rdx>, ir<0>
2548 //
2549 VPBuilder B(FindIVRdxResult);
2550 VPValue *MinOrMaxExiting = MinOrMaxResult->getOperand(0);
2551 auto *FinalMinOrMaxCmp =
2553 ? B.createICmp(CmpInst::ICMP_EQ, MinOrMaxExiting, MinOrMaxResult)
2554 : B.createFCmp(CmpInst::FCMP_OEQ, MinOrMaxExiting, MinOrMaxResult);
2555 VPValue *Sentinel = FindIVCmp->getOperand(1);
2556 VPValue *LastIVExiting = FindIVRdxResult->getOperand(0);
2557 auto *FinalIVSelect =
2558 B.createSelect(FinalMinOrMaxCmp, LastIVExiting, Sentinel);
2559 FindIVRdxResult->setOperand(0, FinalIVSelect);
2560 }
2561 return true;
2562}
2563
2565 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
2566 VPValue *HeaderMask = LoopRegion->getHeaderMask();
2567 Type *I1Ty = IntegerType::getInt1Ty(Plan.getContext());
2568
2569 VPBuilder Builder(Plan.getVectorPreheader());
2570 auto *AliasMask = Builder.createNaryOp(
2571 VPInstruction::IncomingAliasMask, {}, nullptr, {}, {},
2572 DebugLoc::getUnknown(), "incoming.alias.mask", I1Ty);
2573
2574 VPBasicBlock *Header = LoopRegion->getEntryBasicBlock();
2575 Builder = VPBuilder(Header->getFirstNonPhi());
2576
2577 // Update all existing users of the header mask to "HeaderMask & AliasMask".
2578 auto *ClampedHeaderMask = Builder.createAnd(HeaderMask, AliasMask);
2579 HeaderMask->replaceUsesWithIf(ClampedHeaderMask,
2580 not_equal_to(ClampedHeaderMask));
2581}
SDValue Pred
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define DEBUG_TYPE
#define _
iv Induction Variable Users
Definition IVUsers.cpp:48
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
static constexpr uint32_t MinItersBypassWeights[]
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t High
#define P(N)
SmallVector< MachineOperand, 4 > Cond
Provides some synthesis utilities to produce sequences of values.
This file defines less commonly used SmallVector utilities.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
static bool isHeaderBB(BasicBlock *BB, Loop *L)
static bool handleFirstArgMinOrMax(VPlan &Plan, VPReductionPHIRecipe *MinOrMaxPhiR, VPReductionPHIRecipe *FindLastIVPhiR, VPWidenIntOrFpInductionRecipe *WideIV, VPInstruction *MinOrMaxResult, VPInstruction *FindIVSelect, VPRecipeBase *FindIVCmp, VPInstruction *FindIVRdxResult)
Given a first argmin/argmax pattern with strict predicate consisting of 1) a MinOrMax reduction MinOr...
static VPHeaderPHIRecipe * createWidenInductionRecipe(PHINode *Phi, VPPhi *PhiR, VPIRValue *Start, const InductionDescriptor &IndDesc, VPlan &Plan, PredicatedScalarEvolution &PSE, Loop &OrigLoop, DebugLoc DL)
Creates a VPWidenIntOrFpInductionRecipe or VPWidenPointerInductionRecipe for Phi based on IndDesc.
static void addIncomingForLastPredecessor(VPBasicBlock *VPBB)
Add an incoming value to all phis in VPBB for its just-added last predecessor, re-using the value of ...
static void insertCheckBlockBeforeVectorLoop(VPlan &Plan, VPBasicBlock *CheckBlockVPBB)
Insert CheckBlockVPBB on the edge leading to the vector preheader, connecting it to both vector and s...
static void addBypassBranch(VPlan &Plan, VPBasicBlock *CheckBlockVPBB, VPValue *Cond, bool AddBranchWeights)
Create a BranchOnCond terminator in CheckBlockVPBB.
static VPValue * createDiffRuntimeChecks(VPlan &Plan, VPBuilder &Builder, VPSCEVExpander &Expander, ArrayRef< PointerDiffInfo > Checks, ScalarEvolution &SE, ElementCount VF, unsigned UF, DebugLoc DL)
Generate recipes for the memory runtime difference checks Checks using Builder and return the conditi...
static bool sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR, VPRecipeBase *Previous, const VPDominatorTree &VPDT)
Try to sink users of FOR after Previous.
static bool canonicalHeaderAndLatch(VPBlockBase *HeaderVPB, const VPDominatorTree &VPDT)
Checks if HeaderVPB is a loop header block in the plain CFG; that is, it has exactly 2 predecessors (...
static void addInitialSkeleton(VPlan &Plan, Type *InductionTy, PredicatedScalarEvolution &PSE, Loop *TheLoop)
static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR, VPRecipeBase *Previous, const VPDominatorTree &VPDT)
Try to hoist Previous and its operands before all users of FOR.
static void createLoopRegion(VPlan &Plan, VPBlockBase *HeaderVPB, DebugLoc DL)
Create a new VPRegionBlock for the loop starting at HeaderVPB.
static VPInstruction * findFindIVSelect(VPValue *BackedgeVal)
Find and return the final select instruction of the FindIV result pattern for the given BackedgeVal: ...
static bool tryToSinkOrHoistRecurrenceUsers(VPBasicBlock *HeaderVPBB, const VPDominatorTree &VPDT)
Sink users of fixed-order recurrences past or hoist before the recipe defining the previous value,...
static constexpr uint32_t CheckBypassWeights[]
static void printAfterInitialConstruction(VPlan &)
To make RUN_VPLAN_PASS print initial VPlan.
static void createExtractsForLiveOuts(VPlan &Plan, VPBasicBlock *MiddleVPBB)
Creates extracts for values in Plan defined in a loop region and used outside a loop region.
static VPValue * createRuntimeChecks(VPlan &Plan, VPBuilder &Builder, VPSCEVExpander &Expander, ArrayRef< RuntimePointerCheck > Checks, const Loop *TheLoop, ScalarEvolution &SE, DebugLoc DL)
Generate recipes for the memory runtime checks Checks of TheLoop using Builder and return the conditi...
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
This file contains the declarations of different VPlan-related auxiliary helpers.
This file provides utility VPlan to VPlan transformations.
#define RUN_VPLAN_PASS_NO_VERIFY(PASS,...)
This file contains the declarations of the Vectorization Plan base classes:
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
Definition APInt.h:202
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Analysis providing branch probability information.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition InstrTypes.h:746
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition InstrTypes.h:744
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
Definition InstrTypes.h:745
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition InstrTypes.h:747
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:890
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
static LLVM_ABI StringRef getPredicateName(Predicate P)
bool isStrictPredicate() const
Definition InstrTypes.h:906
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
Describes a conditional induction variable: an induction variable that is updated only on loop iterat...
const SCEV * getStepSCEV() const
Returns a SCEV expression for the step of the conditional induction PHI.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
static DebugLoc getUnknown()
Definition DebugLoc.h:153
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:757
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:793
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:306
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:317
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
static FastMathFlags getFast()
Definition FMF.h:50
A struct for saving information about induction variables.
InductionKind getKind() const
const SCEV * getStep() const
@ IK_FpInduction
Floating point induction variable.
@ IK_PtrInduction
Pointer induction var. Step = C.
@ IK_IntInduction
Integer induction variable. Step = C.
Value * getStartValue() const
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
BlockT * getHeader() const
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
LLVM_ABI std::pair< MDNode *, MDNode * > getNoAliasMetadataFor(const Instruction *OrigInst) const
Returns a pair containing the alias_scope and noalias metadata nodes for OrigInst,...
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
LLVM_ABI DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
Definition LoopInfo.cpp:694
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
Definition MDBuilder.cpp:38
Metadata node.
Definition Metadata.h:1081
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:39
ValueT lookup(const KeyT &Key) const
Definition MapVector.h:111
iterator find(const KeyT &Key)
Definition MapVector.h:157
iterator end()
Definition MapVector.h:70
The optimization diagnostic interface.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Diagnostic information for missed-optimization remarks.
Post-order traversal of a graph.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
LLVM_ABI void addPredicate(const SCEVPredicate &Pred)
Adds a new predicate.
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEVPredicate & getPredicate() const
LLVM_ABI const SCEV * getSymbolicMaxBackedgeTakenCount()
Get the (predicated) symbolic max backedge count for the analyzed loop.
LLVM_ABI const SCEV * getSCEV(Value *V)
Returns the SCEV expression of V, in the context of the current SCEV predicate.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
static bool isFMulAddIntrinsic(Instruction *I)
Returns true if the instruction is a call to the llvm.fmuladd intrinsic.
FastMathFlags getFastMathFlags() const
static bool isFPMinMaxNumRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating-point minnum/maxnum kind.
bool hasUsesOutsideReductionChain() const
Returns true if the reduction PHI has any uses outside the reduction chain.
static bool isFindLastRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
TrackingVH< Value > getRecurrenceStartValue() const
static bool isAnyOfRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
RecurKind getRecurrenceKind() const
bool isOrdered() const
Expose an ordered FP reduction to the instance users.
static LLVM_ABI bool isFloatingPointRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating point kind.
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 bool isIntegerRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is an integer kind.
static bool isMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is any min/max kind.
Holds information about the memory runtime legality checks to verify that a group of pointers do not ...
std::optional< ArrayRef< PointerDiffInfo > > getDiffChecks() const
const SmallVectorImpl< RuntimePointerCheck > & getChecks() const
Returns the checks that generateChecks created.
virtual unsigned getComplexity() const
Returns the estimated complexity of this predicate.
This class represents an analyzed expression in the program.
static constexpr auto FlagNUW
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getElementCount(Type *Ty, ElementCount EC, SCEVFlags Flags=SCEV::FlagNone)
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags=SCEV::FlagNone, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getTripCountFromExitCount(const SCEV *ExitCount)
A version of getTripCountFromExitCount below which always picks an evaluation type which can not resu...
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
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 isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getUMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI const SCEV * getStoreSizeOfExpr(Type *IntTy, Type *StoreTy)
Return an expression for the store size of StoreTy that is type IntTy.
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, SCEVUse LHS, SCEVUse RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
LLVM_ABI const SCEV * applyLoopGuards(const SCEV *Expr, const Loop *L)
Try to apply information from loop guards for L to Expr.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition DenseSet.h:295
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
op_range operands()
Definition User.h:267
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4533
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4614
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4564
iterator end()
Definition VPlan.h:4574
iterator begin()
Recipe iterator methods.
Definition VPlan.h:4572
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4627
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:228
VPBasicBlock * splitAt(iterator SplitAt)
Split current block at SplitAt by inserting a new block between the current block and its successors ...
Definition VPlan.cpp:529
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:608
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:95
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
Definition VPlan.h:305
VPRegionBlock * getParent()
Definition VPlan.h:193
const VPBasicBlock * getExitingBasicBlock() const
Definition VPlan.cpp:198
void setName(const Twine &newName)
Definition VPlan.h:186
size_t getNumSuccessors() const
Definition VPlan.h:243
void swapSuccessors()
Swap successors of the block. The block must have exactly 2 successors.
Definition VPlan.h:327
size_t getNumPredecessors() const
Definition VPlan.h:244
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition VPlan.h:296
bool hasSuccessors() const
Returns true if this block has any successors.
Definition VPlan.h:221
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:228
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
Definition VPlan.h:287
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:239
void swapPredecessors()
Swap predecessors of the block.
Definition VPlan.h:319
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:183
void setOneSuccessor(VPBlockBase *Successor)
Set a given VPBlockBase Successor as the single successor of this VPBlockBase.
Definition VPlan.h:276
void setParent(VPRegionBlock *P)
Definition VPlan.h:203
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:233
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:217
static auto blocksAs(T &&Range)
Return an iterator range over Range with each block cast to BlockTy.
Definition VPlanUtils.h:460
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
Definition VPlanUtils.h:342
static void insertOnEdge(VPBlockBase *From, VPBlockBase *To, VPBlockBase *BlockPtr)
Inserts BlockPtr on the edge between From and To.
Definition VPlanUtils.h:479
static VPBasicBlock * getPlainCFGMiddleBlock(const VPlan &Plan)
Returns the middle block of Plan in plain CFG form (before regions are formed).
static bool isHeader(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop header, based on regions or VPDT in their absence.
static void connectBlocks(VPBlockBase *From, VPBlockBase *To, unsigned PredIdx=-1u, unsigned SuccIdx=-1u)
Connect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:387
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:405
static void reassociateBlocks(VPBlockBase *Old, VPBlockBase *New)
Reassociate all the blocks connected to Old so that they now point to New.
Definition VPlanUtils.h:423
static std::pair< VPBasicBlock *, VPBasicBlock * > getPlainCFGHeaderAndLatch(const VPlan &Plan)
Returns the header and latch of the outermost loop of Plan in plain CFG form (before regions are form...
static void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
Definition VPlanUtils.h:437
VPInstruction * createFreeze(VPValue *Op, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
static VPBuilderBase getToInsertAfter(VPRecipeBase *R)
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt, Type *ResultTy=nullptr)
Create a phi with IncomingValues, using the default flags for the result type, unless Flags is set.
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPRecipeBase * getRecipeAtInsertPoint() const
Get the recipe at the current insert point or nullptr if the insert point is the end of the block.
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt)
Create a select of TrueVal and FalseVal based on Cond, using the default flags for the result type,...
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
void setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Type *ResultTy=nullptr, const VPIRAttributes &Attrs={})
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
VPInstruction * createFCmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new FCmp VPInstruction with predicate Pred and operands A and B.
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
A recipe for handling scalar conditional induction PHIs.
Definition VPlan.h:2997
unsigned getNumDefinedValues() const
Returns the number of values defined by the VPDef.
Definition VPlanValue.h:577
VPValue * getVPSingleValue()
Returns the only VPValue defined by the VPDef.
Definition VPlanValue.h:550
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4303
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
LLVM_ABI_FOR_TEST bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B) const
A pure virtual base class for all recipes modeling header phis, including phis for first order recurr...
Definition VPlan.h:2487
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2530
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition VPlan.h:2519
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4692
Class to record and manage LLVM IR flags.
Definition VPlan.h:683
RecurKind getRecurKind() const
Definition VPlan.h:1027
Helper to manage IR metadata for recipes.
Definition VPlan.h:1152
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1322
@ ExtractLastActive
Extracts the last active lane from a set of vectors.
Definition VPlan.h:1437
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
Definition VPlan.h:1427
@ ExitingIVValue
Compute the exiting value of a wide induction after vectorization, that is the value of the last lane...
Definition VPlan.h:1441
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1381
void addIncoming(VPValue *IncomingV)
Append IncomingV as an incoming value to the phi-like recipe.
Definition VPlan.h:1680
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:402
void moveBefore(RecipeListTy::iterator I)
Unlink this recipe and insert it before I.
RecipeListTy::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool isPhi() const
Returns true for PHI-like recipes.
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:547
void insertBefore(VPRecipeBase *InsertPos)
Insert an unlinked recipe into a basic block immediately before the specified recipe.
void moveAfter(VPRecipeBase *MovePos)
Unlink this recipe from its current VPBasicBlock and insert it into the VPBasicBlock that MovePos liv...
Type * getScalarType() const
Returns the scalar type of this VPRecipeValue.
Definition VPlanValue.h:349
A recipe for handling reduction phis.
Definition VPlan.h:2890
bool isOrdered() const
Returns true, if the phi is part of an ordered reduction.
Definition VPlan.h:2962
unsigned getVFScaleFactor() const
Get the factor that the VF of this recipe's output should be scaled by, or 1 if it isn't scaled.
Definition VPlan.h:2946
bool isInLoop() const
Returns true if the phi is part of an in-loop reduction.
Definition VPlan.h:2965
RecurKind getRecurrenceKind() const
Returns the recurrence kind of the reduction.
Definition VPlan.h:2959
A recipe to represent inloop, ordered or partial reduction operations.
Definition VPlan.h:3328
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4764
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
Definition VPlan.h:4911
Type * getCanonicalIVType() const
Return the type of the canonical IV for loop regions.
Definition VPlan.h:4892
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4884
VPRegionValue * getHeaderMask() const
Return the header mask of the region, or null if not set.
Definition VPlan.h:4897
DebugLoc getDebugLoc() const
Returns the debug location of the VPRegionValue.
Definition VPlanValue.h:262
Lightweight SCEV-to-VPlan expander.
Definition VPlanUtils.h:281
VPValue * expand(const SCEV *S)
Expand S into recipes and live-ins using the builder.
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:605
Type * getType() const
Returns the scalar type of this symbolic value.
Definition VPlanValue.h:227
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:396
void replaceUsesOfWith(VPValue *From, VPValue *To)
Replaces all uses of From in the VPUser with To.
Definition VPlan.cpp:1509
operand_range operands()
Definition VPlanValue.h:472
void setOperand(unsigned I, VPValue *New)
Definition VPlanValue.h:445
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:437
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:142
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:123
void replaceUsesWithIf(VPValue *New, llvm::function_ref< bool(VPUser *U)> ShouldReplace)
Go through the uses list for this VPValue and make each use point to New if the callback ShouldReplac...
Definition VPlan.cpp:1482
void setUnderlyingValue(Value *Val)
Definition VPlanValue.h:204
void replaceAllUsesWith(VPValue *New)
Definition VPlan.cpp:1476
unsigned getNumUsers() const
Definition VPlanValue.h:115
user_range users()
Definition VPlanValue.h:157
Base class for widened induction (VPWidenIntOrFpInductionRecipe and VPWidenPointerInductionRecipe),...
Definition VPlan.h:2555
VPValue * getStepValue()
Returns the step value of the induction.
Definition VPlan.h:2597
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition VPlan.h:2614
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2643
bool isCanonical() const
Returns true if the induction is canonical, i.e.
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4951
VPIRValue * getLiveIn(Value *V) const
Return the live-in VPIRValue for V, if there is one or nullptr otherwise.
Definition VPlan.h:5281
LLVMContext & getContext() const
Definition VPlan.h:5148
VPBasicBlock * getEntry()
Definition VPlan.h:5043
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:5115
VPIRValue * getFalse()
Return a VPIRValue wrapping i1 false.
Definition VPlan.h:5247
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5146
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
Definition VPlan.cpp:1312
VPIRValue * getPoison(Type *Ty)
Return a VPIRValue wrapping a poison value of type Ty.
Definition VPlan.h:5275
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:5109
VPSymbolicValue & getVectorTripCount()
The vector trip count.
Definition VPlan.h:5136
VPIRValue * getOrAddLiveIn(Value *V)
Gets the live-in VPIRValue for V or adds a new live-in (if none exists yet) for V.
Definition VPlan.h:5224
VPRegionBlock * createLoopRegion(Type *CanIVTy, DebugLoc DL, const std::string &Name="", VPBlockBase *Entry=nullptr, VPBlockBase *Exiting=nullptr)
Create a new loop region with a canonical IV using CanIVTy and DL.
Definition VPlan.h:5320
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5250
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1066
void setTripCount(VPValue *NewTripCount)
Set the trip count assuming it is currently null; if it is not - use resetTripCount().
Definition VPlan.h:5122
VPBasicBlock * getMiddleBlock()
Returns the 'middle' block of the plan, that is the block that selects whether to execute the scalar ...
Definition VPlan.h:5085
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
Definition VPlan.h:5307
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
Definition VPlan.cpp:1320
VPIRValue * getTrue()
Return a VPIRValue wrapping i1 true.
Definition VPlan.h:5244
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:5048
bool hasScalarVFOnly() const
Definition VPlan.h:5192
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:5099
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
Definition VPlan.h:5064
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition VPlan.h:5105
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5139
bool hasScalarTail() const
Returns true if the scalar tail may execute after the vector loop, i.e.
Definition VPlan.h:5380
VPIRValue * getConstantInt(Type *Ty, uint64_t Val, bool IsSigned=false)
Return a VPIRValue wrapping a ConstantInt with the given type and value.
Definition VPlan.h:5258
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:210
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ Entry
Definition COFF.h:862
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
void reportVectorizationFailure(const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr)
Reports a vectorization failure: print DebugMsg for debugging purposes along with the corresponding o...
auto m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
SelectLike_match< CondTy, LTy, RTy > m_SelectLike(const CondTy &C, const LTy &TrueC, const RTy &FalseC)
Matches a value that behaves like a boolean-controlled select, i.e.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
VPInstruction_match< VPInstruction::ExtractLastLane, VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > > m_ExtractLastLaneOfLastPart(const Op0_t &Op0)
RecipeTy * findSingleUser(VPValue *V, const MatchT &P)
Return the sole user of V matching pattern P, casting it to RecipeTy, or nullptr.
bool matchFindIVResult(VPInstruction *VPI, Op0_t ReducedIV, Op1_t Start)
Match FindIV result pattern: select(icmp ne ComputeReductionResult(ReducedIV), Sentinel),...
VPInstruction_match< VPInstruction::BranchOnTwoConds > m_BranchOnTwoConds()
VPInstruction_match< VPInstruction::ExtractLastLane, Op0_t > m_ExtractLastLane(const Op0_t &Op0)
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > m_ExtractLastPart(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
bool cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking=false)
Return true if we do not know how to (mechanically) hoist or sink R.
VPInstruction * findComputeReductionResult(VPReductionPHIRecipe *PhiR)
Find the ComputeReductionResult recipe for PhiR, looking through selects inserted for predicated redu...
SmallVector< std::pair< VPBasicBlock *, VPIRBasicBlock * > > getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB)
Returns the (early exiting block, exit block) pairs of Plan, i.e.
DenseMap< const VPBasicBlock *, std::optional< VPExecutionFrequency > > computeExecutionFrequencies(ArrayRef< VPBasicBlock * > Blocks)
Computes for each block in Blocks, which must be in reverse post-order, the frequency with which it e...
VPIRFlags getFlagsForInduction(const InductionDescriptor &ID, const VPPhi *PhiR)
Extracts and returns NoWrap flags from PhiR and fast-math flags from ID.
VPRecipeBase * findRecipe(VPValue *Start, PredT Pred)
Search Start's users for a recipe satisfying Pred, looking through recipes with definitions.
Definition VPlanUtils.h:150
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr, bool ExpandInIR=false)
Get or create a VPValue that corresponds to the expansion of Expr.
LLVM_ABI_FOR_TEST const SCEV * getSCEVExprForVPValue(const VPValue *V, PredicatedScalarEvolution &PSE, const Loop *L=nullptr)
Return the SCEV expression for V.
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.
Definition STLExtras.h:316
SmallVector< VPBasicBlock * > vp_rpo_plain_cfg_loop_body(VPBasicBlock *Header)
Returns the VPBasicBlocks forming the loop body of a plain (pre-region) VPlan in reverse post-order s...
Definition VPlanCFG.h:262
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Definition Threading.h:280
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Definition STLExtras.h:2196
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID)
Returns the min/max intrinsic used when expanding a min/max reduction.
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:856
ReductionStyle getReductionStyle(bool InLoop, bool Ordered, unsigned ScaleFactor)
Definition VPlan.h:2877
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
VPBuilderBase<> VPBuilder
Definition VPlan.h:66
auto map_to_vector(ContainerTy &&C, FuncTy &&F)
Map a range to a SmallVector with element types deduced from the mapping.
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...
Definition STLExtras.h:649
iterator_range< df_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_depth_first_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order.
Definition VPlanCFG.h:250
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
Definition STLExtras.h:1710
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:552
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
Definition STLExtras.h:323
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.
@ FindIV
FindIV reduction with select(icmp(),x,y) where one of (x,y) is a loop induction variable (increasing ...
@ FMinimum
FP min with llvm.minimum semantics.
@ FMaxNum
FP max with llvm.maxnum semantics including NaNs.
@ AnyOf
AnyOf reduction with select(cmp(),x,y) where one of (x,y) is loop invariant, and both x and y are int...
@ 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()).
@ 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()).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
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...
Definition STLExtras.h:2035
LLVM_ABI RuntimeCheckBounds getRuntimeCheckBounds(const RuntimeCheckingPtrGroup *CG, const Loop *TheLoop, ScalarEvolution &SE, bool HoistRuntimeChecks)
Return the bounds of CG in TheLoop.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
Definition STLExtras.h:2162
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
LLVM_ABI bool isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L, ScalarEvolution &SE, DominatorTree &DT, AssumptionCache *AC=nullptr, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Return true if we can prove that the given load (which is assumed to be within the specified loop) wo...
Definition Loads.cpp:306
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:881
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:344
A recipe for handling first-order recurrence phis.
Definition VPlan.h:2828
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:274
static void simplifyLiveInsWithSCEV(VPlan &Plan, PredicatedScalarEvolution &PSE)
Check Plan's live-ins and replace them with constants, if they can be simplified via SCEV.
static void addMinimumVectorEpilogueIterationCheck(VPlan &Plan, VPValue *MainVectorTripCount, bool RequiresScalarEpilogue, ElementCount EpilogueVF, unsigned MainLoopStep, unsigned EpilogueLoopStep, ScalarEvolution &SE)
Add a check to Plan to see if the epilogue vector loop should be executed.
static void foldTailByMasking(VPlan &Plan)
Adapts the vector loop region for tail folding by introducing a header mask and conditionally executi...
static bool handleMultiUseReductions(VPlan &Plan, OptimizationRemarkEmitter *ORE, Loop *TheLoop)
Try to legalize reductions with multiple in-loop uses.
static void recordExecutionFrequencies(VPlan &Plan)
Add execution frequencies to each recipe in the loop body of Plan.
static bool handleFindLastReductions(VPlan &Plan)
Check if Plan contains any FindLast reductions.
static void createInLoopReductionRecipes(VPlan &Plan, ElementCount MinVF)
Create VPReductionRecipes for in-loop reductions.
static LLVM_ABI_FOR_TEST bool createHeaderPhiRecipes(VPlan &Plan, PredicatedScalarEvolution &PSE, Loop &OrigLoop, OptimizationRemarkEmitter *ORE, const VPDominatorTree &VPDT, const MapVector< PHINode *, InductionDescriptor > &Inductions, const MapVector< PHINode *, RecurrenceDescriptor > &Reductions, const MapVector< PHINode *, ConditionalInductionDescriptor > &ConditionalInductions, const SmallPtrSetImpl< const PHINode * > &FixedOrderRecurrences, const SmallPtrSetImpl< PHINode * > &InLoopReductions, bool AllowReordering)
Replace VPPhi recipes in Plan's header with corresponding VPHeaderPHIRecipe subclasses for inductions...
static LLVM_ABI_FOR_TEST void createLoopRegions(VPlan &Plan, DebugLoc DL)
Replace loops in Plan's flat CFG with VPRegionBlocks, turning Plan's flat CFG into a hierarchical CFG...
static VPIRBasicBlock * modelGeneratedMainLoopBlocks(VPlan &EpiPlan, VPlan &MainPlan, VPBasicBlock *MainCheck)
Model the blocks the executed MainPlan generated for the main vector loop in EpiPlan during epilogue ...
static LLVM_ABI_FOR_TEST void addMiddleCheck(VPlan &Plan)
If a check is needed to guard executing the scalar epilogue loop, it will be added to the middle bloc...
static void attachAliasMaskToHeaderMask(VPlan &Plan)
Attaches the alias-mask to the existing header-mask.
static bool areAllLoadsDereferenceable(VPBasicBlock *HeaderVPBB, Loop *TheLoop, PredicatedScalarEvolution &PSE, DominatorTree &DT, AssumptionCache *AC)
Check if all loads in the loop are dereferenceable.
static LLVM_ABI_FOR_TEST std::unique_ptr< VPlan > buildVPlan0(Loop *TheLoop, LoopInfo &LI, Type *InductionTy, PredicatedScalarEvolution &PSE, LoopVersioning *LVer=nullptr, function_ref< const BranchProbabilityInfo &()> GetBPI=nullptr)
Create a base VPlan0, serving as the common starting point for all later candidates.
static bool handleMaxMinNumReductions(VPlan &Plan)
Check if Plan contains any FMaxNum or FMinNum reductions.
static void attachCheckBlock(VPlan &Plan, Value *Cond, BasicBlock *CheckBlock, bool AddBranchWeights)
static LLVM_ABI_FOR_TEST void handleCountableEarlyExits(VPlan &Plan)
Disconnect countable early exits from the loop.
static bool finalizeSCEVPredicates(VPlan &Plan, PredicatedScalarEvolution &PSE, bool OptForSize, unsigned SCEVCheckThreshold, OptimizationRemarkEmitter *ORE, Loop *TheLoop)
Finalize SCEV predicates by adding induction predicates from Plan to PSE and checking constraints.
static void addIterationCountCheckBlock(VPlan &Plan, ElementCount VF, unsigned UF, bool RequiresScalarEpilogue, Loop *OrigLoop, const uint32_t *MinItersBypassWeights, DebugLoc DL, PredicatedScalarEvolution &PSE)
Add a new check block before the vector preheader to Plan to check if the main vector loop should be ...
static void attachMemoryChecks(VPlan &Plan, const RuntimePointerChecking &RtPtrChecking, const Loop *TheLoop, ScalarEvolution &SE, ElementCount VF, unsigned UF, bool AddBranchWeights)
Generate the memory runtime checks of RtPtrChecking for TheLoop as recipes and attach the check block...
static void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF, ElementCount MinProfitableTripCount, bool RequiresScalarEpilogue, bool TailFolded, Loop *OrigLoop, const uint32_t *MinItersBypassWeights, DebugLoc DL, PredicatedScalarEvolution &PSE, VPBasicBlock *CheckBlock)
static void attachVPCheckBlock(VPlan &Plan, VPValue *Cond, VPBasicBlock *CheckBlock, bool AddBranchWeights)
Connect CheckBlock to Plan, branching on Cond.
static LLVM_ABI bool HoistRuntimeChecks