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