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
14#include "LoopVectorizationPlanner.h"
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"
24#include "llvm/ADT/SmallVectorExtras.h"
25#include "llvm/Analysis/BranchProbabilityInfo.h"
26#include "llvm/Analysis/Loads.h"
27#include "llvm/Analysis/LoopInfo.h"
28#include "llvm/Analysis/LoopIterator.h"
29#include "llvm/Analysis/OptimizationRemarkEmitter.h"
30#include "llvm/Analysis/ScalarEvolution.h"
31#include "llvm/Analysis/ScalarEvolutionExpressions.h"
32#include "llvm/Analysis/TargetTransformInfo.h"
33#include "llvm/IR/InstrTypes.h"
34#include "llvm/IR/MDBuilder.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Transforms/Utils/LoopUtils.h"
37#include "llvm/Transforms/Utils/LoopVersioning.h"
38#include "llvm/Transforms/Vectorize/LoopVectorize.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.
74 DenseMap<BasicBlock *, VPBasicBlock *> BB2VPBB;
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.
79 SmallVector<PHINode *, 8> PhisToFix;
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>(args&: Lp, args&: 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.
107 SmallVector<VPBlockBase *, 2> VPBBPreds;
108 for (BasicBlock *Pred : predecessors(BB))
109 VPBBPreds.push_back(Elt: getOrCreateVPBB(BB: 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>(Val: 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(BB: Phi->getParent()))
130 PhiR->addIncoming(
131 IncomingV: getOrCreateVPOperand(IRVal: Phi->getIncomingValueForBlock(BB: 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(Val: 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.
160 Instruction *Inst = dyn_cast<Instruction>(Val);
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(Val: 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(V: 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(Kind: 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(C: seq(Size: Term.getNumSuccessors()), F: [&](unsigned I) {
209 return BPI->getEdgeProbability(Src: Term.getParent(), IndexInSuccessors: 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>(Val: Inst))
232 // Skip the rest of the Instruction processing for Branch instructions.
233 continue;
234
235 if (auto *Br = dyn_cast<CondBrInst>(Val: Inst)) {
236 // Conditional branch instruction are represented using BranchOnCond
237 // recipes.
238 VPValue *Cond = getOrCreateVPOperand(IRVal: Br->getCondition());
239 VPIRBuilder.createNaryOp(Opcode: VPInstruction::BranchOnCond, Operands: {Cond}, Inst, Flags: {},
240 MD: getTerminatorMetadata(Term&: *Inst),
241 DL: Inst->getDebugLoc());
242 continue;
243 }
244
245 if (auto *SI = dyn_cast<SwitchInst>(Val: Inst)) {
246 // Don't emit recipes for unconditional switch instructions.
247 if (SI->getNumCases() == 0)
248 continue;
249 SmallVector<VPValue *> Ops = {getOrCreateVPOperand(IRVal: SI->getCondition())};
250 for (auto Case : SI->cases())
251 Ops.push_back(Elt: getOrCreateVPOperand(IRVal: Case.getCaseValue()));
252 VPIRBuilder.createNaryOp(Opcode: Instruction::Switch, Operands: Ops, Inst, Flags: {},
253 MD: getTerminatorMetadata(Term&: *Inst),
254 DL: Inst->getDebugLoc());
255 continue;
256 }
257
258 VPSingleDefRecipe *NewR;
259 if (auto *Phi = dyn_cast<PHINode>(Val: 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(IncomingValues: {}, DL: Phi->getDebugLoc(), Name: "vec.phi",
264 Flags: *Phi, ResultTy: Phi->getType());
265 NewR->setUnderlyingValue(Phi);
266 if (isHeaderBB(BB: Phi->getParent(), L: LI->getLoopFor(BB: Phi->getParent()))) {
267 // Header phis need to be fixed after the VPBB for the latch has been
268 // created.
269 PhisToFix.push_back(Elt: 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: I)]] =
276 getOrCreateVPOperand(IRVal: Phi->getIncomingValue(i: I));
277 }
278 for (VPBlockBase *Pred : VPBB->getPredecessors())
279 cast<VPPhi>(Val: NewR)->addIncoming(
280 IncomingV: VPPredToIncomingValue.lookup(Val: 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>(Val: Inst) && LVer) {
287 const auto &[AliasScopeMD, NoAliasMD] =
288 LVer->getNoAliasMetadataFor(OrigInst: Inst);
289 if (AliasScopeMD)
290 MD.setMetadata(Kind: LLVMContext::MD_alias_scope, Node: AliasScopeMD);
291 if (NoAliasMD)
292 MD.setMetadata(Kind: LLVMContext::MD_noalias, Node: NoAliasMD);
293 }
294
295 assert(!isa<InsertValueInst>(Inst) &&
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(Elt: getOrCreateVPOperand(IRVal: Op));
302 if (auto *EVI = dyn_cast<ExtractValueInst>(Val: Inst))
303 for (unsigned Idx : EVI->indices())
304 VPOperands.push_back(Elt: Plan->getConstantInt(BitWidth: 32, Val: Idx));
305 NewR = VPIRBuilder.createNaryOp(Opcode: Inst->getOpcode(), Operands: VPOperands, Inst,
306 Flags: VPIRFlags(*Inst), MD, DL: Inst->getDebugLoc(),
307 Name: "", ResultTy: Inst->getType());
308 }
309
310 IRDef2VPValue[Inst] = NewR;
311 }
312}
313
314// Main interface to build the plain CFG.
315std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG() {
316 VPIRBasicBlock *Entry = cast<VPIRBasicBlock>(Val: Plan->getEntry());
317 BB2VPBB[Entry->getIRBasicBlock()] = Entry;
318 for (VPIRBasicBlock *ExitVPBB : Plan->getExitBlocks())
319 BB2VPBB[ExitVPBB->getIRBasicBlock()] = ExitVPBB;
320
321 // 1. Scan the body of the loop in a topological order to visit each basic
322 // block after having visited its predecessor basic blocks. Create a VPBB for
323 // each BB and link it to its successor and predecessor VPBBs. Note that
324 // predecessors must be set in the same order as they are in the incomming IR.
325 // Otherwise, there might be problems with existing phi nodes and algorithm
326 // based on predecessors traversal.
327
328 // Loop PH needs to be explicitly visited since it's not taken into account by
329 // LoopBlocksDFS.
330 BasicBlock *ThePreheaderBB = TheLoop->getLoopPreheader();
331 assert((ThePreheaderBB->getTerminator()->getNumSuccessors() == 1) &&
332 "Unexpected loop preheader");
333 for (auto &I : *ThePreheaderBB) {
334 if (I.getType()->isVoidTy())
335 continue;
336 IRDef2VPValue[&I] = Plan->getOrAddLiveIn(V: &I);
337 }
338
339 LoopBlocksRPO RPO(TheLoop);
340 RPO.perform(LI);
341
342 for (BasicBlock *BB : RPO) {
343 // Create or retrieve the VPBasicBlock for this BB.
344 VPBasicBlock *VPBB = getOrCreateVPBB(BB);
345 // Set VPBB predecessors in the same order as they are in the incoming BB.
346 setVPBBPredsFromBB(VPBB, BB);
347
348 // Create VPInstructions for BB.
349 createVPInstructionsForVPBB(VPBB, BB);
350
351 // Set VPBB successors. We create empty VPBBs for successors if they don't
352 // exist already. Recipes will be created when the successor is visited
353 // during the RPO traversal.
354 if (auto *SI = dyn_cast<SwitchInst>(Val: BB->getTerminator())) {
355 SmallVector<VPBlockBase *> Succs = {
356 getOrCreateVPBB(BB: SI->getDefaultDest())};
357 for (auto Case : SI->cases())
358 Succs.push_back(Elt: getOrCreateVPBB(BB: Case.getCaseSuccessor()));
359 VPBB->setSuccessors(Succs);
360 continue;
361 }
362 if (auto *BI = dyn_cast<UncondBrInst>(Val: BB->getTerminator())) {
363 VPBB->setOneSuccessor(getOrCreateVPBB(BB: BI->getSuccessor()));
364 continue;
365 }
366 auto *BI = cast<CondBrInst>(Val: BB->getTerminator());
367 BasicBlock *IRSucc0 = BI->getSuccessor(i: 0);
368 BasicBlock *IRSucc1 = BI->getSuccessor(i: 1);
369 VPBasicBlock *Successor0 = getOrCreateVPBB(BB: IRSucc0);
370 VPBasicBlock *Successor1 = getOrCreateVPBB(BB: IRSucc1);
371 VPBB->setTwoSuccessors(IfTrue: Successor0, IfFalse: Successor1);
372 }
373
374 for (auto *EB : Plan->getExitBlocks())
375 setVPBBPredsFromBB(VPBB: EB, BB: EB->getIRBasicBlock());
376
377 // 2. The whole CFG has been built at this point so all the input Values must
378 // have a VPlan counterpart. Fix VPlan header phi by adding their
379 // corresponding VPlan operands.
380 fixHeaderPhis();
381
382 Plan->getEntry()->setOneSuccessor(getOrCreateVPBB(BB: TheLoop->getHeader()));
383 Plan->getEntry()->setPlan(&*Plan);
384
385 // Fix VPlan loop-closed-ssa exit phi's by adding incoming operands to the
386 // VPIRInstructions wrapping them.
387 // // Note that the operand order corresponds to IR predecessor order, and may
388 // need adjusting when VPlan predecessors are added, if an exit block has
389 // multiple predecessor.
390 for (auto *EB : Plan->getExitBlocks()) {
391 for (VPRecipeBase &R : EB->phis()) {
392 auto *PhiR = cast<VPIRPhi>(Val: &R);
393 PHINode &Phi = PhiR->getIRPhi();
394 assert(PhiR->getNumOperands() == 0 &&
395 "no phi operands should be added yet");
396 for (BasicBlock *Pred : predecessors(BB: EB->getIRBasicBlock()))
397 PhiR->addIncoming(
398 IncomingV: getOrCreateVPOperand(IRVal: Phi.getIncomingValueForBlock(BB: Pred)));
399 }
400 }
401
402 LLVM_DEBUG(Plan->setName("Plain CFG\n"); dbgs() << *Plan);
403 return std::move(Plan);
404}
405
406/// Checks if \p HeaderVPB is a loop header block in the plain CFG; that is, it
407/// has exactly 2 predecessors (preheader and latch), where the block
408/// dominates the latch and the preheader dominates the block. If it is a
409/// header block return true and canonicalize the predecessors of the header
410/// (making sure the preheader appears first and the latch second) and the
411/// successors of the latch (making sure the loop exit comes first). Otherwise
412/// return false.
413static bool canonicalHeaderAndLatch(VPBlockBase *HeaderVPB,
414 const VPDominatorTree &VPDT) {
415 ArrayRef<VPBlockBase *> Preds = HeaderVPB->getPredecessors();
416 if (Preds.size() != 2)
417 return false;
418
419 auto *PreheaderVPBB = Preds[0];
420 auto *LatchVPBB = Preds[1];
421 if (!VPDT.dominates(A: PreheaderVPBB, B: HeaderVPB) ||
422 !VPDT.dominates(A: HeaderVPB, B: LatchVPBB)) {
423 std::swap(a&: PreheaderVPBB, b&: LatchVPBB);
424
425 if (!VPDT.dominates(A: PreheaderVPBB, B: HeaderVPB) ||
426 !VPDT.dominates(A: HeaderVPB, B: LatchVPBB))
427 return false;
428
429 // Canonicalize predecessors of header so that preheader is first and
430 // latch second.
431 HeaderVPB->swapPredecessors();
432 for (VPRecipeBase &R : cast<VPBasicBlock>(Val: HeaderVPB)->phis())
433 R.swapOperands();
434 }
435
436 // The two successors of conditional branch match the condition, with the
437 // first successor corresponding to true and the second to false. We
438 // canonicalize the successors of the latch when introducing the region, such
439 // that the latch exits the region when its condition is true; invert the
440 // original condition if the original CFG branches to the header on true.
441 // Note that the exit edge is not yet connected for top-level loops.
442 if (LatchVPBB->getSingleSuccessor() ||
443 LatchVPBB->getSuccessors()[0] != HeaderVPB)
444 return true;
445
446 assert(LatchVPBB->getNumSuccessors() == 2 && "Must have 2 successors");
447 auto *Term = cast<VPBasicBlock>(Val: LatchVPBB)->getTerminator();
448 assert(cast<VPInstruction>(Term)->getOpcode() ==
449 VPInstruction::BranchOnCond &&
450 "terminator must be a BranchOnCond");
451 auto *Not = new VPInstruction(VPInstruction::Not, {Term->getOperand(N: 0)});
452 Not->insertBefore(InsertPos: Term);
453 Term->setOperand(I: 0, New: Not);
454 LatchVPBB->swapSuccessors();
455
456 return true;
457}
458
459/// Create a new VPRegionBlock for the loop starting at \p HeaderVPB. For the
460/// outermost loop adjust the regions exiting terminator to be based on the
461/// canonical IV.
462static void createLoopRegion(VPlan &Plan, VPBlockBase *HeaderVPB, DebugLoc DL) {
463 auto *PreheaderVPBB = HeaderVPB->getPredecessors()[0];
464 auto *LatchVPBB = cast<VPBasicBlock>(Val: HeaderVPB->getPredecessors()[1]);
465 auto *OutermostHeaderVPBB =
466 VPBlockUtils::getPlainCFGHeaderAndLatch(Plan).first;
467
468 VPBlockUtils::disconnectBlocks(From: PreheaderVPBB, To: HeaderVPB);
469 VPBlockUtils::disconnectBlocks(From: LatchVPBB, To: HeaderVPB);
470
471 // Create an empty region first and insert it between PreheaderVPBB and
472 // the exit blocks, taking care to preserve the original predecessor &
473 // successor order of blocks. Set region entry and exiting after both
474 // HeaderVPB and LatchVPBB have been disconnected from their
475 // predecessors/successors. Only the outermost loop has a canonical IV. Nested
476 // loops are assigned a canonical IV of null type and unknown debug location.
477 bool IsOutermost = HeaderVPB == OutermostHeaderVPBB;
478 Type *CanIVTy = nullptr;
479 if (IsOutermost)
480 CanIVTy = Plan.getVectorTripCount().getType();
481 else
482 DL = DebugLoc::getUnknown();
483 auto *R = Plan.createLoopRegion(CanIVTy, DL);
484
485 // Transfer latch's successors to the region.
486 VPBlockUtils::transferSuccessors(Old: LatchVPBB, New: R);
487
488 VPBlockUtils::connectBlocks(From: PreheaderVPBB, To: R);
489 R->setEntry(HeaderVPB);
490 R->setExiting(LatchVPBB);
491
492 // All VPBB's reachable shallowly from HeaderVPB belong to the current region.
493 for (VPBlockBase *VPBB : vp_depth_first_shallow(G: HeaderVPB))
494 VPBB->setParent(R);
495
496 if (!IsOutermost)
497 return;
498
499 auto *LatchTerm = LatchVPBB->getTerminator();
500 VPBuilder Builder(LatchTerm);
501 // Add a VPInstruction to increment the scalar canonical IV by VF * UF.
502 // Initially the induction increment is guaranteed to not wrap, but that may
503 // change later, e.g. when tail-folding, when the flags need to be dropped.
504 auto *CanonicalIVIncrement = Builder.createAdd(
505 LHS: R->getCanonicalIV(), RHS: &Plan.getVFxUF(), DL, Name: "index.next", WrapFlags: {true, false});
506
507 if (match(V: LatchTerm, P: m_BranchOnTwoConds())) {
508 auto *IsLatchExitTaken = Builder.createICmp(
509 Pred: CmpInst::ICMP_EQ, A: CanonicalIVIncrement, B: &Plan.getVectorTripCount());
510 LatchTerm->setOperand(I: 1, New: IsLatchExitTaken);
511 } else {
512 // We are replacing the branch to exit the region. Remove the original
513 // BranchOnCond.
514 assert(match(LatchTerm, m_BranchOnCond()) && "Unexpected terminator");
515 DebugLoc LatchDL = LatchTerm->getDebugLoc();
516 Builder.createNaryOp(Opcode: VPInstruction::BranchOnCount,
517 Operands: {CanonicalIVIncrement, &Plan.getVectorTripCount()},
518 DL: LatchDL);
519 LatchTerm->eraseFromParent();
520 }
521}
522
523/// Creates extracts for values in \p Plan defined in a loop region and used
524/// outside a loop region.
525static void createExtractsForLiveOuts(VPlan &Plan, VPBasicBlock *MiddleVPBB) {
526 VPBuilder B(MiddleVPBB, MiddleVPBB->getFirstNonPhi());
527 for (VPBasicBlock *EB : Plan.getExitBlocks()) {
528 if (!is_contained(Range: EB->predecessors(), Element: MiddleVPBB))
529 continue;
530
531 for (VPRecipeBase &R : EB->phis()) {
532 auto *ExitIRI = cast<VPIRPhi>(Val: &R);
533 VPValue *Exiting = ExitIRI->getIncomingValueForBlock(VPBB: MiddleVPBB);
534 if (isa<VPIRValue>(Val: Exiting))
535 continue;
536 Exiting = B.createNaryOp(Opcode: VPInstruction::ExtractLastPart, Operands: Exiting);
537 Exiting = B.createNaryOp(Opcode: VPInstruction::ExtractLastLane, Operands: Exiting);
538 ExitIRI->setIncomingValueForBlock(VPBB: MiddleVPBB, V: Exiting);
539 }
540 }
541}
542
543static void addInitialSkeleton(VPlan &Plan, Type *InductionTy,
544 PredicatedScalarEvolution &PSE, Loop *TheLoop) {
545 VPDominatorTree VPDT(Plan);
546
547 auto *HeaderVPBB = cast<VPBasicBlock>(Val: Plan.getEntry()->getSingleSuccessor());
548 if (TheLoop->isInnermost()) {
549 canonicalHeaderAndLatch(HeaderVPB: HeaderVPBB, VPDT);
550 } else {
551 // When vectorizing outer loops, canonicalize all loops up front.
552 SmallVector<VPBlockBase *> Blocks(vp_depth_first_shallow(G: Plan.getEntry()));
553 for (VPBlockBase *VPB : Blocks)
554 canonicalHeaderAndLatch(HeaderVPB: VPB, VPDT);
555 }
556 auto *LatchVPBB = cast<VPBasicBlock>(Val: HeaderVPBB->getPredecessors()[1]);
557
558 VPBasicBlock *VecPreheader = Plan.createVPBasicBlock(Name: "vector.ph");
559 VPBlockUtils::insertBlockAfter(NewBlock: VecPreheader, BlockPtr: Plan.getEntry());
560
561 VPBasicBlock *MiddleVPBB = Plan.createVPBasicBlock(Name: "middle.block");
562 // The canonical LatchVPBB has the header block as last successor. If it has
563 // another successor, this successor is an exit block - insert middle block on
564 // its edge. Otherwise, add middle block as another successor retaining header
565 // as last. In the latter case, the latch has no conditional terminator yet,
566 // so insert a placeholder BranchOnCond that always continues to the header.
567 // It will be canonicalized to a BranchOnCount later
568 if (LatchVPBB->getNumSuccessors() == 2) {
569 VPBlockBase *LatchExitVPB = LatchVPBB->getSuccessors()[0];
570 VPBlockUtils::insertOnEdge(From: LatchVPBB, To: LatchExitVPB, BlockPtr: MiddleVPBB);
571 } else {
572 VPBlockUtils::connectBlocks(From: LatchVPBB, To: MiddleVPBB);
573 LatchVPBB->swapSuccessors();
574 VPBuilder(LatchVPBB).createNaryOp(Opcode: VPInstruction::BranchOnCond,
575 Operands: {Plan.getFalse()});
576 }
577
578 // Create SCEV and VPValue for the trip count.
579 // We use the symbolic max backedge-taken-count, which works also when
580 // vectorizing loops with uncountable early exits.
581 const SCEV *BackedgeTakenCountSCEV = PSE.getSymbolicMaxBackedgeTakenCount();
582 assert(!isa<SCEVCouldNotCompute>(BackedgeTakenCountSCEV) &&
583 "Invalid backedge-taken count");
584 ScalarEvolution &SE = *PSE.getSE();
585 const SCEV *TripCount = SE.getTripCountFromExitCount(ExitCount: BackedgeTakenCountSCEV,
586 EvalTy: InductionTy, L: TheLoop);
587 Plan.setTripCount(vputils::getOrCreateVPValueForSCEVExpr(Plan, Expr: TripCount));
588
589 VPBasicBlock *ScalarPH = Plan.createVPBasicBlock(Name: "scalar.ph");
590 VPBlockUtils::connectBlocks(From: ScalarPH, To: Plan.getScalarHeader());
591
592 // The connection order corresponds to the operands of the conditional branch,
593 // with the middle block already connected to the exit block.
594 VPBlockUtils::connectBlocks(From: MiddleVPBB, To: ScalarPH);
595 // Also connect the entry block to the scalar preheader.
596 // TODO: Also introduce a branch recipe together with the minimum trip count
597 // check.
598 VPBlockUtils::connectBlocks(From: Plan.getEntry(), To: ScalarPH);
599 Plan.getEntry()->swapSuccessors();
600
601 createExtractsForLiveOuts(Plan, MiddleVPBB);
602
603 // Create resume phis in the scalar preheader for each phi in the scalar loop.
604 // Their incoming value from the vector loop will be the last lane of the
605 // corresponding vector loop header phi.
606 VPBuilder MiddleBuilder(MiddleVPBB, MiddleVPBB->getFirstNonPhi());
607 VPBuilder ScalarPHBuilder(ScalarPH);
608 assert(equal(ScalarPH->getPredecessors(),
609 ArrayRef<VPBlockBase *>({MiddleVPBB, Plan.getEntry()})) &&
610 "unexpected predecessor order of scalar ph");
611 for (const auto &[PhiR, ScalarPhiR] :
612 zip_equal(t: HeaderVPBB->phis(), u: Plan.getScalarHeader()->phis())) {
613 auto *VectorPhiR = cast<VPPhi>(Val: &PhiR);
614 VPValue *BackedgeVal = VectorPhiR->getOperand(N: 1);
615 VPValue *ResumeFromVectorLoop =
616 MiddleBuilder.createNaryOp(Opcode: VPInstruction::ExtractLastPart, Operands: BackedgeVal);
617 ResumeFromVectorLoop = MiddleBuilder.createNaryOp(
618 Opcode: VPInstruction::ExtractLastLane, Operands: ResumeFromVectorLoop);
619 // Create scalar resume phi, with the first operand being the incoming value
620 // from the middle block and the second operand coming from the entry block.
621 auto *ResumePhiR = ScalarPHBuilder.createScalarPhi(
622 IncomingValues: {ResumeFromVectorLoop, VectorPhiR->getOperand(N: 0)},
623 DL: VectorPhiR->getDebugLoc());
624 cast<VPIRPhi>(Val: &ScalarPhiR)->addIncoming(IncomingV: ResumePhiR);
625 }
626}
627
628/// To make RUN_VPLAN_PASS print initial VPlan.
629static void printAfterInitialConstruction(VPlan &) {}
630
631std::unique_ptr<VPlan> VPlanTransforms::buildVPlan0(
632 Loop *TheLoop, LoopInfo &LI, Type *InductionTy,
633 PredicatedScalarEvolution &PSE, LoopVersioning *LVer,
634 function_ref<const BranchProbabilityInfo &()> GetBPI) {
635 PlainCFGBuilder Builder(TheLoop, &LI, LVer, InductionTy, GetBPI);
636 std::unique_ptr<VPlan> VPlan0 = Builder.buildPlainCFG();
637 addInitialSkeleton(Plan&: *VPlan0, InductionTy, PSE, TheLoop);
638 simplifyLiveInsWithSCEV(Plan&: *VPlan0, PSE);
639
640 RUN_VPLAN_PASS_NO_VERIFY(printAfterInitialConstruction, *VPlan0);
641 return VPlan0;
642}
643
644void VPlanTransforms::recordExecutionFrequencies(VPlan &Plan) {
645 VPBasicBlock *Header = VPBlockUtils::getPlainCFGHeaderAndLatch(Plan).first;
646 SmallVector<VPBasicBlock *> Blocks = vp_rpo_plain_cfg_loop_body(Header);
647 auto Frequencies = vputils::computeExecutionFrequencies(Blocks);
648 LLVMContext &Ctx = Plan.getContext();
649 for (VPBasicBlock *VPBB : Blocks) {
650 std::optional<VPExecutionFrequency> Freq = Frequencies.lookup(Val: VPBB);
651 for (VPInstruction &VPI : make_isa_range<VPInstruction>(Range&: *VPBB))
652 VPI.setExecutionFrequency(Freq, Ctx);
653 }
654}
655
656/// Creates a VPWidenIntOrFpInductionRecipe or VPWidenPointerInductionRecipe
657/// for \p Phi based on \p IndDesc.
658static VPHeaderPHIRecipe *
659createWidenInductionRecipe(PHINode *Phi, VPPhi *PhiR, VPIRValue *Start,
660 const InductionDescriptor &IndDesc, VPlan &Plan,
661 PredicatedScalarEvolution &PSE, Loop &OrigLoop,
662 DebugLoc DL) {
663 [[maybe_unused]] ScalarEvolution &SE = *PSE.getSE();
664 assert(SE.isLoopInvariant(IndDesc.getStep(), &OrigLoop) &&
665 "step must be loop invariant");
666 assert((Plan.getLiveIn(IndDesc.getStartValue()) == Start ||
667 (SE.isSCEVable(IndDesc.getStartValue()->getType()) &&
668 PSE.getSCEV(IndDesc.getStartValue()) ==
669 vputils::getSCEVExprForVPValue(Start, PSE))) &&
670 "Start VPValue must match IndDesc's start value");
671
672 VPValue *Step =
673 vputils::getOrCreateVPValueForSCEVExpr(Plan, Expr: IndDesc.getStep());
674
675 VPValue *BackedgeVal = PhiR->getOperand(N: 1);
676 // Replace live-out extracts of WideIV's backedge value by ExitingIVValue
677 // recipes. optimizeInductionLiveOutUsers will later compute the proper
678 // DerivedIV.
679 //
680 // For an IV that requires SCEV predicate, keep extracting the exit values
681 // from the loop directly, as the pre-computed exit value as-is would be
682 // incorrect outside the loop.
683 auto ReplaceExtractsWithExitingIVValueIfPossible = [&](VPWidenInductionRecipe
684 *WideIV) {
685 bool IsPredicated = !WideIV->getNoWrapPredicates().empty();
686 for (VPUser *U : to_vector(Range: BackedgeVal->users())) {
687 if (!match(U, P: m_ExtractLastPart(Op0: m_VPValue())))
688 continue;
689 auto *ExtractLastPart = cast<VPInstruction>(Val: U);
690 VPUser *ExtractLastPartUser = ExtractLastPart->getSingleUser();
691 assert(ExtractLastPartUser && "must have a single user");
692 if (!match(U: ExtractLastPartUser, P: m_ExtractLastLane(Op0: m_VPValue())))
693 continue;
694 auto *ExtractLastLane = cast<VPInstruction>(Val: ExtractLastPartUser);
695 assert(is_contained(ExtractLastLane->getParent()->successors(),
696 Plan.getScalarPreheader()) &&
697 "last lane must be extracted in the middle block");
698 // Keep the vector extract for exit-block live-out uses of a predicated
699 // IV.
700 if (IsPredicated &&
701 any_of(Range: ExtractLastLane->users(), P: [&](VPUser *LaneUser) {
702 auto *R = cast<VPRecipeBase>(Val: LaneUser);
703 return Plan.isExitBlock(VPBB: R->getParent());
704 }))
705 continue;
706 VPBuilder Builder(ExtractLastLane);
707 ExtractLastLane->replaceAllUsesWith(
708 New: Builder.createNaryOp(Opcode: VPInstruction::ExitingIVValue, Operands: {WideIV}));
709 ExtractLastLane->eraseFromParent();
710 ExtractLastPart->eraseFromParent();
711 }
712 };
713
714 if (IndDesc.getKind() == InductionDescriptor::IK_PtrInduction) {
715 auto *WideIV = new VPWidenPointerInductionRecipe(
716 Phi, Start, Step, &Plan.getVFxUF(), IndDesc, DL);
717 ReplaceExtractsWithExitingIVValueIfPossible(WideIV);
718 return WideIV;
719 }
720
721 assert((IndDesc.getKind() == InductionDescriptor::IK_IntInduction ||
722 IndDesc.getKind() == InductionDescriptor::IK_FpInduction) &&
723 "must have an integer or float induction at this point");
724
725 // Update wide induction increments to use the same step as the corresponding
726 // wide induction. This enables detecting induction increments directly in
727 // VPlan and removes redundant splats.
728 if (match(V: BackedgeVal, P: m_Add(Op0: m_Specific(VPV: PhiR), Op1: m_VPValue())))
729 BackedgeVal->getDefiningRecipe()->setOperand(I: 1, New: Step);
730
731 // It is always safe to copy over the NoWrap and FastMath flags. In
732 // particular, when folding tail by masking, the masked-off lanes are never
733 // used, so it is safe.
734 VPIRFlags Flags = vputils::getFlagsForInduction(ID: IndDesc, PhiR);
735
736 auto *WideIV = new VPWidenIntOrFpInductionRecipe(
737 Phi, Start, Step, &Plan.getVF(), IndDesc, Flags, DL);
738
739 ReplaceExtractsWithExitingIVValueIfPossible(WideIV);
740 return WideIV;
741}
742
743/// Try to sink users of \p FOR after \p Previous. \returns true if sinking
744/// succeeded or was not necessary, and false otherwise.
745static bool
746sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
747 VPRecipeBase *Previous,
748 const VPDominatorTree &VPDT) {
749 // Collect recipes that need sinking.
750 SmallVector<VPRecipeBase *> WorkList;
751 SmallPtrSet<VPRecipeBase *, 8> Seen;
752 Seen.insert(Ptr: Previous);
753 auto TryToPushSinkCandidate = [&](VPRecipeBase *SinkCandidate) {
754 // The previous value must not depend on the users of the recurrence phi.
755 // In that case, FOR is not a fixed order recurrence.
756 if (SinkCandidate == Previous)
757 return false;
758
759 if (isa<VPHeaderPHIRecipe>(Val: SinkCandidate) ||
760 !Seen.insert(Ptr: SinkCandidate).second ||
761 VPDT.properlyDominates(A: Previous, B: SinkCandidate))
762 return true;
763
764 if (vputils::cannotHoistOrSinkRecipe(R: *SinkCandidate, /*Sinking=*/true))
765 return false;
766
767 WorkList.push_back(Elt: SinkCandidate);
768 return true;
769 };
770
771 // Recursively sink users of FOR after Previous.
772 WorkList.push_back(Elt: FOR);
773 for (unsigned I = 0; I != WorkList.size(); ++I) {
774 VPRecipeBase *Current = WorkList[I];
775 assert(Current->getNumDefinedValues() == 1 &&
776 "only recipes with a single defined value expected");
777
778 for (VPUser *User : Current->getVPSingleValue()->users()) {
779 if (!TryToPushSinkCandidate(cast<VPRecipeBase>(Val: User)))
780 return false;
781 }
782 }
783
784 // Keep recipes to sink ordered by dominance so earlier instructions are
785 // processed first.
786 sort(C&: WorkList, Comp: [&VPDT](const VPRecipeBase *A, const VPRecipeBase *B) {
787 return VPDT.properlyDominates(A, B);
788 });
789
790 for (VPRecipeBase *SinkCandidate : WorkList) {
791 if (SinkCandidate == FOR)
792 continue;
793
794 SinkCandidate->moveAfter(MovePos: Previous);
795 Previous = SinkCandidate;
796 }
797 return true;
798}
799
800/// Try to hoist \p Previous and its operands before all users of \p FOR.
801/// \returns true if hoisting succeeded or was not necessary, and false
802/// otherwise.
803static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
804 VPRecipeBase *Previous,
805 const VPDominatorTree &VPDT) {
806 if (vputils::cannotHoistOrSinkRecipe(R: *Previous))
807 return false;
808
809 // Collect recipes that need hoisting.
810 SmallVector<VPRecipeBase *> HoistCandidates;
811 SmallPtrSet<VPRecipeBase *, 8> Visited;
812 // Find the closest hoist point by looking at all users of FOR and selecting
813 // the recipe dominating all other users.
814 VPRecipeBase *HoistPoint = nullptr;
815 for (VPUser *U : FOR->users()) {
816 auto *R = cast<VPRecipeBase>(Val: U);
817 if (!HoistPoint || VPDT.properlyDominates(A: R, B: HoistPoint))
818 HoistPoint = R;
819 }
820 // Dominance is only a partial order, so the users of FOR may not have a
821 // single user dominating all others. Bail out in that case.
822 if (!HoistPoint || HoistPoint->isPhi() ||
823 any_of(Range: FOR->users(), P: [&VPDT, HoistPoint](VPUser *U) {
824 auto *R = cast<VPRecipeBase>(Val: U);
825 return HoistPoint != R && !VPDT.properlyDominates(A: HoistPoint, B: R);
826 }))
827 return false;
828
829 auto NeedsHoisting = [HoistPoint, &VPDT,
830 &Visited](VPValue *HoistCandidateV) -> VPRecipeBase * {
831 VPRecipeBase *HoistCandidate = HoistCandidateV->getDefiningRecipe();
832 if (!HoistCandidate)
833 return nullptr;
834 // Hoist candidate was already visited, no need to hoist.
835 if (!Visited.insert(Ptr: HoistCandidate).second)
836 return nullptr;
837 // If we reached a recipe that dominates HoistPoint, we don't need to
838 // hoist the recipe.
839 if (VPDT.properlyDominates(A: HoistCandidate, B: HoistPoint))
840 return nullptr;
841 return HoistCandidate;
842 };
843
844 if (!NeedsHoisting(Previous->getVPSingleValue()))
845 return true;
846
847 // Recursively try to hoist Previous and its operands before all users of
848 // FOR.
849 HoistCandidates.push_back(Elt: Previous);
850
851 for (unsigned I = 0; I != HoistCandidates.size(); ++I) {
852 VPRecipeBase *Current = HoistCandidates[I];
853 assert(Current->getNumDefinedValues() == 1 &&
854 "only recipes with a single defined value expected");
855 if (vputils::cannotHoistOrSinkRecipe(R: *Current))
856 return false;
857
858 for (VPValue *Op : Current->operands()) {
859 // If we reach FOR, it means the original Previous depends on some other
860 // recurrence that in turn depends on FOR. If that is the case, we would
861 // also need to hoist recipes involving the other FOR, which may break
862 // dependencies.
863 if (Op == FOR)
864 return false;
865
866 if (auto *R = NeedsHoisting(Op)) {
867 // Bail out if the recipe defines multiple values.
868 // TODO: Hoisting such recipes requires additional handling.
869 if (R->getNumDefinedValues() != 1)
870 return false;
871 HoistCandidates.push_back(Elt: R);
872 }
873 }
874 }
875
876 // Moving a candidate to HoistPoint keeps it dominating its other users only
877 // if HoistPoint dominates the candidate's current position.
878 if (any_of(Range&: HoistCandidates, P: [&VPDT, HoistPoint](VPRecipeBase *R) {
879 return !VPDT.properlyDominates(A: HoistPoint, B: R);
880 }))
881 return false;
882
883 // Order recipes to hoist by dominance so earlier instructions are processed
884 // first.
885 sort(C&: HoistCandidates, Comp: [&VPDT](const VPRecipeBase *A, const VPRecipeBase *B) {
886 return VPDT.properlyDominates(A, B);
887 });
888
889 for (VPRecipeBase *HoistCandidate : HoistCandidates) {
890 HoistCandidate->moveBefore(BB&: *HoistPoint->getParent(),
891 I: HoistPoint->getIterator());
892 }
893
894 return true;
895}
896
897/// Sink users of fixed-order recurrences past or hoist before the recipe
898/// defining the previous value, introduce FirstOrderRecurrenceSplice
899/// VPInstructions, and replace FOR uses. Returns false if hoisting or sinking
900/// fails.
901static bool tryToSinkOrHoistRecurrenceUsers(VPBasicBlock *HeaderVPBB,
902 const VPDominatorTree &VPDT) {
903 auto FORs =
904 map_to_vector(C: make_filter_range(Range: HeaderVPBB->phis(),
905 Pred: IsaPred<VPFirstOrderRecurrencePHIRecipe>),
906 F: [](VPRecipeBase &R) {
907 return cast<VPFirstOrderRecurrencePHIRecipe>(Val: &R);
908 });
909 for (VPFirstOrderRecurrencePHIRecipe *FOR : FORs) {
910 // Follow through FOR phi chains to find the actual Previous recipe.
911 // Fixed-order recurrences do not contain cycles, so this loop is
912 // guaranteed to terminate.
913 SmallPtrSet<VPFirstOrderRecurrencePHIRecipe *, 4> SeenPhis;
914 VPRecipeBase *Previous = FOR->getBackedgeValue()->getDefiningRecipe();
915 while (auto *PrevPhi =
916 dyn_cast_or_null<VPFirstOrderRecurrencePHIRecipe>(Val: Previous)) {
917 assert(PrevPhi->getParent() == FOR->getParent() &&
918 "PrevPhi must be in same block as FOR");
919 assert(SeenPhis.insert(PrevPhi).second &&
920 "PrevPhi must not be visited multiple times");
921 Previous = PrevPhi->getBackedgeValue()->getDefiningRecipe();
922 }
923
924 VPBasicBlock *InsertBlock = FOR->getParent();
925 VPBasicBlock::iterator InsertPt = InsertBlock->getFirstNonPhi();
926 if (Previous) {
927 // Sink FOR users after Previous or hoist Previous before FOR users.
928 if (!sinkRecurrenceUsersAfterPrevious(FOR, Previous, VPDT) &&
929 !hoistPreviousBeforeFORUsers(FOR, Previous, VPDT))
930 return false;
931 InsertBlock = Previous->getParent();
932 InsertPt = isa<VPHeaderPHIRecipe>(Val: Previous)
933 ? InsertBlock->getFirstNonPhi()
934 : std::next(x: Previous->getIterator());
935 }
936
937 // Create FirstOrderRecurrenceSplice and replace FOR uses.
938 VPBuilder LoopBuilder(InsertBlock, InsertPt);
939 auto *RecurSplice =
940 LoopBuilder.createNaryOp(Opcode: VPInstruction::FirstOrderRecurrenceSplice,
941 Operands: {FOR, FOR->getBackedgeValue()});
942 FOR->replaceUsesWithIf(New: RecurSplice, ShouldReplace: not_equal_to(Arg&: RecurSplice));
943 }
944
945 return true;
946}
947
948bool VPlanTransforms::createHeaderPhiRecipes(
949 VPlan &Plan, PredicatedScalarEvolution &PSE, Loop &OrigLoop,
950 OptimizationRemarkEmitter *ORE, const VPDominatorTree &VPDT,
951 const MapVector<PHINode *, InductionDescriptor> &Inductions,
952 const MapVector<PHINode *, RecurrenceDescriptor> &Reductions,
953 const SmallPtrSetImpl<const PHINode *> &FixedOrderRecurrences,
954 const SmallPtrSetImpl<PHINode *> &InLoopReductions, bool AllowReordering) {
955 // Retrieve the header manually from the intial plain-CFG VPlan.
956 auto [HeaderVPBB, LatchVPBB] = VPBlockUtils::getPlainCFGHeaderAndLatch(Plan);
957 assert(VPDT.dominates(HeaderVPBB, LatchVPBB) &&
958 "header must dominate its latch");
959
960 auto CreateHeaderPhiRecipe = [&](VPPhi *PhiR) -> VPHeaderPHIRecipe * {
961 // TODO: Gradually replace uses of underlying instruction by analyses on
962 // VPlan.
963 auto *Phi = cast<PHINode>(Val: PhiR->getUnderlyingInstr());
964 assert(PhiR->getNumOperands() == 2 &&
965 "Must have 2 operands for header phis");
966
967 // Extract common values once.
968 VPIRValue *Start = cast<VPIRValue>(Val: PhiR->getOperand(N: 0));
969 VPValue *BackedgeValue = PhiR->getOperand(N: 1);
970
971 if (FixedOrderRecurrences.contains(Ptr: Phi)) {
972 // TODO: Currently fixed-order recurrences are modeled as chains of
973 // first-order recurrences. If there are no users of the intermediate
974 // recurrences in the chain, the fixed order recurrence should be
975 // modeled directly, enabling more efficient codegen.
976 return new VPFirstOrderRecurrencePHIRecipe(Phi, *Start, *BackedgeValue);
977 }
978
979 auto InductionIt = Inductions.find(Key: Phi);
980 if (InductionIt != Inductions.end())
981 return createWidenInductionRecipe(Phi, PhiR, Start, IndDesc: InductionIt->second,
982 Plan, PSE, OrigLoop,
983 DL: PhiR->getDebugLoc());
984
985 assert(Reductions.contains(Phi) && "only reductions are expected now");
986 const RecurrenceDescriptor &RdxDesc = Reductions.lookup(Key: Phi);
987 assert(RdxDesc.getRecurrenceStartValue() ==
988 Phi->getIncomingValueForBlock(OrigLoop.getLoopPreheader()) &&
989 "incoming value must match start value");
990 // Will be updated later to >1 if reduction is partial.
991 unsigned ScaleFactor = 1;
992 bool UseOrderedReductions = !AllowReordering && RdxDesc.isOrdered();
993 return new VPReductionPHIRecipe(
994 Phi, RdxDesc.getRecurrenceKind(), *Start, *BackedgeValue,
995 getReductionStyle(InLoop: InLoopReductions.contains(Ptr: Phi), Ordered: UseOrderedReductions,
996 ScaleFactor),
997 Phi->getType()->isFloatingPointTy() ? RdxDesc.getFastMathFlags()
998 : VPIRFlags(),
999 RdxDesc.hasUsesOutsideReductionChain());
1000 };
1001
1002 for (VPRecipeBase &R : make_early_inc_range(Range: HeaderVPBB->phis())) {
1003 auto *PhiR = cast<VPPhi>(Val: &R);
1004 VPHeaderPHIRecipe *HeaderPhiR = CreateHeaderPhiRecipe(PhiR);
1005 HeaderPhiR->insertBefore(InsertPos: PhiR);
1006 PhiR->replaceAllUsesWith(New: HeaderPhiR);
1007 PhiR->eraseFromParent();
1008 }
1009
1010 if (!tryToSinkOrHoistRecurrenceUsers(HeaderVPBB, VPDT)) {
1011 reportVectorizationFailure(
1012 DebugMsg: "Failed to sink or hoist user of first-order recurrence",
1013 ORETag: "CannotSinkHoistFORUser", ORE, TheLoop: &OrigLoop);
1014 return false;
1015 }
1016
1017 // Skip renaming resume phi recipes, if any header phi has been removed.
1018 if (range_size(Range: HeaderVPBB->phis()) !=
1019 range_size(Range: Plan.getScalarPreheader()->phis()))
1020 return true;
1021 for (const auto &[HeaderPhiR, ScalarPhiR] :
1022 zip_equal(t: HeaderVPBB->phis(), u: Plan.getScalarPreheader()->phis())) {
1023 auto *ResumePhiR = cast<VPPhi>(Val: &ScalarPhiR);
1024 if (isa<VPFirstOrderRecurrencePHIRecipe>(Val: &HeaderPhiR)) {
1025 ResumePhiR->setName("scalar.recur.init");
1026 auto *ExtractLastLane = cast<VPInstruction>(Val: ResumePhiR->getOperand(N: 0));
1027 ExtractLastLane->setName("vector.recur.extract");
1028 continue;
1029 }
1030 ResumePhiR->setName(isa<VPWidenInductionRecipe>(Val: HeaderPhiR)
1031 ? "bc.resume.val"
1032 : "bc.merge.rdx");
1033 }
1034 return true;
1035}
1036
1037bool VPlanTransforms::finalizeSCEVPredicates(VPlan &Plan,
1038 PredicatedScalarEvolution &PSE,
1039 bool OptForSize,
1040 unsigned SCEVCheckThreshold,
1041 OptimizationRemarkEmitter *ORE,
1042 Loop *TheLoop) {
1043 // Collect which wide IVs have predicates and add them to PSE.
1044 auto [HeaderVPBB, _] = VPBlockUtils::getPlainCFGHeaderAndLatch(Plan);
1045 SmallPtrSet<VPWidenInductionRecipe *, 4> PredicatedIVs;
1046 for (VPWidenInductionRecipe &WideIV :
1047 make_isa_range<VPWidenInductionRecipe>(Range: HeaderVPBB->phis())) {
1048 if (WideIV.getNoWrapPredicates().empty())
1049 continue;
1050 PredicatedIVs.insert(Ptr: &WideIV);
1051 for (const auto *P : WideIV.getNoWrapPredicates())
1052 PSE.addPredicate(Pred: *P);
1053 }
1054
1055 unsigned TotalComplexity = PSE.getPredicate().getComplexity();
1056 if (TotalComplexity && OptForSize) {
1057 LLVM_DEBUG(
1058 dbgs() << "LV: Not vectorizing: SCEV predicates needed for induction "
1059 "but optimizing for size\n");
1060 reportVectorizationFailure(
1061 DebugMsg: "Runtime SCEV check is required with -Os/-Oz",
1062 OREMsg: "runtime SCEV checks needed but optimizing for size",
1063 ORETag: "CantVersionLoopWithOptForSize", ORE, TheLoop);
1064 return false;
1065 }
1066
1067 if (TotalComplexity > SCEVCheckThreshold) {
1068 LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Too many SCEV checks needed ("
1069 << TotalComplexity << " > " << SCEVCheckThreshold
1070 << ")\n");
1071 reportVectorizationFailure(
1072 DebugMsg: "Too many SCEV checks needed",
1073 OREMsg: "Too many SCEV assumptions need to be made and checked at runtime",
1074 ORETag: "TooManySCEVRunTimeChecks", ORE, TheLoop);
1075 return false;
1076 }
1077
1078 return true;
1079}
1080
1081void VPlanTransforms::createInLoopReductionRecipes(VPlan &Plan,
1082 ElementCount MinVF) {
1083 VPBasicBlock *Header = Plan.getVectorLoopRegion()->getEntryBasicBlock();
1084 SmallVector<VPRecipeBase *> ToDelete;
1085
1086 for (VPRecipeBase &R : Header->phis()) {
1087 auto *PhiR = dyn_cast<VPReductionPHIRecipe>(Val: &R);
1088 if (!PhiR || !PhiR->isInLoop() || (MinVF.isScalar() && !PhiR->isOrdered()))
1089 continue;
1090
1091 RecurKind Kind = PhiR->getRecurrenceKind();
1092 assert(!RecurrenceDescriptor::isFindLastRecurrenceKind(Kind) &&
1093 !RecurrenceDescriptor::isAnyOfRecurrenceKind(Kind) &&
1094 !RecurrenceDescriptor::isFindIVRecurrenceKind(Kind) &&
1095 "AnyOf and Find reductions are not allowed for in-loop reductions");
1096
1097 bool IsFPRecurrence =
1098 RecurrenceDescriptor::isFloatingPointRecurrenceKind(Kind);
1099 FastMathFlags FMFs =
1100 IsFPRecurrence ? FastMathFlags::getFast() : FastMathFlags();
1101
1102 // Collect the chain of "link" recipes for the reduction starting at PhiR.
1103 SetVector<VPSingleDefRecipe *> Worklist;
1104 Worklist.insert(X: PhiR);
1105 for (unsigned I = 0; I != Worklist.size(); ++I) {
1106 VPSingleDefRecipe *Cur = Worklist[I];
1107 for (VPUser *U : Cur->users()) {
1108 auto *UserRecipe = cast<VPSingleDefRecipe>(Val: U);
1109 if (!UserRecipe->getParent()->getEnclosingLoopRegion()) {
1110 assert((UserRecipe->getParent() == Plan.getMiddleBlock() ||
1111 UserRecipe->getParent() == Plan.getScalarPreheader()) &&
1112 "U must be either in the loop region, the middle block or the "
1113 "scalar preheader.");
1114 continue;
1115 }
1116
1117 // Stores using instructions will be sunk later.
1118 if (match(R: UserRecipe, P: m_VPInstruction<Instruction::Store>()))
1119 continue;
1120 Worklist.insert(X: UserRecipe);
1121 }
1122 }
1123
1124 // Visit operation "Links" along the reduction chain top-down starting from
1125 // the phi until LoopExitValue. We keep track of the previous item
1126 // (PreviousLink) to tell which of the two operands of a Link will remain
1127 // scalar and which will be reduced. For minmax by select(cmp), Link will be
1128 // the select instructions. Blend recipes of in-loop reduction phi's will
1129 // get folded to their non-phi operand, as the reduction recipe handles the
1130 // condition directly.
1131 VPSingleDefRecipe *PreviousLink = PhiR; // Aka Worklist[0].
1132 for (VPSingleDefRecipe *CurrentLink : drop_begin(RangeOrContainer&: Worklist)) {
1133 if (auto *Blend = dyn_cast<VPBlendRecipe>(Val: CurrentLink)) {
1134 assert(Blend->getNumIncomingValues() == 2 &&
1135 "Blend must have 2 incoming values");
1136 unsigned PhiRIdx = Blend->getIncomingValue(Idx: 0) == PhiR ? 0 : 1;
1137 assert(Blend->getIncomingValue(PhiRIdx) == PhiR &&
1138 "PhiR must be an operand of the blend");
1139 Blend->replaceAllUsesWith(New: Blend->getIncomingValue(Idx: 1 - PhiRIdx));
1140 continue;
1141 }
1142
1143 if (IsFPRecurrence) {
1144 FastMathFlags CurFMF =
1145 cast<VPRecipeWithIRFlags>(Val: CurrentLink)->getFastMathFlagsOrNone();
1146 if (match(R: CurrentLink, P: m_Select(Op0: m_VPValue(), Op1: m_VPValue(), Op2: m_VPValue())))
1147 CurFMF |= cast<VPRecipeWithIRFlags>(Val: CurrentLink->getOperand(N: 0))
1148 ->getFastMathFlagsOrNone();
1149 FMFs &= CurFMF;
1150 }
1151
1152 Instruction *CurrentLinkI = CurrentLink->getUnderlyingInstr();
1153
1154 // Recognize a call to the llvm.fmuladd intrinsic.
1155 bool IsFMulAdd = Kind == RecurKind::FMulAdd;
1156 VPValue *VecOp;
1157 VPBasicBlock *LinkVPBB = CurrentLink->getParent();
1158 if (IsFMulAdd) {
1159 assert(RecurrenceDescriptor::isFMulAddIntrinsic(CurrentLinkI) &&
1160 "Expected current VPInstruction to be a call to the "
1161 "llvm.fmuladd intrinsic");
1162 assert(CurrentLink->getOperand(2) == PreviousLink &&
1163 "expected a call where the previous link is the added operand");
1164
1165 // If the instruction is a call to the llvm.fmuladd intrinsic then we
1166 // need to create an fmul recipe (multiplying the first two operands of
1167 // the fmuladd together) to use as the vector operand for the fadd
1168 // reduction.
1169 auto *FMulRecipe = new VPInstruction(
1170 Instruction::FMul,
1171 {CurrentLink->getOperand(N: 0), CurrentLink->getOperand(N: 1)},
1172 CurrentLinkI->getFastMathFlags());
1173 LinkVPBB->insert(Recipe: FMulRecipe, InsertPt: CurrentLink->getIterator());
1174 VecOp = FMulRecipe;
1175 } else if (Kind == RecurKind::AddChainWithSubs &&
1176 match(R: CurrentLink, P: m_Sub(Op0: m_VPValue(), Op1: m_VPValue()))) {
1177 Type *PhiTy = PhiR->getScalarType();
1178 auto *Zero = Plan.getConstantInt(Ty: PhiTy, Val: 0);
1179 VPBuilder Builder(LinkVPBB, CurrentLink->getIterator());
1180 auto *Sub = Builder.createSub(LHS: Zero, RHS: CurrentLink->getOperand(N: 1),
1181 DL: CurrentLinkI->getDebugLoc());
1182 Sub->setUnderlyingValue(CurrentLinkI);
1183 VecOp = Sub;
1184 } else {
1185 // Index of the first operand which holds a non-mask vector operand.
1186 unsigned IndexOfFirstOperand = 0;
1187 if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind)) {
1188 if (match(R: CurrentLink, P: m_Cmp(Op0: m_VPValue(), Op1: m_VPValue())))
1189 continue;
1190 assert(match(CurrentLink,
1191 m_Select(m_VPValue(), m_VPValue(), m_VPValue())) &&
1192 "must be a select recipe");
1193 IndexOfFirstOperand = 1;
1194 }
1195 // Note that for non-commutable operands (cmp-selects), the semantics of
1196 // the cmp-select are captured in the recurrence kind.
1197 unsigned VecOpId =
1198 CurrentLink->getOperand(N: IndexOfFirstOperand) == PreviousLink
1199 ? IndexOfFirstOperand + 1
1200 : IndexOfFirstOperand;
1201 VecOp = CurrentLink->getOperand(N: VecOpId);
1202 assert(
1203 VecOp != PreviousLink &&
1204 CurrentLink->getOperand(
1205 cast<VPInstruction>(CurrentLink)->getNumOperandsWithoutMask() -
1206 1 - (VecOpId - IndexOfFirstOperand)) == PreviousLink &&
1207 "PreviousLink must be the operand other than VecOp");
1208 }
1209
1210 assert(PhiR->getVFScaleFactor() == 1 &&
1211 "inloop reductions must be unscaled");
1212 VPValue *CondOp = cast<VPInstruction>(Val: CurrentLink)->getMask();
1213 auto *RedRecipe = new VPReductionRecipe(
1214 Kind, FMFs, CurrentLinkI, PreviousLink, VecOp, CondOp,
1215 getReductionStyle(/*IsInLoop=*/InLoop: true, Ordered: PhiR->isOrdered(), ScaleFactor: 1),
1216 CurrentLinkI->getDebugLoc());
1217 // Append the recipe to the end of the VPBasicBlock because we need to
1218 // ensure that it comes after all of it's inputs, including CondOp.
1219 // Delete CurrentLink as it will be invalid if its operand is replaced
1220 // with a reduction defined at the bottom of the block in the next link.
1221 if (LinkVPBB->getNumSuccessors() == 0)
1222 RedRecipe->insertBefore(InsertPos: &*std::prev(x: std::prev(x: LinkVPBB->end())));
1223 else
1224 LinkVPBB->appendRecipe(Recipe: RedRecipe);
1225
1226 CurrentLink->replaceAllUsesWith(New: RedRecipe);
1227 // Move any store recipes using the RedRecipe that appear before it in the
1228 // same block to just after the RedRecipe.
1229 for (VPRecipeBase *UserR : make_early_inc_range(
1230 Range: make_isa_range<VPRecipeBase>(Range: RedRecipe->users()))) {
1231 if (UserR->getParent() != LinkVPBB)
1232 continue;
1233 if (!match(V: UserR, P: m_VPInstruction<Instruction::Store>()))
1234 continue;
1235 UserR->moveAfter(MovePos: RedRecipe);
1236 }
1237 ToDelete.push_back(Elt: CurrentLink);
1238 PreviousLink = RedRecipe;
1239 }
1240 }
1241
1242 for (VPRecipeBase *R : ToDelete)
1243 R->eraseFromParent();
1244}
1245
1246bool VPlanTransforms::areAllLoadsDereferenceable(VPBasicBlock *HeaderVPBB,
1247 Loop *TheLoop,
1248 PredicatedScalarEvolution &PSE,
1249 DominatorTree &DT,
1250 AssumptionCache *AC) {
1251 ScalarEvolution &SE = *PSE.getSE();
1252 const DataLayout &DL = TheLoop->getHeader()->getDataLayout();
1253 for (VPBasicBlock *VPBB : vp_rpo_plain_cfg_loop_body(Header: HeaderVPBB)) {
1254 for (VPRecipeBase &R : *VPBB) {
1255 // Pseudo-probes are profiling placeholders with side effects but no real
1256 // memory access. They are modeled as reading inaccessible memory, so skip
1257 // them here to stay consistent with isReadOnlyLoop(), which classifies
1258 // such loops as read-only.
1259 if (match(V: &R, P: m_Intrinsic<Intrinsic::pseudoprobe>()))
1260 continue;
1261 auto *VPI = dyn_cast<VPInstruction>(Val: &R);
1262 if (!VPI || VPI->getOpcode() != Instruction::Load) {
1263 assert(!R.mayReadFromMemory() && "unexpected recipe reading memory");
1264 continue;
1265 }
1266
1267 // Get the pointer SCEV for dereferenceability checking.
1268 VPValue *Ptr = VPI->getOperand(N: 0);
1269 const SCEV *PtrSCEV = vputils::getSCEVExprForVPValue(V: Ptr, PSE, L: TheLoop);
1270 if (isa<SCEVCouldNotCompute>(Val: PtrSCEV)) {
1271 LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Found non-dereferenceable "
1272 "load with SCEVCouldNotCompute pointer\n");
1273 return false;
1274 }
1275
1276 // Check dereferenceability using the SCEV-based version.
1277 Type *LoadTy = VPI->getScalarType();
1278 const SCEV *SizeSCEV =
1279 SE.getStoreSizeOfExpr(IntTy: DL.getIndexType(PtrTy: PtrSCEV->getType()), StoreTy: LoadTy);
1280 auto *Load = cast<LoadInst>(Val: VPI->getUnderlyingValue());
1281 SmallVector<const SCEVPredicate *> Preds;
1282 if (isDereferenceableAndAlignedInLoop(PtrSCEV, Alignment: Load->getAlign(), EltSizeSCEV: SizeSCEV,
1283 L: TheLoop, SE, DT, AC, Predicates: &Preds))
1284 continue;
1285
1286 return false;
1287 }
1288 }
1289 return true;
1290}
1291
1292void VPlanTransforms::handleCountableEarlyExits(VPlan &Plan) {
1293 auto *MiddleVPBB = VPBlockUtils::getPlainCFGMiddleBlock(Plan);
1294 // Disconnect countable early exits from the loop, leaving it with a single
1295 // exit from the latch. Countable early exits are left for a scalar epilog.
1296 for (auto [EarlyExitingVPBB, EB] : vputils::getEarlyExits(Plan, MiddleVPBB)) {
1297 // Remove phi operands for the early exiting block.
1298 for (VPRecipeBase &R : EB->phis())
1299 cast<VPIRPhi>(Val: &R)->removeIncomingValueFor(IncomingBlock: EarlyExitingVPBB);
1300 EarlyExitingVPBB->getTerminator()->eraseFromParent();
1301 VPBlockUtils::disconnectBlocks(From: EarlyExitingVPBB, To: EB);
1302 }
1303}
1304
1305void VPlanTransforms::addMiddleCheck(VPlan &Plan) {
1306 auto *MiddleVPBB = VPBlockUtils::getPlainCFGMiddleBlock(Plan);
1307 // If MiddleVPBB has a single successor then the original loop does not exit
1308 // via the latch and the single successor must be the scalar preheader.
1309 // There's no need to add a runtime check to MiddleVPBB.
1310 if (MiddleVPBB->getNumSuccessors() == 1) {
1311 assert(MiddleVPBB->getSingleSuccessor() == Plan.getScalarPreheader() &&
1312 "must have ScalarPH as single successor");
1313 return;
1314 }
1315
1316 assert(MiddleVPBB->getNumSuccessors() == 2 && "must have 2 successors");
1317
1318 // Add a check in the middle block to see if we have completed all of the
1319 // iterations in the first vector loop.
1320 //
1321 // Three cases:
1322 // 1) If we require a scalar epilogue, the scalar ph must execute. Set the
1323 // condition to false.
1324 // 2) If (N - N%VF) == N, then we *don't* need to run the
1325 // remainder. Thus if tail is to be folded, we know we don't need to run
1326 // the remainder and we can set the condition to true.
1327 // 3) Otherwise, construct a runtime check.
1328
1329 // We use the same DebugLoc as the scalar loop latch terminator instead of
1330 // the corresponding compare because they may have ended up with different
1331 // line numbers and we want to avoid awkward line stepping while debugging.
1332 // E.g., if the compare has got a line number inside the loop.
1333 auto *LatchVPBB = cast<VPBasicBlock>(Val: MiddleVPBB->getSinglePredecessor());
1334 DebugLoc LatchDL = LatchVPBB->getTerminator()->getDebugLoc();
1335 VPBuilder Builder(MiddleVPBB);
1336 VPValue *Cmp =
1337 Builder.createICmp(Pred: CmpInst::ICMP_EQ, A: Plan.getTripCount(),
1338 B: &Plan.getVectorTripCount(), DL: LatchDL, Name: "cmp.n");
1339 Builder.createNaryOp(Opcode: VPInstruction::BranchOnCond, Operands: {Cmp}, DL: LatchDL);
1340}
1341
1342void VPlanTransforms::createLoopRegions(VPlan &Plan, DebugLoc DL) {
1343 VPDominatorTree VPDT(Plan);
1344 PostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>> POT(
1345 Plan.getEntry());
1346 // Headers and latches have been canonicalized by addInitialSkeleton.
1347 for (VPBlockBase *HeaderVPB : POT) {
1348 if (!VPBlockUtils::isHeader(VPB: HeaderVPB, VPDT))
1349 continue;
1350 assert(HeaderVPB->getPredecessors()[1]->getSuccessors().back() ==
1351 HeaderVPB &&
1352 "latch must have the header as last successor");
1353 createLoopRegion(Plan, HeaderVPB, DL);
1354 }
1355
1356 VPRegionBlock *TopRegion = Plan.getVectorLoopRegion();
1357 TopRegion->setName("vector loop");
1358 TopRegion->getEntryBasicBlock()->setName("vector.body");
1359}
1360
1361void VPlanTransforms::foldTailByMasking(VPlan &Plan) {
1362 assert(Plan.getExitBlocks().size() == 1 &&
1363 "only a single-exit block is supported currently");
1364 assert(Plan.getExitBlocks().front()->getSinglePredecessor() ==
1365 Plan.getMiddleBlock() &&
1366 "the exit block must have middle block as single predecessor");
1367
1368 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
1369 assert(LoopRegion->getSingleSuccessor() == Plan.getMiddleBlock() &&
1370 "The vector loop region must have the middle block as its single "
1371 "successor for now");
1372 VPBasicBlock *Header = LoopRegion->getEntryBasicBlock();
1373
1374 Header->splitAt(SplitAt: Header->getFirstNonPhi());
1375
1376 // Abstract header mask, materialized into concrete recipes later.
1377 VPValue *HeaderMask = LoopRegion->createHeaderMask();
1378 VPBuilder Builder(Header, Header->getFirstNonPhi());
1379 Builder.createNaryOp(Opcode: VPInstruction::BranchOnCond, Operands: HeaderMask);
1380
1381 VPBasicBlock *OrigLatch = LoopRegion->getExitingBasicBlock();
1382 VPValue *IVInc;
1383 [[maybe_unused]] bool TermBranchOnCount =
1384 match(V: OrigLatch->getTerminator(),
1385 P: m_BranchOnCount(Op0: m_VPValue(V&: IVInc),
1386 Op1: m_Specific(VPV: &Plan.getVectorTripCount())));
1387 assert(TermBranchOnCount &&
1388 match(IVInc, m_Add(m_Specific(LoopRegion->getCanonicalIV()),
1389 m_Specific(&Plan.getVFxUF()))) &&
1390 std::next(IVInc->getDefiningRecipe()->getIterator()) ==
1391 OrigLatch->getTerminator()->getIterator() &&
1392 "Unexpected canonical iv increment");
1393
1394 // Split the latch at the IV update, and branch to it from the header mask.
1395 VPBasicBlock *Latch =
1396 OrigLatch->splitAt(SplitAt: IVInc->getDefiningRecipe()->getIterator());
1397 Latch->setName("vector.latch");
1398 VPBlockUtils::connectBlocks(From: Header, To: Latch);
1399
1400 // Collect any values defined in the loop that need a phi, that is header phis
1401 // and any value defined n the loop and used in the middle block.
1402 // TODO: Handle early exits via Plan.getExitBlocks()
1403 MapVector<VPValue *, SmallVector<VPUser *>> NeedsPhi;
1404 auto CollectBypassedOperands = [&](VPRecipeBase &R) {
1405 for (VPValue *Op : R.operands()) {
1406 auto *DefR = Op->getDefiningRecipe();
1407 if (DefR && DefR->getParent()->getEnclosingLoopRegion() == LoopRegion &&
1408 !is_contained(Set: {Header, Latch}, Element: DefR->getParent()))
1409 NeedsPhi[Op].push_back(Elt: &R);
1410 }
1411 };
1412 for (VPRecipeBase &R : Header->phis())
1413 CollectBypassedOperands(R);
1414 for (VPRecipeBase &R : *Plan.getMiddleBlock())
1415 CollectBypassedOperands(R);
1416
1417 // Insert phis for values coming past the end of the tail.
1418 Builder.setInsertPoint(TheBB: Latch, IP: Latch->begin());
1419 for (const auto &[V, Users] : NeedsPhi) {
1420 VPValue *TailVal = Plan.getPoison(Ty: V->getScalarType());
1421 std::optional<VPIRFlags> Flags;
1422 assert(llvm::count_if(Users, IsaPred<VPReductionPHIRecipe>) <= 1 &&
1423 "Value used by more than two reduction phis?");
1424 auto *RedIt = find_if(Range: Users, P: IsaPred<VPReductionPHIRecipe>);
1425 auto *RdxPhi =
1426 RedIt != Users.end() ? cast<VPReductionPHIRecipe>(Val: *RedIt) : nullptr;
1427 if (RdxPhi && !RdxPhi->isInLoop()) {
1428 TailVal = RdxPhi;
1429 Flags = *RdxPhi;
1430 }
1431
1432 VPInstruction *Phi = Builder.createScalarPhi(IncomingValues: {V, TailVal}, DL: {}, Name: "", Flags);
1433 for (VPUser *U : Users)
1434 U->replaceUsesOfWith(From: V, To: Phi);
1435 }
1436
1437 // Any extract of the last element must be updated to extract from the last
1438 // active lane of the header mask instead (i.e., the lane corresponding to the
1439 // last active iteration).
1440 Builder.setInsertPoint(Plan.getMiddleBlock()->getTerminator());
1441 for (VPRecipeBase &R : *Plan.getMiddleBlock()) {
1442 VPValue *Op;
1443 if (!match(V: &R, P: m_ExtractLastLaneOfLastPart(Op0: m_VPValue(V&: Op))))
1444 continue;
1445
1446 // Compute the index of the last active lane.
1447 VPValue *LastActiveLane = Builder.createLastActiveLane(Masks: HeaderMask);
1448 auto *Ext =
1449 Builder.createNaryOp(Opcode: VPInstruction::ExtractLane, Operands: {LastActiveLane, Op});
1450 R.getVPSingleValue()->replaceAllUsesWith(New: Ext);
1451 }
1452
1453 // VectorTripCount now equals TripCount so simplify the MiddleVPBB branch.
1454 assert(match(Plan.getMiddleBlock()->getTerminator(),
1455 m_BranchOnCond(m_SpecificICmp(
1456 CmpInst::ICMP_EQ, m_Specific(Plan.getTripCount()),
1457 m_Specific(&Plan.getVectorTripCount())))) &&
1458 "Unexpected MiddleVPBB branch");
1459 Plan.getMiddleBlock()->getTerminator()->setOperand(I: 0, New: Plan.getTrue());
1460}
1461
1462/// Add an incoming value to all phis in \p VPBB for its just-added last
1463/// predecessor, re-using the value of the previously last one.
1464static void addIncomingForLastPredecessor(VPBasicBlock *VPBB) {
1465 for (VPRecipeBase &R : VPBB->phis()) {
1466 auto *Phi = cast<VPPhi>(Val: &R);
1467 assert(Phi->getNumIncoming() == VPBB->getNumPredecessors() - 1 &&
1468 "must have incoming values for all predecessors but the new one");
1469 Phi->addIncoming(IncomingV: Phi->getIncomingValue(Idx: Phi->getNumIncoming() - 1));
1470 }
1471}
1472
1473/// Insert \p CheckBlockVPBB on the edge leading to the vector preheader,
1474/// connecting it to both vector and scalar preheaders. Updates scalar
1475/// preheader phis to account for the new predecessor.
1476static void insertCheckBlockBeforeVectorLoop(VPlan &Plan,
1477 VPBasicBlock *CheckBlockVPBB) {
1478 VPBlockBase *VectorPH = Plan.getVectorPreheader();
1479 auto *ScalarPH = cast<VPBasicBlock>(Val: Plan.getScalarPreheader());
1480 VPBlockBase *PreVectorPH = VectorPH->getSinglePredecessor();
1481 VPBlockUtils::insertOnEdge(From: PreVectorPH, To: VectorPH, BlockPtr: CheckBlockVPBB);
1482 VPBlockUtils::connectBlocks(From: CheckBlockVPBB, To: ScalarPH);
1483 CheckBlockVPBB->swapSuccessors();
1484 addIncomingForLastPredecessor(VPBB: ScalarPH);
1485}
1486
1487void VPlanTransforms::modelGeneratedMainLoopBlocks(
1488 VPlan &EpiPlan, VPlan &MainPlan, VPIRBasicBlock *EnteredFrom) {
1489 // Map blocks from MainPlan to new, empty VPIRBasicBlocks in EpiPlan, so the
1490 // skeleton CFG can be modeled explicitly. MainPlan's entry maps to EpiPlan's
1491 // now-disconnected entry and its scalar PH to EnteredFrom.
1492 VPBlockBase *MainEntry = MainPlan.getEntry();
1493 VPBlockBase *MainScalarPH = MainPlan.getScalarPreheader();
1494 SmallMapVector<VPBlockBase *, VPBlockBase *, 8> MainToEpiVPBB;
1495 MainToEpiVPBB[MainEntry] = EpiPlan.getEntry();
1496 ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>> RPOT(
1497 MainEntry);
1498 for (VPIRBasicBlock *VPBB : VPBlockUtils::blocksAs<VPIRBasicBlock>(Range&: RPOT))
1499 // Skip entry block and exit blocks/scalar loop header; they are already
1500 // modeled in the epilogue plan.
1501 if (VPBB != MainEntry && VPBB != MainScalarPH && VPBB->hasSuccessors())
1502 MainToEpiVPBB[VPBB] =
1503 EpiPlan.createEmptyVPIRBasicBlock(IRBB: VPBB->getIRBasicBlock());
1504 MainToEpiVPBB[MainScalarPH] = EnteredFrom;
1505
1506 // First, connect the edges from the bypass blocks (minimum iteration checks,
1507 // runtime checks) to the scalar preheader, in reverse order, to preserve the
1508 // predecessor order of the generated IR.
1509 VPBasicBlock *EpiScalarPH = EpiPlan.getScalarPreheader();
1510 for (VPBlockBase *MainVPBB :
1511 reverse(C: drop_end(RangeOrContainer: drop_begin(RangeOrContainer: MainScalarPH->predecessors())))) {
1512 VPBlockUtils::connectBlocks(From: MainToEpiVPBB.lookup(Key: MainVPBB), To: EpiScalarPH);
1513 addIncomingForLastPredecessor(VPBB: EpiScalarPH);
1514 }
1515
1516 // Mirror MainPlan's CFG, skipping the bypass edges connected above, which
1517 // come first, and edges to blocks not modeled in EpiPlan.
1518 for (auto &[MainVPBB, EpiVPBB] : drop_end(RangeOrContainer&: MainToEpiVPBB))
1519 for (VPBlockBase *Succ :
1520 drop_begin(RangeOrContainer&: MainVPBB->getSuccessors(), N: EpiVPBB->getNumSuccessors()))
1521 if (auto *SuccVPBB = MainToEpiVPBB.lookup(Key: Succ))
1522 VPBlockUtils::connectBlocks(From: EpiVPBB, To: SuccVPBB);
1523
1524 // EnteredFrom is the only modeled block with phis; re-use the incoming values
1525 // its IR phis already have for the new predecessors.
1526 for (VPRecipeBase &R : EnteredFrom->phis()) {
1527 auto *PhiR = cast<VPIRPhi>(Val: &R);
1528 for (VPIRBasicBlock *Pred :
1529 VPBlockUtils::blocksAs<VPIRBasicBlock>(Range&: EnteredFrom->getPredecessors()))
1530 PhiR->addIncoming(IncomingV: EpiPlan.getOrAddLiveIn(
1531 V: PhiR->getIRPhi().getIncomingValueForBlock(BB: Pred->getIRBasicBlock())));
1532 }
1533}
1534
1535// Likelyhood of bypassing the vectorized loop due to a runtime check block,
1536// including memory overlap checks block and wrapping/unit-stride checks block.
1537static constexpr uint32_t CheckBypassWeights[] = {1, 127};
1538
1539/// Create a BranchOnCond terminator in \p CheckBlockVPBB. Optionally adds
1540/// branch weights.
1541static void addBypassBranch(VPlan &Plan, VPBasicBlock *CheckBlockVPBB,
1542 VPValue *Cond, bool AddBranchWeights) {
1543 DebugLoc DL = Plan.getVectorLoopRegion()->getCanonicalIV()->getDebugLoc();
1544 auto *Term = VPBuilder(CheckBlockVPBB)
1545 .createNaryOp(Opcode: VPInstruction::BranchOnCond, Operands: {Cond}, DL);
1546 if (AddBranchWeights) {
1547 MDBuilder MDB(Plan.getContext());
1548 MDNode *BranchWeights =
1549 MDB.createBranchWeights(Weights: CheckBypassWeights, /*IsExpected=*/false);
1550 Term->setMetadata(Kind: LLVMContext::MD_prof, Node: BranchWeights);
1551 }
1552}
1553
1554void VPlanTransforms::attachVPCheckBlock(VPlan &Plan, VPValue *Cond,
1555 VPBasicBlock *CheckBlock,
1556 bool AddBranchWeights) {
1557 insertCheckBlockBeforeVectorLoop(Plan, CheckBlockVPBB: CheckBlock);
1558 addBypassBranch(Plan, CheckBlockVPBB: CheckBlock, Cond, AddBranchWeights);
1559}
1560
1561void VPlanTransforms::attachCheckBlock(VPlan &Plan, Value *Cond,
1562 BasicBlock *CheckBlock,
1563 bool AddBranchWeights) {
1564 VPValue *CondVPV = Plan.getOrAddLiveIn(V: Cond);
1565 VPBasicBlock *CheckBlockVPBB = Plan.createVPIRBasicBlock(IRBB: CheckBlock);
1566 attachVPCheckBlock(Plan, Cond: CondVPV, CheckBlock: CheckBlockVPBB, AddBranchWeights);
1567}
1568
1569/// Generate recipes for the memory runtime checks \p Checks using \p Builder
1570/// and return the condition that is true if any check fails.
1571static VPValue *createRuntimeChecks(VPlan &Plan, VPBuilder &Builder,
1572 VPSCEVExpander &Expander,
1573 ArrayRef<RuntimePointerCheck> Checks,
1574 DebugLoc DL) {
1575 // Expand each group's bounds once so all checks reuse the same frozen values.
1576 SmallDenseMap<const RuntimeCheckingPtrGroup *,
1577 std::pair<VPValue *, VPValue *>, 8>
1578 GroupToBounds;
1579 for (const auto &[A, B] : Checks)
1580 for (const RuntimeCheckingPtrGroup *CG : {A, B}) {
1581 auto &[Start, End] = GroupToBounds[CG];
1582 if (Start)
1583 continue;
1584 Start = Expander.expand(S: CG->Low);
1585 End = Expander.expand(S: CG->High);
1586 if (CG->NeedsFreeze) {
1587 Start = Builder.createFreeze(Op: Start, DL);
1588 End = Builder.createFreeze(Op: End, DL);
1589 }
1590 }
1591
1592 VPValue *Cond = Plan.getFalse();
1593 for (const auto &[A, B] : Checks) {
1594 auto [AStart, AEnd] = GroupToBounds[A];
1595 auto [BStart, BEnd] = GroupToBounds[B];
1596 VPValue *Bound0 =
1597 Builder.createICmp(Pred: CmpInst::ICMP_ULT, A: AStart, B: BEnd, DL, Name: "bound0");
1598 VPValue *Bound1 =
1599 Builder.createICmp(Pred: CmpInst::ICMP_ULT, A: BStart, B: AEnd, DL, Name: "bound1");
1600 VPValue *IsConflict =
1601 Builder.createAnd(LHS: Bound0, RHS: Bound1, DL, Name: "found.conflict");
1602 Cond = Builder.createOr(LHS: Cond, RHS: IsConflict, DL, Name: "conflict.rdx");
1603 }
1604 return Cond;
1605}
1606
1607/// Generate recipes for the memory runtime difference checks \p Checks using
1608/// \p Builder and return the condition that is true if any check fails. Each
1609/// difference is compared against a threshold derived from \p VF and \p UF.
1610static VPValue *createDiffRuntimeChecks(VPlan &Plan, VPBuilder &Builder,
1611 VPSCEVExpander &Expander,
1612 ArrayRef<PointerDiffInfo> Checks,
1613 ScalarEvolution &SE, ElementCount VF,
1614 unsigned UF, DebugLoc DL) {
1615 // Set of operand pairs of already created compares, to allow detecting and
1616 // re-using redundant compares.
1617 SmallDenseSet<std::pair<const SCEV *, const SCEV *>, 8> SeenCompares;
1618 VPValue *Cond = Plan.getFalse();
1619 for (const auto &[SrcStart, SinkStart, AccessSize, NeedsFreeze] : Checks) {
1620 assert(UF * AccessSize > 0 &&
1621 "Threshold must be non-zero to use diff-check");
1622 Type *Ty = SinkStart->getType();
1623 const SCEV *TotalAccessSize = SE.getElementCount(Ty, EC: VF * UF * AccessSize);
1624 const SCEV *ThresholdMinusOneSCEV =
1625 SE.getMinusSCEV(LHS: TotalAccessSize, RHS: SE.getOne(Ty));
1626 const SCEV *DiffSCEV = SE.getMinusSCEV(LHS: SinkStart, RHS: SrcStart);
1627
1628 // If the same compare has already been created earlier, there is no need to
1629 // check it again.
1630 if (!SeenCompares.insert(V: {DiffSCEV, ThresholdMinusOneSCEV}).second)
1631 continue;
1632
1633 VPValue *ThresholdMinusOne = Expander.expand(S: ThresholdMinusOneSCEV);
1634 VPValue *Diff = Expander.expand(S: DiffSCEV);
1635 // Use (Diff - 1) <u (Threshold - 1), equivalent to 0 <u Diff <u Threshold,
1636 // to exclude Diff == 0 (equal pointers are safe).
1637 VPValue *DiffMinusOne =
1638 Builder.createSub(LHS: Diff, RHS: Plan.getConstantInt(Ty, Val: 1), DL);
1639 VPValue *IsConflict = Builder.createICmp(
1640 Pred: CmpInst::ICMP_ULT, A: DiffMinusOne, B: ThresholdMinusOne, DL, Name: "diff.check");
1641 if (NeedsFreeze)
1642 IsConflict = Builder.createFreeze(Op: IsConflict, DL, Name: "diff.check.fr");
1643 Cond = Builder.createOr(LHS: Cond, RHS: IsConflict, DL, Name: "conflict.rdx");
1644 }
1645 return Cond;
1646}
1647
1648void VPlanTransforms::attachMemoryChecks(
1649 VPlan &Plan, const RuntimePointerChecking &RtPtrChecking,
1650 ScalarEvolution &SE, ElementCount VF, unsigned UF, DebugLoc DL,
1651 bool AddBranchWeights) {
1652 assert(!RtPtrChecking.getChecks().empty() && "No checks to generate");
1653
1654 auto *MemCheckVPBB = Plan.createVPBasicBlock(Name: "vector.memcheck");
1655 VPBuilder Builder(MemCheckVPBB);
1656 VPSCEVExpander Expander(Builder, SE, DL);
1657 auto DiffChecks = RtPtrChecking.getDiffChecks();
1658 VPValue *Cond = DiffChecks
1659 ? createDiffRuntimeChecks(Plan, Builder, Expander,
1660 Checks: *DiffChecks, SE, VF, UF, DL)
1661 : createRuntimeChecks(Plan, Builder, Expander,
1662 Checks: RtPtrChecking.getChecks(), DL);
1663 attachVPCheckBlock(Plan, Cond, CheckBlock: MemCheckVPBB, AddBranchWeights);
1664}
1665
1666void VPlanTransforms::addMinimumIterationCheck(
1667 VPlan &Plan, ElementCount VF, unsigned UF,
1668 ElementCount MinProfitableTripCount, bool RequiresScalarEpilogue,
1669 bool TailFolded, Loop *OrigLoop, const uint32_t *MinItersBypassWeights,
1670 DebugLoc DL, PredicatedScalarEvolution &PSE, VPBasicBlock *CheckBlock) {
1671 // Generate code to check if the loop's trip count is less than VF * UF, or
1672 // equal to it in case a scalar epilogue is required; this implies that the
1673 // vector trip count is zero. This check also covers the case where adding one
1674 // to the backedge-taken count overflowed leading to an incorrect trip count
1675 // of zero. In this case we will also jump to the scalar loop.
1676 CmpInst::Predicate CmpPred =
1677 RequiresScalarEpilogue ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
1678 // If tail is to be folded, vector loop takes care of all iterations.
1679 VPValue *TripCountVPV = Plan.getTripCount();
1680 const SCEV *TripCount = vputils::getSCEVExprForVPValue(V: TripCountVPV, PSE);
1681 Type *TripCountTy = TripCount->getType();
1682 ScalarEvolution &SE = *PSE.getSE();
1683 auto GetMinTripCount = [&]() -> const SCEV * {
1684 // Compute max(MinProfitableTripCount, UF * VF) and return it.
1685 const SCEV *VFxUF =
1686 SE.getElementCount(Ty: TripCountTy, EC: (VF * UF), Flags: SCEV::FlagNUW);
1687 if (UF * VF.getKnownMinValue() >=
1688 MinProfitableTripCount.getKnownMinValue()) {
1689 // TODO: SCEV should be able to simplify test.
1690 return VFxUF;
1691 }
1692 const SCEV *MinProfitableTripCountSCEV =
1693 SE.getElementCount(Ty: TripCountTy, EC: MinProfitableTripCount, Flags: SCEV::FlagNUW);
1694 return SE.getUMaxExpr(LHS: MinProfitableTripCountSCEV, RHS: VFxUF);
1695 };
1696
1697 VPBuilder Builder(CheckBlock);
1698 VPValue *TripCountCheck = Plan.getFalse();
1699 const SCEV *Step = GetMinTripCount();
1700 // TripCountCheck = false, folding tail implies positive vector trip
1701 // count.
1702 if (!TailFolded) {
1703 // TODO: Emit unconditional branch to vector preheader instead of
1704 // conditional branch with known condition.
1705 TripCount = SE.applyLoopGuards(Expr: TripCount, L: OrigLoop);
1706 // Check if the trip count is < the step.
1707 if (SE.isKnownPredicate(Pred: CmpPred, LHS: TripCount, RHS: Step)) {
1708 // TODO: Ensure step is at most the trip count when determining max VF and
1709 // UF, w/o tail folding.
1710 TripCountCheck = Plan.getTrue();
1711 } else if (!SE.isKnownPredicate(Pred: CmpInst::getInversePredicate(pred: CmpPred),
1712 LHS: TripCount, RHS: Step)) {
1713 // Generate the minimum iteration check only if we cannot prove the
1714 // check is known to be true, or known to be false.
1715 VPValue *MinTripCountVPV =
1716 VPSCEVExpander(Builder, *PSE.getSE(), DL).expand(S: Step);
1717 TripCountCheck = Builder.createICmp(
1718 Pred: CmpPred, A: TripCountVPV, B: MinTripCountVPV, DL, Name: "min.iters.check");
1719 } // else step known to be < trip count, use TripCountCheck preset to false.
1720 }
1721 VPInstruction *Term =
1722 Builder.createNaryOp(Opcode: VPInstruction::BranchOnCond, Operands: {TripCountCheck}, DL);
1723 if (MinItersBypassWeights) {
1724 MDBuilder MDB(Plan.getContext());
1725 MDNode *BranchWeights = MDB.createBranchWeights(
1726 Weights: ArrayRef(MinItersBypassWeights, 2), /*IsExpected=*/false);
1727 Term->setMetadata(Kind: LLVMContext::MD_prof, Node: BranchWeights);
1728 }
1729}
1730
1731void VPlanTransforms::addIterationCountCheckBlock(
1732 VPlan &Plan, ElementCount VF, unsigned UF, bool RequiresScalarEpilogue,
1733 Loop *OrigLoop, const uint32_t *MinItersBypassWeights, DebugLoc DL,
1734 PredicatedScalarEvolution &PSE) {
1735 auto *CheckBlock = Plan.createVPBasicBlock(Name: "vector.main.loop.iter.check");
1736 insertCheckBlockBeforeVectorLoop(Plan, CheckBlockVPBB: CheckBlock);
1737 addMinimumIterationCheck(Plan, VF, UF, MinProfitableTripCount: ElementCount::getFixed(MinVal: 0),
1738 RequiresScalarEpilogue, /*TailFolded=*/false,
1739 OrigLoop, MinItersBypassWeights, DL, PSE,
1740 CheckBlock);
1741}
1742
1743void VPlanTransforms::addMinimumVectorEpilogueIterationCheck(
1744 VPlan &Plan, VPValue *MainVectorTripCount, bool RequiresScalarEpilogue,
1745 ElementCount EpilogueVF, unsigned MainLoopStep, unsigned EpilogueLoopStep,
1746 ScalarEvolution &SE) {
1747 // Add the minimum iteration check for the epilogue vector loop.
1748 VPValue *TC = Plan.getTripCount();
1749 VPBuilder Builder(cast<VPBasicBlock>(Val: Plan.getEntry()));
1750 VPValue *VFxUF = Builder.createExpandSCEV(
1751 Expr: SE.getElementCount(Ty: TC->getScalarType(), EC: EpilogueVF, Flags: SCEV::FlagNUW));
1752 VPValue *Count = Builder.createSub(LHS: TC, RHS: MainVectorTripCount,
1753 DL: DebugLoc::getUnknown(), Name: "n.vec.remaining");
1754
1755 // Generate code to check if the loop's trip count is less than VF * UF of
1756 // the vector epilogue loop.
1757 auto P = RequiresScalarEpilogue ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
1758 auto *CheckMinIters = Builder.createICmp(
1759 Pred: P, A: Count, B: VFxUF, DL: DebugLoc::getUnknown(), Name: "min.epilog.iters.check");
1760 VPInstruction *Branch =
1761 Builder.createNaryOp(Opcode: VPInstruction::BranchOnCond, Operands: CheckMinIters);
1762
1763 // We assume the remaining `Count` is equally distributed in
1764 // [0, MainLoopStep)
1765 // So the probability for `Count < EpilogueLoopStep` should be
1766 // min(MainLoopStep, EpilogueLoopStep) / MainLoopStep
1767 // TODO: Improve the estimate by taking the estimated trip count into
1768 // consideration.
1769 unsigned EstimatedSkipCount = std::min(a: MainLoopStep, b: EpilogueLoopStep);
1770 const uint32_t Weights[] = {EstimatedSkipCount,
1771 MainLoopStep - EstimatedSkipCount};
1772 MDBuilder MDB(Plan.getContext());
1773 MDNode *BranchWeights =
1774 MDB.createBranchWeights(Weights, /*IsExpected=*/false);
1775 Branch->setMetadata(Kind: LLVMContext::MD_prof, Node: BranchWeights);
1776}
1777
1778/// Find and return the final select instruction of the FindIV result pattern
1779/// for the given \p BackedgeVal:
1780/// select(icmp ne ComputeReductionResult(ReducedIV), Sentinel),
1781/// ComputeReductionResult(ReducedIV), Start.
1782static VPInstruction *findFindIVSelect(VPValue *BackedgeVal) {
1783 return cast<VPInstruction>(
1784 Val: vputils::findRecipe(Start: BackedgeVal, Pred: [BackedgeVal](VPRecipeBase *R) {
1785 auto *VPI = dyn_cast<VPInstruction>(Val: R);
1786 return VPI &&
1787 matchFindIVResult(VPI, ReducedIV: m_Specific(VPV: BackedgeVal), Start: m_VPValue());
1788 }));
1789}
1790
1791bool VPlanTransforms::handleMaxMinNumReductions(VPlan &Plan) {
1792 auto GetMinOrMaxCompareValue =
1793 [](VPReductionPHIRecipe *RedPhiR) -> VPValue * {
1794 auto *MinOrMaxR =
1795 dyn_cast_or_null<VPRecipeWithIRFlags>(Val: RedPhiR->getBackedgeValue());
1796 if (!MinOrMaxR)
1797 return nullptr;
1798
1799 // Check that MinOrMaxR is a VPWidenIntrinsicRecipe or VPReplicateRecipe
1800 // with an intrinsic that matches the reduction kind.
1801 Intrinsic::ID ExpectedIntrinsicID =
1802 getMinMaxReductionIntrinsicOp(RK: RedPhiR->getRecurrenceKind());
1803 if (!match(V: MinOrMaxR, P: m_Intrinsic(IntrID: ExpectedIntrinsicID)))
1804 return nullptr;
1805
1806 // MinOrMaxR must combine RedPhiR directly with the new element, as the NaN
1807 // check added below only covers the other operand.
1808 // TODO: Support multi-step min/max chains (e.g. maxnum(l, maxnum(k, phi)))
1809 // by checking all operands feeding the chain for NaNs.
1810 if (MinOrMaxR->getOperand(N: 0) == RedPhiR)
1811 return MinOrMaxR->getOperand(N: 1);
1812 if (MinOrMaxR->getOperand(N: 1) == RedPhiR)
1813 return MinOrMaxR->getOperand(N: 0);
1814 return nullptr;
1815 };
1816
1817 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
1818 SmallVector<std::pair<VPReductionPHIRecipe *, VPValue *>>
1819 MinOrMaxNumReductionsToHandle;
1820 bool HasUnsupportedPhi = false;
1821 for (auto &R : LoopRegion->getEntryBasicBlock()->phis()) {
1822 if (isa<VPWidenIntOrFpInductionRecipe>(Val: &R))
1823 continue;
1824 auto *Cur = dyn_cast<VPReductionPHIRecipe>(Val: &R);
1825 if (!Cur) {
1826 // TODO: Also support fixed-order recurrence phis.
1827 HasUnsupportedPhi = true;
1828 continue;
1829 }
1830 if (!RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind(
1831 Kind: Cur->getRecurrenceKind())) {
1832 HasUnsupportedPhi = true;
1833 continue;
1834 }
1835
1836 VPValue *MinOrMaxOp = GetMinOrMaxCompareValue(Cur);
1837 if (!MinOrMaxOp)
1838 return false;
1839
1840 MinOrMaxNumReductionsToHandle.emplace_back(Args&: Cur, Args&: MinOrMaxOp);
1841 }
1842
1843 if (MinOrMaxNumReductionsToHandle.empty())
1844 return true;
1845
1846 // We won't be able to resume execution in the scalar tail, if there are
1847 // unsupported header phis or there is no scalar tail at all, due to
1848 // tail-folding.
1849 if (HasUnsupportedPhi || !Plan.hasScalarTail())
1850 return false;
1851
1852 /// Check if the vector loop of \p Plan can early exit and restart
1853 /// execution of last vector iteration in the scalar loop. This requires all
1854 /// recipes up to early exit point be side-effect free as they are
1855 /// re-executed. Currently we check that the loop is free of any recipe that
1856 /// may write to memory. Expected to operate on an early VPlan w/o nested
1857 /// regions.
1858 for (VPBlockBase *VPB : vp_depth_first_shallow(
1859 G: Plan.getVectorLoopRegion()->getEntryBasicBlock())) {
1860 auto *VPBB = cast<VPBasicBlock>(Val: VPB);
1861 for (auto &R : *VPBB) {
1862 if (R.mayWriteToMemory() && !match(V: &R, P: m_BranchOnCount()))
1863 return false;
1864 }
1865 }
1866
1867 // Freeze MinOrMaxOps since:
1868 // * multiple uses are introduced and the value may be undef
1869 // * they feed into a branch condition, so block poison propagation to
1870 // prevent immediate UB
1871 for (auto &[Phi, MinOrMaxOp] : MinOrMaxNumReductionsToHandle) {
1872 VPRecipeBase *MinOrMaxR = Phi->getBackedgeValue()->getDefiningRecipe();
1873 VPInstruction *Freeze = VPBuilder(MinOrMaxR).createFreeze(Op: MinOrMaxOp);
1874 MinOrMaxR->replaceUsesOfWith(From: MinOrMaxOp, To: Freeze);
1875 MinOrMaxOp = Freeze;
1876 }
1877
1878 VPBasicBlock *LatchVPBB = LoopRegion->getExitingBasicBlock();
1879 VPBuilder LatchBuilder(LatchVPBB->getTerminator());
1880 VPValue *AllNaNLanes = nullptr;
1881 SmallPtrSet<VPValue *, 2> RdxResults;
1882 for (const auto &[_, MinOrMaxOp] : MinOrMaxNumReductionsToHandle) {
1883 VPValue *RedNaNLanes =
1884 LatchBuilder.createFCmp(Pred: CmpInst::FCMP_UNO, A: MinOrMaxOp, B: MinOrMaxOp);
1885 AllNaNLanes = AllNaNLanes ? LatchBuilder.createOr(LHS: AllNaNLanes, RHS: RedNaNLanes)
1886 : RedNaNLanes;
1887 }
1888
1889 VPValue *AnyNaNLane =
1890 LatchBuilder.createNaryOp(Opcode: VPInstruction::AnyOf, Operands: {AllNaNLanes});
1891 VPBasicBlock *MiddleVPBB = Plan.getMiddleBlock();
1892 VPBuilder MiddleBuilder(MiddleVPBB, MiddleVPBB->begin());
1893 for (const auto &[RedPhiR, _] : MinOrMaxNumReductionsToHandle) {
1894 assert(RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind(
1895 RedPhiR->getRecurrenceKind()) &&
1896 "unsupported reduction");
1897
1898 // If we exit early due to NaNs, compute the final reduction result based on
1899 // the reduction phi at the beginning of the last vector iteration.
1900 auto *RdxResult = vputils::findComputeReductionResult(PhiR: RedPhiR);
1901 assert(RdxResult && "must find a ComputeReductionResult");
1902
1903 auto *NewSel = MiddleBuilder.createSelect(Cond: AnyNaNLane, TrueVal: RedPhiR,
1904 FalseVal: RdxResult->getOperand(N: 0));
1905 RdxResult->setOperand(I: 0, New: NewSel);
1906 assert(!RdxResults.contains(RdxResult) && "RdxResult already used");
1907 RdxResults.insert(Ptr: RdxResult);
1908 }
1909
1910 auto *LatchExitingBranch = LatchVPBB->getTerminator();
1911 assert(match(LatchExitingBranch, m_BranchOnCount(m_VPValue(), m_VPValue())) &&
1912 "Unexpected terminator");
1913 auto *IsLatchExitTaken = LatchBuilder.createICmp(
1914 Pred: CmpInst::ICMP_EQ, A: LatchExitingBranch->getOperand(N: 0),
1915 B: LatchExitingBranch->getOperand(N: 1));
1916 auto *AnyExitTaken = LatchBuilder.createOr(LHS: AnyNaNLane, RHS: IsLatchExitTaken);
1917 LatchBuilder.createNaryOp(Opcode: VPInstruction::BranchOnCond, Operands: AnyExitTaken);
1918 LatchExitingBranch->eraseFromParent();
1919
1920 // Update resume phis for inductions in the scalar preheader. If AnyNaNLane is
1921 // true, the resume from the start of the last vector iteration via the
1922 // canonical IV, otherwise from the original value.
1923 auto IsTC = [&Plan](VPValue *V) {
1924 return V == &Plan.getVectorTripCount() || V == Plan.getTripCount();
1925 };
1926 for (auto &R : Plan.getScalarPreheader()->phis()) {
1927 auto *ResumeR = cast<VPPhi>(Val: &R);
1928 VPValue *VecV = ResumeR->getOperand(N: 0);
1929 if (RdxResults.contains(Ptr: VecV))
1930 continue;
1931 if (auto *DerivedIV = dyn_cast<VPDerivedIVRecipe>(Val: VecV)) {
1932 VPValue *DIVTC = DerivedIV->getOperand(N: 1);
1933 if (DerivedIV->hasOneUse() && IsTC(DIVTC)) {
1934 auto *NewSel = MiddleBuilder.createSelect(
1935 Cond: AnyNaNLane, TrueVal: LoopRegion->getCanonicalIV(), FalseVal: DIVTC);
1936 DerivedIV->moveAfter(MovePos: MiddleBuilder.getRecipeAtInsertPoint());
1937 DerivedIV->setOperand(I: 1, New: NewSel);
1938 continue;
1939 }
1940 }
1941 // Bail out and abandon the current, partially modified, VPlan if we
1942 // encounter resume phi that cannot be updated yet.
1943 if (!IsTC(VecV)) {
1944 LLVM_DEBUG(dbgs() << "Found resume phi we cannot update for VPlan with "
1945 "FMaxNum/FMinNum reduction.\n");
1946 return false;
1947 }
1948 auto *NewSel = MiddleBuilder.createSelect(
1949 Cond: AnyNaNLane, TrueVal: LoopRegion->getCanonicalIV(), FalseVal: VecV);
1950 ResumeR->setOperand(I: 0, New: NewSel);
1951 }
1952
1953 auto *MiddleTerm = MiddleVPBB->getTerminator();
1954 MiddleBuilder.setInsertPoint(MiddleTerm);
1955 VPValue *MiddleCond = MiddleTerm->getOperand(N: 0);
1956 VPValue *NewCond =
1957 MiddleBuilder.createAnd(LHS: MiddleCond, RHS: MiddleBuilder.createNot(Operand: AnyNaNLane));
1958 MiddleTerm->setOperand(I: 0, New: NewCond);
1959 return true;
1960}
1961
1962bool VPlanTransforms::handleFindLastReductions(VPlan &Plan) {
1963 if (Plan.hasScalarVFOnly())
1964 return false;
1965
1966 // We want to create the following nodes:
1967 // vector.body:
1968 // ...new WidenPHI recipe introduced to keep the mask value for the latest
1969 // iteration where any lane was active.
1970 // mask.phi = phi [ ir<false>, vector.ph ], [ vp<new.mask>, vector.body ]
1971 // ...data.phi (a VPReductionPHIRecipe for a FindLast reduction) already
1972 // exists, but needs updating to use 'new.data' for the backedge value.
1973 // data.phi = phi ir<default.val>, vp<new.data>
1974 //
1975 // ...'data' and 'compare' created by existing nodes...
1976 //
1977 // ...new recipes introduced to determine whether to update the reduction
1978 // values or keep the current one.
1979 // any.active = i1 any-of ir<compare>
1980 // new.mask = select vp<any.active>, ir<compare>, vp<mask.phi>
1981 // new.data = select vp<any.active>, ir<data>, ir<data.phi>
1982 //
1983 // middle.block:
1984 // ...extract-last-active replaces compute-reduction-result.
1985 // result = extract-last-active vp<new.data>, vp<new.mask>, ir<default.val>
1986
1987 SmallVector<VPReductionPHIRecipe *, 4> Phis;
1988 for (VPReductionPHIRecipe &PhiR : make_isa_range<VPReductionPHIRecipe>(
1989 Range: Plan.getVectorLoopRegion()->getEntryBasicBlock()->phis())) {
1990 if (RecurrenceDescriptor::isFindLastRecurrenceKind(
1991 Kind: PhiR.getRecurrenceKind()))
1992 Phis.push_back(Elt: &PhiR);
1993 }
1994
1995 if (Phis.empty())
1996 return true;
1997
1998 VPValue *HeaderMask = Plan.getVectorLoopRegion()->getHeaderMask();
1999 for (VPReductionPHIRecipe *PhiR : Phis) {
2000 // Find the condition for the select/blend.
2001 VPValue *BackedgeSelect = PhiR->getBackedgeValue();
2002 VPValue *CondSelect = BackedgeSelect;
2003
2004 // If there's a header mask, the backedge select will not be the find-last
2005 // select.
2006 if (HeaderMask &&
2007 !match(V: BackedgeSelect,
2008 P: m_SelectLike(Op0: m_Specific(VPV: HeaderMask), Op1: m_VPValue(V&: CondSelect),
2009 Op2: m_Specific(VPV: PhiR))))
2010 return false;
2011
2012 VPValue *Cond = nullptr, *Op1 = nullptr, *Op2 = nullptr;
2013
2014 // If we're matching a blend rather than a select, there should be one
2015 // incoming value which is the data, then all other incoming values should
2016 // be the phi.
2017 auto MatchBlend = [&](VPRecipeBase *R) {
2018 auto *Blend = dyn_cast<VPBlendRecipe>(Val: R);
2019 if (!Blend)
2020 return false;
2021 assert(!Blend->isNormalized() && "must run before blend normalizaion");
2022 unsigned NumIncomingDataValues = 0;
2023 for (unsigned I = 0; I < Blend->getNumIncomingValues(); ++I) {
2024 VPValue *Incoming = Blend->getIncomingValue(Idx: I);
2025 if (Incoming != PhiR) {
2026 ++NumIncomingDataValues;
2027 Cond = Blend->getMask(Idx: I);
2028 Op1 = Incoming;
2029 Op2 = PhiR;
2030 }
2031 }
2032 return NumIncomingDataValues == 1;
2033 };
2034
2035 VPSingleDefRecipe *SelectR =
2036 cast<VPSingleDefRecipe>(Val: CondSelect->getDefiningRecipe());
2037 if (!match(R: SelectR,
2038 P: m_Select(Op0: m_VPValue(V&: Cond), Op1: m_VPValue(V&: Op1), Op2: m_VPValue(V&: Op2))) &&
2039 !MatchBlend(SelectR))
2040 return false;
2041
2042 // Bail out if PhiR has users other than the find-last select/blend and the
2043 // header mask select, e.g. nested blends. Then the data operand may be PhiR
2044 // on some paths and Cond does not determine the lanes to update.
2045 if (any_of(Range: PhiR->users(), P: [&](VPUser *U) {
2046 return U != SelectR && U != BackedgeSelect->getDefiningRecipe();
2047 }))
2048 return false;
2049
2050 assert(Cond != HeaderMask && "Cond must not be HeaderMask");
2051
2052 // Find final reduction computation and replace it with an
2053 // extract.last.active intrinsic.
2054 auto *RdxResult =
2055 findUserOf<VPInstruction::ComputeReductionResult>(V: BackedgeSelect);
2056 assert(RdxResult && "Could not find reduction result");
2057
2058 // Add mask phi.
2059 VPBuilder Builder = VPBuilder::getToInsertAfter(R: PhiR);
2060 auto *MaskPHI = Builder.createWidenPhi(IncomingValues: Plan.getFalse());
2061
2062 // Add select for mask.
2063 Builder.setInsertPoint(SelectR);
2064
2065 if (Op1 == PhiR) {
2066 // Normalize to selecting the data operand when the condition is true by
2067 // swapping operands and negating the condition.
2068 std::swap(a&: Op1, b&: Op2);
2069 Cond = Builder.createNot(Operand: Cond);
2070 }
2071 assert(Op2 == PhiR && "data value must be selected if Cond is true");
2072
2073 if (HeaderMask)
2074 Cond = Builder.createLogicalAnd(LHS: HeaderMask, RHS: Cond);
2075
2076 Cond = Builder.createFreeze(Op: Cond);
2077 VPValue *AnyOf = Builder.createNaryOp(Opcode: VPInstruction::AnyOf, Operands: Cond);
2078 VPValue *MaskSelect = Builder.createSelect(Cond: AnyOf, TrueVal: Cond, FalseVal: MaskPHI);
2079 MaskPHI->addIncoming(IncomingV: MaskSelect);
2080
2081 // Replace select for data.
2082 VPValue *DataSelect =
2083 Builder.createSelect(Cond: AnyOf, TrueVal: Op1, FalseVal: Op2, DL: SelectR->getDebugLoc());
2084 SelectR->replaceAllUsesWith(New: DataSelect);
2085 PhiR->setBackedgeValue(DataSelect);
2086 SelectR->eraseFromParent();
2087
2088 Builder.setInsertPoint(RdxResult);
2089 auto *ExtractLastActive =
2090 Builder.createNaryOp(Opcode: VPInstruction::ExtractLastActive,
2091 Operands: {PhiR->getStartValue(), DataSelect, MaskSelect},
2092 DL: RdxResult->getDebugLoc());
2093 RdxResult->replaceAllUsesWith(New: ExtractLastActive);
2094 RdxResult->eraseFromParent();
2095 }
2096
2097 return true;
2098}
2099
2100/// Given a first argmin/argmax pattern with strict predicate consisting of
2101/// 1) a MinOrMax reduction \p MinOrMaxPhiR producing \p MinOrMaxResult,
2102/// 2) a wide induction \p WideIV,
2103/// 3) a FindLastIV reduction \p FindLastIVPhiR using \p WideIV,
2104/// return the smallest index of the FindLastIV reduction result using UMin,
2105/// unless \p MinOrMaxResult equals the start value of its MinOrMax reduction.
2106/// In that case, return the start value of the FindLastIV reduction instead.
2107/// If \p WideIV is not canonical, a new canonical wide IV is added, and the
2108/// final result is scaled back to the non-canonical \p WideIV.
2109/// The final value of the FindLastIV reduction is originally computed using
2110/// \p FindIVSelect, \p FindIVCmp, and \p FindIVRdxResult, which are replaced
2111/// and removed.
2112/// Returns true if the pattern was handled successfully, false otherwise.
2113static bool handleFirstArgMinOrMax(
2114 VPlan &Plan, VPReductionPHIRecipe *MinOrMaxPhiR,
2115 VPReductionPHIRecipe *FindLastIVPhiR, VPWidenIntOrFpInductionRecipe *WideIV,
2116 VPInstruction *MinOrMaxResult, VPInstruction *FindIVSelect,
2117 VPRecipeBase *FindIVCmp, VPInstruction *FindIVRdxResult) {
2118 assert(!FindLastIVPhiR->isInLoop() && !FindLastIVPhiR->isOrdered() &&
2119 "inloop and ordered reductions not supported");
2120 assert(FindLastIVPhiR->getVFScaleFactor() == 1 &&
2121 "FindIV reduction must not be scaled");
2122
2123 // TODO: support for FP in handleFirstArgMinOrMax
2124 if (RecurrenceDescriptor::isFloatingPointRecurrenceKind(
2125 Kind: MinOrMaxPhiR->getRecurrenceKind()))
2126 return false;
2127
2128 Type *Ty = Plan.getVectorLoopRegion()->getCanonicalIVType();
2129 // TODO: Support non (i.e., narrower than) canonical IV types.
2130 // TODO: Emit remarks for failed transformations.
2131 if (Ty != WideIV->getScalarType())
2132 return false;
2133
2134 VPValue *HeaderMask = Plan.getVectorLoopRegion()->getHeaderMask();
2135 auto *BackedgeVal = FindLastIVPhiR->getBackedgeValue();
2136 auto *FindIVSelectVal = BackedgeVal;
2137 if (HeaderMask && !match(V: BackedgeVal, P: m_Select(Op0: m_Specific(VPV: HeaderMask),
2138 Op1: m_VPValue(V&: FindIVSelectVal),
2139 Op2: m_Specific(VPV: FindLastIVPhiR))))
2140 return false;
2141 auto *FindIVSelectR =
2142 cast<VPSingleDefRecipe>(Val: FindIVSelectVal->getDefiningRecipe());
2143
2144 assert(
2145 match(FindIVSelectR, m_Select(m_VPValue(), m_VPValue(), m_VPValue())) &&
2146 "backedge value must be a select");
2147 if (FindIVSelectR->getOperand(N: 1) != WideIV &&
2148 FindIVSelectR->getOperand(N: 2) != WideIV)
2149 return false;
2150
2151 // If the original wide IV is not canonical, create a new one. The canonical
2152 // wide IV is guaranteed to not wrap for all lanes that are active in the
2153 // vector loop.
2154 if (!WideIV->isCanonical()) {
2155 VPIRValue *Zero = Plan.getConstantInt(Ty, Val: 0);
2156 VPIRValue *One = Plan.getConstantInt(Ty, Val: 1);
2157 auto *WidenCanIV = new VPWidenIntOrFpInductionRecipe(
2158 nullptr, Zero, One, WideIV->getVFValue(),
2159 WideIV->getInductionDescriptor(),
2160 VPIRFlags::WrapFlagsTy(/*HasNUW=*/true, /*HasNSW=*/false),
2161 WideIV->getDebugLoc());
2162 WidenCanIV->insertBefore(InsertPos: WideIV);
2163
2164 // Update the select to use the wide canonical IV.
2165 FindIVSelectR->setOperand(I: FindIVSelectR->getOperand(N: 1) == WideIV ? 1 : 2,
2166 New: WidenCanIV);
2167 }
2168 FindLastIVPhiR->setOperand(I: 0, New: Plan.getPoison(Ty));
2169
2170 // The reduction using MinOrMaxPhiR needs adjusting to compute the correct
2171 // result:
2172 // 1. Find the first canonical indices corresponding to partial min/max
2173 // values, using loop reductions.
2174 // 2. Find which of the partial min/max values are equal to the overall
2175 // min/max value.
2176 // 3. Select among the canonical indices those corresponding to the overall
2177 // min/max value.
2178 // 4. Find the first canonical index of overall min/max and scale it back to
2179 // the original IV using VPDerivedIVRecipe.
2180 // 5. If the overall min/max equals the starting min/max, the condition in
2181 // the loop was always false, due to being strict; return the start value
2182 // of FindLastIVPhiR in that case.
2183 //
2184 // For example, we transforms two independent reduction result computations
2185 // for
2186 //
2187 // <x1> vector loop: {
2188 // vector.body:
2189 // ...
2190 // ir<%iv> = WIDEN-INDUCTION nuw nsw ir<10>, ir<1>, vp<%0>
2191 // WIDEN-REDUCTION-PHI ir<%min.idx> = phi ir<sentinel.min.start>,
2192 // ir<%min.idx.next>
2193 // WIDEN-REDUCTION-PHI ir<%min.val> = phi ir<100>, ir<%min.val.next>
2194 // ....
2195 // WIDEN-INTRINSIC ir<%min.val.next> = call llvm.umin(ir<%min.val>, ir<%l>)
2196 // WIDEN ir<%min.idx.next> = select ir<%cmp>, ir<%iv>, ir<%min.idx>
2197 // ...
2198 // }
2199 // Successor(s): middle.block
2200 //
2201 // middle.block:
2202 // vp<%iv.rdx> = compute-reduction-result (smax) vp<%min.idx.next>
2203 // vp<%min.result> = compute-reduction-result (umin) ir<%min.val.next>
2204 // vp<%cmp> = icmp ne vp<%iv.rdx>, ir<sentinel.min.start>
2205 // vp<%find.iv.result> = select vp<%cmp>, vp<%iv.rdx>, ir<10>
2206 //
2207 //
2208 // Into:
2209 //
2210 // vp<%reduced.min> = compute-reduction-result (umin) ir<%min.val.next>
2211 // vp<%reduced.mins.mask> = icmp eq ir<%min.val.next>, vp<%reduced.min>
2212 // vp<%idxs2reduce> = select vp<%reduced.mins.mask>, ir<%min.idx.next>,
2213 // ir<MaxUInt>
2214 // vp<%reduced.idx> = compute-reduction-result (umin) vp<%idxs2reduce>
2215 // vp<%scaled.idx> = DERIVED-IV ir<20> + vp<%reduced.idx> * ir<1>
2216 // vp<%always.false> = icmp eq vp<%reduced.min>, ir<100>
2217 // vp<%final.idx> = select vp<%always.false>, ir<10>,
2218 // vp<%scaled.idx>
2219
2220 VPBuilder Builder(FindIVRdxResult);
2221 VPValue *MinOrMaxExiting = MinOrMaxResult->getOperand(N: 0);
2222 auto *FinalMinOrMaxCmp =
2223 Builder.createICmp(Pred: CmpInst::ICMP_EQ, A: MinOrMaxExiting, B: MinOrMaxResult);
2224 VPValue *LastIVExiting = FindIVRdxResult->getOperand(N: 0);
2225 VPValue *MaxIV =
2226 Plan.getConstantInt(Val: APInt::getMaxValue(numBits: Ty->getIntegerBitWidth()));
2227 auto *FinalIVSelect =
2228 Builder.createSelect(Cond: FinalMinOrMaxCmp, TrueVal: LastIVExiting, FalseVal: MaxIV);
2229 VPIRFlags RdxFlags(RecurKind::UMin, false, false, FastMathFlags());
2230 VPSingleDefRecipe *FinalCanIV = Builder.createNaryOp(
2231 Opcode: VPInstruction::ComputeReductionResult, Operands: {FinalIVSelect}, Flags: RdxFlags,
2232 DL: FindIVRdxResult->getDebugLoc());
2233
2234 // If we used a new wide canonical IV convert the reduction result back to the
2235 // original IV scale before the final select.
2236 if (!WideIV->isCanonical()) {
2237 auto *DerivedIVRecipe = new VPDerivedIVRecipe(
2238 InductionDescriptor::IK_IntInduction,
2239 nullptr, // No FPBinOp for integer induction
2240 WideIV->getStartValue(), FinalCanIV, WideIV->getStepValue());
2241 DerivedIVRecipe->insertBefore(InsertPos: Builder.getRecipeAtInsertPoint());
2242 FinalCanIV = DerivedIVRecipe;
2243 }
2244
2245 // If the final min/max value matches its start value, the condition in the
2246 // loop was always false, i.e. no induction value has been selected. If that's
2247 // the case, set the result of the IV reduction to its start value.
2248 VPValue *AlwaysFalse = Builder.createICmp(Pred: CmpInst::ICMP_EQ, A: MinOrMaxResult,
2249 B: MinOrMaxPhiR->getStartValue());
2250 VPValue *FinalIV = Builder.createSelect(
2251 Cond: AlwaysFalse, TrueVal: FindIVSelect->getOperand(N: 2), FalseVal: FinalCanIV);
2252 FindIVSelect->replaceAllUsesWith(New: FinalIV);
2253
2254 // Erase the old FindIV result pattern which is now dead.
2255 FindIVSelect->eraseFromParent();
2256 FindIVCmp->eraseFromParent();
2257 FindIVRdxResult->eraseFromParent();
2258 return true;
2259}
2260
2261bool VPlanTransforms::handleMultiUseReductions(VPlan &Plan,
2262 OptimizationRemarkEmitter *ORE,
2263 Loop *TheLoop) {
2264 for (auto &PhiR : make_early_inc_range(
2265 Range: Plan.getVectorLoopRegion()->getEntryBasicBlock()->phis())) {
2266 auto *MinOrMaxPhiR = dyn_cast<VPReductionPHIRecipe>(Val: &PhiR);
2267 // TODO: check for multi-uses in VPlan directly.
2268 if (!MinOrMaxPhiR || !MinOrMaxPhiR->hasUsesOutsideReductionChain())
2269 continue;
2270
2271 // MinOrMaxPhiR has users outside the reduction cycle in the loop. Check if
2272 // the only other user is a FindLastIV reduction. MinOrMaxPhiR must have
2273 // exactly 2 users if not tailfolded:
2274 // 1) the min/max operation of the reduction cycle, and
2275 // 2) the compare of a FindLastIV reduction cycle. This compare must match
2276 // the min/max operation - comparing MinOrMaxPhiR with the operand of the
2277 // min/max operation, and be used only by the select of the FindLastIV
2278 // reduction cycle.
2279 // There is an additional user if the tail was folded:
2280 // 3) the select operation of the vector.latch block. This select uses the
2281 // original MinOrMaxPhiR if the mask is zero.
2282 RecurKind RdxKind = MinOrMaxPhiR->getRecurrenceKind();
2283 assert(
2284 RecurrenceDescriptor::isMinMaxRecurrenceKind(RdxKind) &&
2285 "only min/max recurrences support users outside the reduction chain");
2286
2287 auto *MinOrMaxBackedgeR =
2288 dyn_cast<VPRecipeWithIRFlags>(Val: MinOrMaxPhiR->getBackedgeValue());
2289 if (!MinOrMaxBackedgeR)
2290 return false;
2291
2292 // If the tail was folded then the backedge won't be the
2293 // reduction-intrinsic but the select in the vector.latch block that wraps
2294 // the reduction-intrinsic.
2295 auto *MinOrMaxOp = MinOrMaxBackedgeR;
2296 VPValue *HeaderMask = Plan.getVectorLoopRegion()->getHeaderMask();
2297 VPValue *MinOrMaxTailfold;
2298 if (HeaderMask) {
2299 if (!match(V: MinOrMaxBackedgeR, P: m_SelectLike(Op0: m_Specific(VPV: HeaderMask),
2300 Op1: m_VPValue(V&: MinOrMaxTailfold),
2301 Op2: m_Specific(VPV: MinOrMaxPhiR))))
2302 return false;
2303
2304 MinOrMaxOp = dyn_cast<VPRecipeWithIRFlags>(Val: MinOrMaxTailfold);
2305 if (!MinOrMaxOp)
2306 return false;
2307 }
2308
2309 // Check that MinOrMaxOp is a VPWidenIntrinsicRecipe or
2310 // VPReplicateRecipe with an intrinsic that matches the reduction kind.
2311 Intrinsic::ID ExpectedIntrinsicID = getMinMaxReductionIntrinsicOp(RK: RdxKind);
2312 if (!match(V: MinOrMaxOp, P: m_Intrinsic(IntrID: ExpectedIntrinsicID)))
2313 return false;
2314
2315 // Tailfolded MinOrMaxOp should only feed into the predicated
2316 // select MinOrMaxBackedgeR.
2317 assert((!HeaderMask || MinOrMaxOp->getNumUsers() == 1) &&
2318 "Tailfolded MinOrMaxOp must have exactly 1 user");
2319 // MinOrMaxBackedgeR must have 2 users: 1) MinOrMaxPhiR and 2)
2320 // ComputeReductionResult.
2321 assert(MinOrMaxBackedgeR->getNumUsers() == 2 &&
2322 "MinOrMaxBackedgeR must have exactly 2 users");
2323 // MinOrMaxOp must combine MinOrMaxPhiR directly with the new element;
2324 // reject multi-step min/max chains (e.g. max(l, max(k, phi))), which
2325 // this transform does not handle.
2326 VPValue *MinOrMaxOpValue;
2327 if (MinOrMaxOp->getOperand(N: 0) == MinOrMaxPhiR)
2328 MinOrMaxOpValue = MinOrMaxOp->getOperand(N: 1);
2329 else if (MinOrMaxOp->getOperand(N: 1) == MinOrMaxPhiR)
2330 MinOrMaxOpValue = MinOrMaxOp->getOperand(N: 0);
2331 else
2332 return false;
2333
2334 VPValue *CmpOpA;
2335 VPValue *CmpOpB;
2336 CmpPredicate Pred;
2337 auto *Cmp = dyn_cast_or_null<VPRecipeWithIRFlags>(Val: findUserOf(
2338 V: MinOrMaxPhiR, P: m_Cmp(Pred, Op0: m_VPValue(V&: CmpOpA), Op1: m_VPValue(V&: CmpOpB))));
2339 if (!Cmp || Cmp->getNumUsers() != 1 ||
2340 (CmpOpA != MinOrMaxOpValue && CmpOpB != MinOrMaxOpValue))
2341 return false;
2342
2343 if (MinOrMaxOpValue != CmpOpB)
2344 Pred = CmpInst::getSwappedPredicate(pred: Pred);
2345
2346 // MinOrMaxPhiR must have exactly 2 users if not tailfolded:
2347 // * MinOrMaxOp,
2348 // * Cmp (that's part of a FindLastIV chain).
2349 // Also an additional third user if it is tailfolded:
2350 // * Predicated HEADER-MASK select in the vector.latch block.
2351 if (MinOrMaxPhiR->getNumUsers() != (HeaderMask ? 3 : 2))
2352 return false;
2353
2354 VPInstruction *MinOrMaxResult =
2355 findUserOf<VPInstruction::ComputeReductionResult>(V: MinOrMaxBackedgeR);
2356 assert(MinOrMaxResult &&
2357 "MinOrMaxResult must be a user of MinOrMaxBackedgeR");
2358
2359 // Cmp must be used by the select of a FindLastIV chain.
2360 VPValue *Sel = dyn_cast<VPSingleDefRecipe>(Val: Cmp->getSingleUser());
2361 VPValue *IVOp, *FindIV;
2362 if (!Sel || (Sel->getNumUsers() != (HeaderMask ? 1 : 2)) ||
2363 !match(V: Sel,
2364 P: m_Select(Op0: m_Specific(VPV: Cmp), Op1: m_VPValue(V&: IVOp), Op2: m_VPValue(V&: FindIV))))
2365 return false;
2366
2367 if (!isa<VPReductionPHIRecipe>(Val: FindIV)) {
2368 std::swap(a&: FindIV, b&: IVOp);
2369 Pred = CmpInst::getInversePredicate(pred: Pred);
2370 }
2371
2372 auto *FindIVPhiR = dyn_cast<VPReductionPHIRecipe>(Val: FindIV);
2373 if (!FindIVPhiR || !RecurrenceDescriptor::isFindIVRecurrenceKind(
2374 Kind: FindIVPhiR->getRecurrenceKind()))
2375 return false;
2376
2377 assert(!FindIVPhiR->isInLoop() && !FindIVPhiR->isOrdered() &&
2378 "cannot handle inloop/ordered reductions yet");
2379
2380 // Check if FindIVPhiR is a FindLast pattern by checking the MinMaxKind
2381 // on its ComputeReductionResult. SMax/UMax indicates FindLast.
2382 VPInstruction *FindIVResult =
2383 findUserOf<VPInstruction::ComputeReductionResult>(
2384 V: FindIVPhiR->getBackedgeValue());
2385 assert(FindIVResult &&
2386 "must be able to retrieve the FindIVResult VPInstruction");
2387 RecurKind FindIVMinMaxKind = FindIVResult->getRecurKind();
2388 if (FindIVMinMaxKind != RecurKind::SMax &&
2389 FindIVMinMaxKind != RecurKind::UMax)
2390 return false;
2391
2392 // TODO: Support cases where IVOp is the IV increment.
2393 if (!match(V: IVOp, P: m_TruncOrSelf(Op0: m_VPValue(V&: IVOp))) ||
2394 !isa<VPWidenIntOrFpInductionRecipe>(Val: IVOp))
2395 return false;
2396
2397 // Check if the predicate is compatible with the reduction kind.
2398 bool IsValidKindPred = [RdxKind, Pred]() {
2399 switch (RdxKind) {
2400 case RecurKind::UMin:
2401 return Pred == CmpInst::ICMP_UGE || Pred == CmpInst::ICMP_UGT;
2402 case RecurKind::UMax:
2403 return Pred == CmpInst::ICMP_ULE || Pred == CmpInst::ICMP_ULT;
2404 case RecurKind::SMax:
2405 return Pred == CmpInst::ICMP_SLE || Pred == CmpInst::ICMP_SLT;
2406 case RecurKind::SMin:
2407 return Pred == CmpInst::ICMP_SGE || Pred == CmpInst::ICMP_SGT;
2408 case RecurKind::FMax:
2409 case RecurKind::FMaximumNum:
2410 return Pred == CmpInst::FCMP_OLE || Pred == CmpInst::FCMP_OLT;
2411 case RecurKind::FMin:
2412 case RecurKind::FMinimumNum:
2413 return Pred == CmpInst::FCMP_OGE || Pred == CmpInst::FCMP_OGT;
2414 // minnum and maxnum need special handling due to expected sNaN behaviour
2415 // minimum and maximum return NaN if either input is a NAN
2416 case RecurKind::FMinNum:
2417 case RecurKind::FMaxNum:
2418 case RecurKind::FMinimum:
2419 case RecurKind::FMaximum:
2420 return false;
2421 default:
2422 llvm_unreachable("unhandled recurrence kind");
2423 }
2424 }();
2425 if (!IsValidKindPred) {
2426 ORE->emit(RemarkBuilder: [&]() {
2427 return OptimizationRemarkMissed(
2428 DEBUG_TYPE, "VectorizationMultiUseReductionPredicate",
2429 TheLoop->getStartLoc(), TheLoop->getHeader())
2430 << "Multi-use reduction with predicate "
2431 << CmpInst::getPredicateName(P: Pred)
2432 << " incompatible with reduction kind";
2433 });
2434 return false;
2435 }
2436
2437 if (RdxKind == RecurKind::FMaximumNum ||
2438 RdxKind == RecurKind::FMinimumNum) {
2439 auto *StartC = dyn_cast<VPConstant>(Val: MinOrMaxPhiR->getStartValue());
2440 if (!StartC || StartC->getConstant()->isNaN())
2441 return false;
2442 }
2443
2444 auto *FindIVSelect = findFindIVSelect(BackedgeVal: FindIVPhiR->getBackedgeValue());
2445 auto *FindIVCmp = FindIVSelect->getOperand(N: 0)->getDefiningRecipe();
2446 auto *FindIVRdxResult = cast<VPInstruction>(Val: FindIVCmp->getOperand(N: 0));
2447 assert(FindIVSelect->getParent() == MinOrMaxResult->getParent() &&
2448 "both results must be computed in the same block");
2449 // Reducing to a scalar min or max value is placed right before reducing to
2450 // its scalar iteration, in order to generate instructions that use both
2451 // their operands.
2452 MinOrMaxResult->moveBefore(BB&: *FindIVRdxResult->getParent(),
2453 I: FindIVRdxResult->getIterator());
2454
2455 bool IsStrictPredicate = CmpInst::isStrictPredicate(predicate: Pred);
2456 if (IsStrictPredicate) {
2457 if (!handleFirstArgMinOrMax(Plan, MinOrMaxPhiR, FindLastIVPhiR: FindIVPhiR,
2458 WideIV: cast<VPWidenIntOrFpInductionRecipe>(Val: IVOp),
2459 MinOrMaxResult, FindIVSelect, FindIVCmp,
2460 FindIVRdxResult))
2461 return false;
2462 continue;
2463 }
2464
2465 // The reduction using MinOrMaxPhiR needs adjusting to compute the correct
2466 // result:
2467 // 1. We need to find the last IV for which the condition based on the
2468 // min/max recurrence is true,
2469 // 2. Compare the partial min/max reduction result to its final value and,
2470 // 3. Select the lanes of the partial FindLastIV reductions which
2471 // correspond to the lanes matching the min/max reduction result.
2472 //
2473 // For example, this transforms
2474 // vp<%min.result> = compute-reduction-result ir<%min.val.next>
2475 // vp<%iv.rdx> = compute-reduction-result (smax) vp<%min.idx.next>
2476 // vp<%cmp> = icmp ne vp<%iv.rdx>, SENTINEL
2477 // vp<%find.iv.result> = select vp<%cmp>, vp<%iv.rdx>, ir<0>
2478 //
2479 // into:
2480 //
2481 // vp<min.result> = compute-reduction-result ir<%min.val.next>
2482 // vp<%final.min.cmp> = icmp eq ir<%min.val.next>, vp<min.result>
2483 // vp<%final.iv> = select vp<%final.min.cmp>, vp<%min.idx.next>, SENTINEL
2484 // vp<%iv.rdx> = compute-reduction-result (smax) vp<%final.iv>
2485 // vp<%cmp> = icmp ne vp<%iv.rdx>, SENTINEL
2486 // vp<%find.iv.result> = select vp<%cmp>, vp<%iv.rdx>, ir<0>
2487 //
2488 VPBuilder B(FindIVRdxResult);
2489 VPValue *MinOrMaxExiting = MinOrMaxResult->getOperand(N: 0);
2490 auto *FinalMinOrMaxCmp =
2491 (RecurrenceDescriptor::isIntegerRecurrenceKind(Kind: RdxKind))
2492 ? B.createICmp(Pred: CmpInst::ICMP_EQ, A: MinOrMaxExiting, B: MinOrMaxResult)
2493 : B.createFCmp(Pred: CmpInst::FCMP_OEQ, A: MinOrMaxExiting, B: MinOrMaxResult);
2494 VPValue *Sentinel = FindIVCmp->getOperand(N: 1);
2495 VPValue *LastIVExiting = FindIVRdxResult->getOperand(N: 0);
2496 auto *FinalIVSelect =
2497 B.createSelect(Cond: FinalMinOrMaxCmp, TrueVal: LastIVExiting, FalseVal: Sentinel);
2498 FindIVRdxResult->setOperand(I: 0, New: FinalIVSelect);
2499 }
2500 return true;
2501}
2502
2503void VPlanTransforms::attachAliasMaskToHeaderMask(VPlan &Plan) {
2504 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
2505 VPValue *HeaderMask = LoopRegion->getHeaderMask();
2506 Type *I1Ty = IntegerType::getInt1Ty(C&: Plan.getContext());
2507
2508 VPBuilder Builder(Plan.getVectorPreheader());
2509 auto *AliasMask = Builder.createNaryOp(
2510 Opcode: VPInstruction::IncomingAliasMask, Operands: {}, Inst: nullptr, Flags: {}, MD: {},
2511 DL: DebugLoc::getUnknown(), Name: "incoming.alias.mask", ResultTy: I1Ty);
2512
2513 VPBasicBlock *Header = LoopRegion->getEntryBasicBlock();
2514 Builder = VPBuilder(Header, Header->getFirstNonPhi());
2515
2516 // Update all existing users of the header mask to "HeaderMask & AliasMask".
2517 auto *ClampedHeaderMask = Builder.createAnd(LHS: HeaderMask, RHS: AliasMask);
2518 HeaderMask->replaceUsesWithIf(New: ClampedHeaderMask,
2519 ShouldReplace: not_equal_to(Arg&: ClampedHeaderMask));
2520}
2521