1 //===- VPlanRecipes.cpp - Implementations for VPlan recipes ---------------===//
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 contains implementations for different VPlan recipes.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "VPlan.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/Analysis/IVDescriptors.h"
19 #include "llvm/IR/BasicBlock.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/Instruction.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/Type.h"
24 #include "llvm/IR/Value.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
30 #include <cassert>
31 
32 using namespace llvm;
33 
34 extern cl::opt<bool> EnableVPlanNativePath;
35 
36 #define LV_NAME "loop-vectorize"
37 #define DEBUG_TYPE LV_NAME
38 
39 bool VPRecipeBase::mayWriteToMemory() const {
40   switch (getVPDefID()) {
41   case VPWidenMemoryInstructionSC: {
42     return cast<VPWidenMemoryInstructionRecipe>(this)->isStore();
43   }
44   case VPReplicateSC:
45   case VPWidenCallSC:
46     return cast<Instruction>(getVPSingleValue()->getUnderlyingValue())
47         ->mayWriteToMemory();
48   case VPBranchOnMaskSC:
49     return false;
50   case VPWidenIntOrFpInductionSC:
51   case VPWidenCanonicalIVSC:
52   case VPWidenPHISC:
53   case VPBlendSC:
54   case VPWidenSC:
55   case VPWidenGEPSC:
56   case VPReductionSC:
57   case VPWidenSelectSC: {
58     const Instruction *I =
59         dyn_cast_or_null<Instruction>(getVPSingleValue()->getUnderlyingValue());
60     (void)I;
61     assert((!I || !I->mayWriteToMemory()) &&
62            "underlying instruction may write to memory");
63     return false;
64   }
65   default:
66     return true;
67   }
68 }
69 
70 bool VPRecipeBase::mayReadFromMemory() const {
71   switch (getVPDefID()) {
72   case VPWidenMemoryInstructionSC: {
73     return !cast<VPWidenMemoryInstructionRecipe>(this)->isStore();
74   }
75   case VPReplicateSC:
76   case VPWidenCallSC:
77     return cast<Instruction>(getVPSingleValue()->getUnderlyingValue())
78         ->mayReadFromMemory();
79   case VPBranchOnMaskSC:
80     return false;
81   case VPWidenIntOrFpInductionSC:
82   case VPWidenCanonicalIVSC:
83   case VPWidenPHISC:
84   case VPBlendSC:
85   case VPWidenSC:
86   case VPWidenGEPSC:
87   case VPReductionSC:
88   case VPWidenSelectSC: {
89     const Instruction *I =
90         dyn_cast_or_null<Instruction>(getVPSingleValue()->getUnderlyingValue());
91     (void)I;
92     assert((!I || !I->mayReadFromMemory()) &&
93            "underlying instruction may read from memory");
94     return false;
95   }
96   default:
97     return true;
98   }
99 }
100 
101 bool VPRecipeBase::mayHaveSideEffects() const {
102   switch (getVPDefID()) {
103   case VPWidenIntOrFpInductionSC:
104   case VPWidenPointerInductionSC:
105   case VPWidenCanonicalIVSC:
106   case VPWidenPHISC:
107   case VPBlendSC:
108   case VPWidenSC:
109   case VPWidenGEPSC:
110   case VPReductionSC:
111   case VPWidenSelectSC:
112   case VPScalarIVStepsSC: {
113     const Instruction *I =
114         dyn_cast_or_null<Instruction>(getVPSingleValue()->getUnderlyingValue());
115     (void)I;
116     assert((!I || !I->mayHaveSideEffects()) &&
117            "underlying instruction has side-effects");
118     return false;
119   }
120   case VPReplicateSC: {
121     auto *R = cast<VPReplicateRecipe>(this);
122     return R->getUnderlyingInstr()->mayHaveSideEffects();
123   }
124   default:
125     return true;
126   }
127 }
128 
129 void VPLiveOut::fixPhi(VPlan &Plan, VPTransformState &State) {
130   auto Lane = VPLane::getLastLaneForVF(State.VF);
131   VPValue *ExitValue = getOperand(0);
132   if (Plan.isUniformAfterVectorization(ExitValue))
133     Lane = VPLane::getFirstLane();
134   Phi->addIncoming(State.get(ExitValue, VPIteration(State.UF - 1, Lane)),
135                    State.Builder.GetInsertBlock());
136 }
137 
138 void VPRecipeBase::insertBefore(VPRecipeBase *InsertPos) {
139   assert(!Parent && "Recipe already in some VPBasicBlock");
140   assert(InsertPos->getParent() &&
141          "Insertion position not in any VPBasicBlock");
142   Parent = InsertPos->getParent();
143   Parent->getRecipeList().insert(InsertPos->getIterator(), this);
144 }
145 
146 void VPRecipeBase::insertBefore(VPBasicBlock &BB,
147                                 iplist<VPRecipeBase>::iterator I) {
148   assert(!Parent && "Recipe already in some VPBasicBlock");
149   assert(I == BB.end() || I->getParent() == &BB);
150   Parent = &BB;
151   BB.getRecipeList().insert(I, this);
152 }
153 
154 void VPRecipeBase::insertAfter(VPRecipeBase *InsertPos) {
155   assert(!Parent && "Recipe already in some VPBasicBlock");
156   assert(InsertPos->getParent() &&
157          "Insertion position not in any VPBasicBlock");
158   Parent = InsertPos->getParent();
159   Parent->getRecipeList().insertAfter(InsertPos->getIterator(), this);
160 }
161 
162 void VPRecipeBase::removeFromParent() {
163   assert(getParent() && "Recipe not in any VPBasicBlock");
164   getParent()->getRecipeList().remove(getIterator());
165   Parent = nullptr;
166 }
167 
168 iplist<VPRecipeBase>::iterator VPRecipeBase::eraseFromParent() {
169   assert(getParent() && "Recipe not in any VPBasicBlock");
170   return getParent()->getRecipeList().erase(getIterator());
171 }
172 
173 void VPRecipeBase::moveAfter(VPRecipeBase *InsertPos) {
174   removeFromParent();
175   insertAfter(InsertPos);
176 }
177 
178 void VPRecipeBase::moveBefore(VPBasicBlock &BB,
179                               iplist<VPRecipeBase>::iterator I) {
180   removeFromParent();
181   insertBefore(BB, I);
182 }
183 
184 void VPInstruction::generateInstruction(VPTransformState &State,
185                                         unsigned Part) {
186   IRBuilderBase &Builder = State.Builder;
187   Builder.SetCurrentDebugLocation(DL);
188 
189   if (Instruction::isBinaryOp(getOpcode())) {
190     Value *A = State.get(getOperand(0), Part);
191     Value *B = State.get(getOperand(1), Part);
192     Value *V =
193         Builder.CreateBinOp((Instruction::BinaryOps)getOpcode(), A, B, Name);
194     State.set(this, V, Part);
195     return;
196   }
197 
198   switch (getOpcode()) {
199   case VPInstruction::Not: {
200     Value *A = State.get(getOperand(0), Part);
201     Value *V = Builder.CreateNot(A, Name);
202     State.set(this, V, Part);
203     break;
204   }
205   case VPInstruction::ICmpULE: {
206     Value *IV = State.get(getOperand(0), Part);
207     Value *TC = State.get(getOperand(1), Part);
208     Value *V = Builder.CreateICmpULE(IV, TC, Name);
209     State.set(this, V, Part);
210     break;
211   }
212   case Instruction::Select: {
213     Value *Cond = State.get(getOperand(0), Part);
214     Value *Op1 = State.get(getOperand(1), Part);
215     Value *Op2 = State.get(getOperand(2), Part);
216     Value *V = Builder.CreateSelect(Cond, Op1, Op2, Name);
217     State.set(this, V, Part);
218     break;
219   }
220   case VPInstruction::ActiveLaneMask: {
221     // Get first lane of vector induction variable.
222     Value *VIVElem0 = State.get(getOperand(0), VPIteration(Part, 0));
223     // Get the original loop tripcount.
224     Value *ScalarTC = State.get(getOperand(1), Part);
225 
226     auto *Int1Ty = Type::getInt1Ty(Builder.getContext());
227     auto *PredTy = VectorType::get(Int1Ty, State.VF);
228     Instruction *Call = Builder.CreateIntrinsic(
229         Intrinsic::get_active_lane_mask, {PredTy, ScalarTC->getType()},
230         {VIVElem0, ScalarTC}, nullptr, Name);
231     State.set(this, Call, Part);
232     break;
233   }
234   case VPInstruction::FirstOrderRecurrenceSplice: {
235     // Generate code to combine the previous and current values in vector v3.
236     //
237     //   vector.ph:
238     //     v_init = vector(..., ..., ..., a[-1])
239     //     br vector.body
240     //
241     //   vector.body
242     //     i = phi [0, vector.ph], [i+4, vector.body]
243     //     v1 = phi [v_init, vector.ph], [v2, vector.body]
244     //     v2 = a[i, i+1, i+2, i+3];
245     //     v3 = vector(v1(3), v2(0, 1, 2))
246 
247     // For the first part, use the recurrence phi (v1), otherwise v2.
248     auto *V1 = State.get(getOperand(0), 0);
249     Value *PartMinus1 = Part == 0 ? V1 : State.get(getOperand(1), Part - 1);
250     if (!PartMinus1->getType()->isVectorTy()) {
251       State.set(this, PartMinus1, Part);
252     } else {
253       Value *V2 = State.get(getOperand(1), Part);
254       State.set(this, Builder.CreateVectorSplice(PartMinus1, V2, -1, Name),
255                 Part);
256     }
257     break;
258   }
259   case VPInstruction::CanonicalIVIncrement:
260   case VPInstruction::CanonicalIVIncrementNUW: {
261     Value *Next = nullptr;
262     if (Part == 0) {
263       bool IsNUW = getOpcode() == VPInstruction::CanonicalIVIncrementNUW;
264       auto *Phi = State.get(getOperand(0), 0);
265       // The loop step is equal to the vectorization factor (num of SIMD
266       // elements) times the unroll factor (num of SIMD instructions).
267       Value *Step =
268           createStepForVF(Builder, Phi->getType(), State.VF, State.UF);
269       Next = Builder.CreateAdd(Phi, Step, Name, IsNUW, false);
270     } else {
271       Next = State.get(this, 0);
272     }
273 
274     State.set(this, Next, Part);
275     break;
276   }
277   case VPInstruction::BranchOnCond: {
278     if (Part != 0)
279       break;
280 
281     Value *Cond = State.get(getOperand(0), VPIteration(Part, 0));
282     VPRegionBlock *ParentRegion = getParent()->getParent();
283     VPBasicBlock *Header = ParentRegion->getEntryBasicBlock();
284 
285     // Replace the temporary unreachable terminator with a new conditional
286     // branch, hooking it up to backward destination for exiting blocks now and
287     // to forward destination(s) later when they are created.
288     BranchInst *CondBr =
289         Builder.CreateCondBr(Cond, Builder.GetInsertBlock(), nullptr);
290 
291     if (getParent()->isExiting())
292       CondBr->setSuccessor(1, State.CFG.VPBB2IRBB[Header]);
293 
294     CondBr->setSuccessor(0, nullptr);
295     Builder.GetInsertBlock()->getTerminator()->eraseFromParent();
296     break;
297   }
298   case VPInstruction::BranchOnCount: {
299     if (Part != 0)
300       break;
301     // First create the compare.
302     Value *IV = State.get(getOperand(0), Part);
303     Value *TC = State.get(getOperand(1), Part);
304     Value *Cond = Builder.CreateICmpEQ(IV, TC);
305 
306     // Now create the branch.
307     auto *Plan = getParent()->getPlan();
308     VPRegionBlock *TopRegion = Plan->getVectorLoopRegion();
309     VPBasicBlock *Header = TopRegion->getEntry()->getEntryBasicBlock();
310 
311     // Replace the temporary unreachable terminator with a new conditional
312     // branch, hooking it up to backward destination (the header) now and to the
313     // forward destination (the exit/middle block) later when it is created.
314     // Note that CreateCondBr expects a valid BB as first argument, so we need
315     // to set it to nullptr later.
316     BranchInst *CondBr = Builder.CreateCondBr(Cond, Builder.GetInsertBlock(),
317                                               State.CFG.VPBB2IRBB[Header]);
318     CondBr->setSuccessor(0, nullptr);
319     Builder.GetInsertBlock()->getTerminator()->eraseFromParent();
320     break;
321   }
322   default:
323     llvm_unreachable("Unsupported opcode for instruction");
324   }
325 }
326 
327 void VPInstruction::execute(VPTransformState &State) {
328   assert(!State.Instance && "VPInstruction executing an Instance");
329   IRBuilderBase::FastMathFlagGuard FMFGuard(State.Builder);
330   State.Builder.setFastMathFlags(FMF);
331   for (unsigned Part = 0; Part < State.UF; ++Part)
332     generateInstruction(State, Part);
333 }
334 
335 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
336 void VPInstruction::dump() const {
337   VPSlotTracker SlotTracker(getParent()->getPlan());
338   print(dbgs(), "", SlotTracker);
339 }
340 
341 void VPInstruction::print(raw_ostream &O, const Twine &Indent,
342                           VPSlotTracker &SlotTracker) const {
343   O << Indent << "EMIT ";
344 
345   if (hasResult()) {
346     printAsOperand(O, SlotTracker);
347     O << " = ";
348   }
349 
350   switch (getOpcode()) {
351   case VPInstruction::Not:
352     O << "not";
353     break;
354   case VPInstruction::ICmpULE:
355     O << "icmp ule";
356     break;
357   case VPInstruction::SLPLoad:
358     O << "combined load";
359     break;
360   case VPInstruction::SLPStore:
361     O << "combined store";
362     break;
363   case VPInstruction::ActiveLaneMask:
364     O << "active lane mask";
365     break;
366   case VPInstruction::FirstOrderRecurrenceSplice:
367     O << "first-order splice";
368     break;
369   case VPInstruction::CanonicalIVIncrement:
370     O << "VF * UF + ";
371     break;
372   case VPInstruction::CanonicalIVIncrementNUW:
373     O << "VF * UF +(nuw) ";
374     break;
375   case VPInstruction::BranchOnCond:
376     O << "branch-on-cond";
377     break;
378   case VPInstruction::BranchOnCount:
379     O << "branch-on-count ";
380     break;
381   default:
382     O << Instruction::getOpcodeName(getOpcode());
383   }
384 
385   O << FMF;
386 
387   for (const VPValue *Operand : operands()) {
388     O << " ";
389     Operand->printAsOperand(O, SlotTracker);
390   }
391 
392   if (DL) {
393     O << ", !dbg ";
394     DL.print(O);
395   }
396 }
397 #endif
398 
399 void VPInstruction::setFastMathFlags(FastMathFlags FMFNew) {
400   // Make sure the VPInstruction is a floating-point operation.
401   assert((Opcode == Instruction::FAdd || Opcode == Instruction::FMul ||
402           Opcode == Instruction::FNeg || Opcode == Instruction::FSub ||
403           Opcode == Instruction::FDiv || Opcode == Instruction::FRem ||
404           Opcode == Instruction::FCmp) &&
405          "this op can't take fast-math flags");
406   FMF = FMFNew;
407 }
408 
409 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
410 void VPWidenCallRecipe::print(raw_ostream &O, const Twine &Indent,
411                               VPSlotTracker &SlotTracker) const {
412   O << Indent << "WIDEN-CALL ";
413 
414   auto *CI = cast<CallInst>(getUnderlyingInstr());
415   if (CI->getType()->isVoidTy())
416     O << "void ";
417   else {
418     printAsOperand(O, SlotTracker);
419     O << " = ";
420   }
421 
422   O << "call @" << CI->getCalledFunction()->getName() << "(";
423   printOperands(O, SlotTracker);
424   O << ")";
425 }
426 
427 void VPWidenSelectRecipe::print(raw_ostream &O, const Twine &Indent,
428                                 VPSlotTracker &SlotTracker) const {
429   O << Indent << "WIDEN-SELECT ";
430   printAsOperand(O, SlotTracker);
431   O << " = select ";
432   getOperand(0)->printAsOperand(O, SlotTracker);
433   O << ", ";
434   getOperand(1)->printAsOperand(O, SlotTracker);
435   O << ", ";
436   getOperand(2)->printAsOperand(O, SlotTracker);
437   O << (InvariantCond ? " (condition is loop invariant)" : "");
438 }
439 #endif
440 
441 void VPWidenSelectRecipe::execute(VPTransformState &State) {
442   auto &I = *cast<SelectInst>(getUnderlyingInstr());
443   State.setDebugLocFromInst(&I);
444 
445   // The condition can be loop invariant but still defined inside the
446   // loop. This means that we can't just use the original 'cond' value.
447   // We have to take the 'vectorized' value and pick the first lane.
448   // Instcombine will make this a no-op.
449   auto *InvarCond =
450       InvariantCond ? State.get(getOperand(0), VPIteration(0, 0)) : nullptr;
451 
452   for (unsigned Part = 0; Part < State.UF; ++Part) {
453     Value *Cond = InvarCond ? InvarCond : State.get(getOperand(0), Part);
454     Value *Op0 = State.get(getOperand(1), Part);
455     Value *Op1 = State.get(getOperand(2), Part);
456     Value *Sel = State.Builder.CreateSelect(Cond, Op0, Op1);
457     State.set(this, Sel, Part);
458     State.addMetadata(Sel, &I);
459   }
460 }
461 
462 void VPWidenRecipe::execute(VPTransformState &State) {
463   auto &I = *cast<Instruction>(getUnderlyingValue());
464   auto &Builder = State.Builder;
465   switch (I.getOpcode()) {
466   case Instruction::Call:
467   case Instruction::Br:
468   case Instruction::PHI:
469   case Instruction::GetElementPtr:
470   case Instruction::Select:
471     llvm_unreachable("This instruction is handled by a different recipe.");
472   case Instruction::UDiv:
473   case Instruction::SDiv:
474   case Instruction::SRem:
475   case Instruction::URem:
476   case Instruction::Add:
477   case Instruction::FAdd:
478   case Instruction::Sub:
479   case Instruction::FSub:
480   case Instruction::FNeg:
481   case Instruction::Mul:
482   case Instruction::FMul:
483   case Instruction::FDiv:
484   case Instruction::FRem:
485   case Instruction::Shl:
486   case Instruction::LShr:
487   case Instruction::AShr:
488   case Instruction::And:
489   case Instruction::Or:
490   case Instruction::Xor: {
491     // Just widen unops and binops.
492     State.setDebugLocFromInst(&I);
493 
494     for (unsigned Part = 0; Part < State.UF; ++Part) {
495       SmallVector<Value *, 2> Ops;
496       for (VPValue *VPOp : operands())
497         Ops.push_back(State.get(VPOp, Part));
498 
499       Value *V = Builder.CreateNAryOp(I.getOpcode(), Ops);
500 
501       if (auto *VecOp = dyn_cast<Instruction>(V)) {
502         VecOp->copyIRFlags(&I);
503 
504         // If the instruction is vectorized and was in a basic block that needed
505         // predication, we can't propagate poison-generating flags (nuw/nsw,
506         // exact, etc.). The control flow has been linearized and the
507         // instruction is no longer guarded by the predicate, which could make
508         // the flag properties to no longer hold.
509         if (State.MayGeneratePoisonRecipes.contains(this))
510           VecOp->dropPoisonGeneratingFlags();
511       }
512 
513       // Use this vector value for all users of the original instruction.
514       State.set(this, V, Part);
515       State.addMetadata(V, &I);
516     }
517 
518     break;
519   }
520   case Instruction::Freeze: {
521     State.setDebugLocFromInst(&I);
522 
523     for (unsigned Part = 0; Part < State.UF; ++Part) {
524       Value *Op = State.get(getOperand(0), Part);
525 
526       Value *Freeze = Builder.CreateFreeze(Op);
527       State.set(this, Freeze, Part);
528     }
529     break;
530   }
531   case Instruction::ICmp:
532   case Instruction::FCmp: {
533     // Widen compares. Generate vector compares.
534     bool FCmp = (I.getOpcode() == Instruction::FCmp);
535     auto *Cmp = cast<CmpInst>(&I);
536     State.setDebugLocFromInst(Cmp);
537     for (unsigned Part = 0; Part < State.UF; ++Part) {
538       Value *A = State.get(getOperand(0), Part);
539       Value *B = State.get(getOperand(1), Part);
540       Value *C = nullptr;
541       if (FCmp) {
542         // Propagate fast math flags.
543         IRBuilder<>::FastMathFlagGuard FMFG(Builder);
544         Builder.setFastMathFlags(Cmp->getFastMathFlags());
545         C = Builder.CreateFCmp(Cmp->getPredicate(), A, B);
546       } else {
547         C = Builder.CreateICmp(Cmp->getPredicate(), A, B);
548       }
549       State.set(this, C, Part);
550       State.addMetadata(C, &I);
551     }
552 
553     break;
554   }
555 
556   case Instruction::ZExt:
557   case Instruction::SExt:
558   case Instruction::FPToUI:
559   case Instruction::FPToSI:
560   case Instruction::FPExt:
561   case Instruction::PtrToInt:
562   case Instruction::IntToPtr:
563   case Instruction::SIToFP:
564   case Instruction::UIToFP:
565   case Instruction::Trunc:
566   case Instruction::FPTrunc:
567   case Instruction::BitCast: {
568     auto *CI = cast<CastInst>(&I);
569     State.setDebugLocFromInst(CI);
570 
571     /// Vectorize casts.
572     Type *DestTy = (State.VF.isScalar())
573                        ? CI->getType()
574                        : VectorType::get(CI->getType(), State.VF);
575 
576     for (unsigned Part = 0; Part < State.UF; ++Part) {
577       Value *A = State.get(getOperand(0), Part);
578       Value *Cast = Builder.CreateCast(CI->getOpcode(), A, DestTy);
579       State.set(this, Cast, Part);
580       State.addMetadata(Cast, &I);
581     }
582     break;
583   }
584   default:
585     // This instruction is not vectorized by simple widening.
586     LLVM_DEBUG(dbgs() << "LV: Found an unhandled instruction: " << I);
587     llvm_unreachable("Unhandled instruction!");
588   } // end of switch.
589 }
590 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
591 void VPWidenRecipe::print(raw_ostream &O, const Twine &Indent,
592                           VPSlotTracker &SlotTracker) const {
593   O << Indent << "WIDEN ";
594   printAsOperand(O, SlotTracker);
595   O << " = " << getUnderlyingInstr()->getOpcodeName() << " ";
596   printOperands(O, SlotTracker);
597 }
598 
599 void VPWidenIntOrFpInductionRecipe::print(raw_ostream &O, const Twine &Indent,
600                                           VPSlotTracker &SlotTracker) const {
601   O << Indent << "WIDEN-INDUCTION";
602   if (getTruncInst()) {
603     O << "\\l\"";
604     O << " +\n" << Indent << "\"  " << VPlanIngredient(IV) << "\\l\"";
605     O << " +\n" << Indent << "\"  ";
606     getVPValue(0)->printAsOperand(O, SlotTracker);
607   } else
608     O << " " << VPlanIngredient(IV);
609 
610   O << ", ";
611   getStepValue()->printAsOperand(O, SlotTracker);
612 }
613 #endif
614 
615 bool VPWidenIntOrFpInductionRecipe::isCanonical() const {
616   auto *StartC = dyn_cast<ConstantInt>(getStartValue()->getLiveInIRValue());
617   auto *StepC = dyn_cast<SCEVConstant>(getInductionDescriptor().getStep());
618   return StartC && StartC->isZero() && StepC && StepC->isOne();
619 }
620 
621 VPCanonicalIVPHIRecipe *VPScalarIVStepsRecipe::getCanonicalIV() const {
622   return cast<VPCanonicalIVPHIRecipe>(getOperand(0));
623 }
624 
625 bool VPScalarIVStepsRecipe::isCanonical() const {
626   auto *CanIV = getCanonicalIV();
627   // The start value of the steps-recipe must match the start value of the
628   // canonical induction and it must step by 1.
629   if (CanIV->getStartValue() != getStartValue())
630     return false;
631   auto *StepVPV = getStepValue();
632   if (StepVPV->getDef())
633     return false;
634   auto *StepC = dyn_cast_or_null<ConstantInt>(StepVPV->getLiveInIRValue());
635   return StepC && StepC->isOne();
636 }
637 
638 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
639 void VPScalarIVStepsRecipe::print(raw_ostream &O, const Twine &Indent,
640                                   VPSlotTracker &SlotTracker) const {
641   O << Indent;
642   printAsOperand(O, SlotTracker);
643   O << Indent << "= SCALAR-STEPS ";
644   printOperands(O, SlotTracker);
645 }
646 #endif
647 
648 void VPWidenGEPRecipe::execute(VPTransformState &State) {
649   auto *GEP = cast<GetElementPtrInst>(getUnderlyingInstr());
650   // Construct a vector GEP by widening the operands of the scalar GEP as
651   // necessary. We mark the vector GEP 'inbounds' if appropriate. A GEP
652   // results in a vector of pointers when at least one operand of the GEP
653   // is vector-typed. Thus, to keep the representation compact, we only use
654   // vector-typed operands for loop-varying values.
655 
656   if (State.VF.isVector() && IsPtrLoopInvariant && IsIndexLoopInvariant.all()) {
657     // If we are vectorizing, but the GEP has only loop-invariant operands,
658     // the GEP we build (by only using vector-typed operands for
659     // loop-varying values) would be a scalar pointer. Thus, to ensure we
660     // produce a vector of pointers, we need to either arbitrarily pick an
661     // operand to broadcast, or broadcast a clone of the original GEP.
662     // Here, we broadcast a clone of the original.
663     //
664     // TODO: If at some point we decide to scalarize instructions having
665     //       loop-invariant operands, this special case will no longer be
666     //       required. We would add the scalarization decision to
667     //       collectLoopScalars() and teach getVectorValue() to broadcast
668     //       the lane-zero scalar value.
669     auto *Clone = State.Builder.Insert(GEP->clone());
670     for (unsigned Part = 0; Part < State.UF; ++Part) {
671       Value *EntryPart = State.Builder.CreateVectorSplat(State.VF, Clone);
672       State.set(this, EntryPart, Part);
673       State.addMetadata(EntryPart, GEP);
674     }
675   } else {
676     // If the GEP has at least one loop-varying operand, we are sure to
677     // produce a vector of pointers. But if we are only unrolling, we want
678     // to produce a scalar GEP for each unroll part. Thus, the GEP we
679     // produce with the code below will be scalar (if VF == 1) or vector
680     // (otherwise). Note that for the unroll-only case, we still maintain
681     // values in the vector mapping with initVector, as we do for other
682     // instructions.
683     for (unsigned Part = 0; Part < State.UF; ++Part) {
684       // The pointer operand of the new GEP. If it's loop-invariant, we
685       // won't broadcast it.
686       auto *Ptr = IsPtrLoopInvariant
687                       ? State.get(getOperand(0), VPIteration(0, 0))
688                       : State.get(getOperand(0), Part);
689 
690       // Collect all the indices for the new GEP. If any index is
691       // loop-invariant, we won't broadcast it.
692       SmallVector<Value *, 4> Indices;
693       for (unsigned I = 1, E = getNumOperands(); I < E; I++) {
694         VPValue *Operand = getOperand(I);
695         if (IsIndexLoopInvariant[I - 1])
696           Indices.push_back(State.get(Operand, VPIteration(0, 0)));
697         else
698           Indices.push_back(State.get(Operand, Part));
699       }
700 
701       // If the GEP instruction is vectorized and was in a basic block that
702       // needed predication, we can't propagate the poison-generating 'inbounds'
703       // flag. The control flow has been linearized and the GEP is no longer
704       // guarded by the predicate, which could make the 'inbounds' properties to
705       // no longer hold.
706       bool IsInBounds =
707           GEP->isInBounds() && State.MayGeneratePoisonRecipes.count(this) == 0;
708 
709       // Create the new GEP. Note that this GEP may be a scalar if VF == 1,
710       // but it should be a vector, otherwise.
711       auto *NewGEP = State.Builder.CreateGEP(GEP->getSourceElementType(), Ptr,
712                                              Indices, "", IsInBounds);
713       assert((State.VF.isScalar() || NewGEP->getType()->isVectorTy()) &&
714              "NewGEP is not a pointer vector");
715       State.set(this, NewGEP, Part);
716       State.addMetadata(NewGEP, GEP);
717     }
718   }
719 }
720 
721 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
722 void VPWidenGEPRecipe::print(raw_ostream &O, const Twine &Indent,
723                              VPSlotTracker &SlotTracker) const {
724   O << Indent << "WIDEN-GEP ";
725   O << (IsPtrLoopInvariant ? "Inv" : "Var");
726   size_t IndicesNumber = IsIndexLoopInvariant.size();
727   for (size_t I = 0; I < IndicesNumber; ++I)
728     O << "[" << (IsIndexLoopInvariant[I] ? "Inv" : "Var") << "]";
729 
730   O << " ";
731   printAsOperand(O, SlotTracker);
732   O << " = getelementptr ";
733   printOperands(O, SlotTracker);
734 }
735 
736 void VPBlendRecipe::print(raw_ostream &O, const Twine &Indent,
737                           VPSlotTracker &SlotTracker) const {
738   O << Indent << "BLEND ";
739   Phi->printAsOperand(O, false);
740   O << " =";
741   if (getNumIncomingValues() == 1) {
742     // Not a User of any mask: not really blending, this is a
743     // single-predecessor phi.
744     O << " ";
745     getIncomingValue(0)->printAsOperand(O, SlotTracker);
746   } else {
747     for (unsigned I = 0, E = getNumIncomingValues(); I < E; ++I) {
748       O << " ";
749       getIncomingValue(I)->printAsOperand(O, SlotTracker);
750       O << "/";
751       getMask(I)->printAsOperand(O, SlotTracker);
752     }
753   }
754 }
755 
756 void VPReductionRecipe::print(raw_ostream &O, const Twine &Indent,
757                               VPSlotTracker &SlotTracker) const {
758   O << Indent << "REDUCE ";
759   printAsOperand(O, SlotTracker);
760   O << " = ";
761   getChainOp()->printAsOperand(O, SlotTracker);
762   O << " +";
763   if (isa<FPMathOperator>(getUnderlyingInstr()))
764     O << getUnderlyingInstr()->getFastMathFlags();
765   O << " reduce." << Instruction::getOpcodeName(RdxDesc->getOpcode()) << " (";
766   getVecOp()->printAsOperand(O, SlotTracker);
767   if (getCondOp()) {
768     O << ", ";
769     getCondOp()->printAsOperand(O, SlotTracker);
770   }
771   O << ")";
772   if (RdxDesc->IntermediateStore)
773     O << " (with final reduction value stored in invariant address sank "
774          "outside of loop)";
775 }
776 
777 void VPReplicateRecipe::print(raw_ostream &O, const Twine &Indent,
778                               VPSlotTracker &SlotTracker) const {
779   O << Indent << (IsUniform ? "CLONE " : "REPLICATE ");
780 
781   if (!getUnderlyingInstr()->getType()->isVoidTy()) {
782     printAsOperand(O, SlotTracker);
783     O << " = ";
784   }
785   if (auto *CB = dyn_cast<CallBase>(getUnderlyingInstr())) {
786     O << "call @" << CB->getCalledFunction()->getName() << "(";
787     interleaveComma(make_range(op_begin(), op_begin() + (getNumOperands() - 1)),
788                     O, [&O, &SlotTracker](VPValue *Op) {
789                       Op->printAsOperand(O, SlotTracker);
790                     });
791     O << ")";
792   } else {
793     O << Instruction::getOpcodeName(getUnderlyingInstr()->getOpcode()) << " ";
794     printOperands(O, SlotTracker);
795   }
796 
797   if (AlsoPack)
798     O << " (S->V)";
799 }
800 
801 void VPPredInstPHIRecipe::print(raw_ostream &O, const Twine &Indent,
802                                 VPSlotTracker &SlotTracker) const {
803   O << Indent << "PHI-PREDICATED-INSTRUCTION ";
804   printAsOperand(O, SlotTracker);
805   O << " = ";
806   printOperands(O, SlotTracker);
807 }
808 
809 void VPWidenMemoryInstructionRecipe::print(raw_ostream &O, const Twine &Indent,
810                                            VPSlotTracker &SlotTracker) const {
811   O << Indent << "WIDEN ";
812 
813   if (!isStore()) {
814     getVPSingleValue()->printAsOperand(O, SlotTracker);
815     O << " = ";
816   }
817   O << Instruction::getOpcodeName(Ingredient.getOpcode()) << " ";
818 
819   printOperands(O, SlotTracker);
820 }
821 #endif
822 
823 void VPCanonicalIVPHIRecipe::execute(VPTransformState &State) {
824   Value *Start = getStartValue()->getLiveInIRValue();
825   PHINode *EntryPart = PHINode::Create(
826       Start->getType(), 2, "index", &*State.CFG.PrevBB->getFirstInsertionPt());
827 
828   BasicBlock *VectorPH = State.CFG.getPreheaderBBFor(this);
829   EntryPart->addIncoming(Start, VectorPH);
830   EntryPart->setDebugLoc(DL);
831   for (unsigned Part = 0, UF = State.UF; Part < UF; ++Part)
832     State.set(this, EntryPart, Part);
833 }
834 
835 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
836 void VPCanonicalIVPHIRecipe::print(raw_ostream &O, const Twine &Indent,
837                                    VPSlotTracker &SlotTracker) const {
838   O << Indent << "EMIT ";
839   printAsOperand(O, SlotTracker);
840   O << " = CANONICAL-INDUCTION";
841 }
842 #endif
843 
844 bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(ElementCount VF) {
845   bool IsUniform = vputils::onlyFirstLaneUsed(this);
846   return all_of(users(),
847                 [&](const VPUser *U) { return U->usesScalars(this); }) &&
848          (IsUniform || !VF.isScalable());
849 }
850 
851 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
852 void VPWidenPointerInductionRecipe::print(raw_ostream &O, const Twine &Indent,
853                                           VPSlotTracker &SlotTracker) const {
854   O << Indent << "EMIT ";
855   printAsOperand(O, SlotTracker);
856   O << " = WIDEN-POINTER-INDUCTION ";
857   getStartValue()->printAsOperand(O, SlotTracker);
858   O << ", " << *IndDesc.getStep();
859 }
860 #endif
861 
862 void VPExpandSCEVRecipe::execute(VPTransformState &State) {
863   assert(!State.Instance && "cannot be used in per-lane");
864   const DataLayout &DL = State.CFG.PrevBB->getModule()->getDataLayout();
865   SCEVExpander Exp(SE, DL, "induction");
866 
867   Value *Res = Exp.expandCodeFor(Expr, Expr->getType(),
868                                  &*State.Builder.GetInsertPoint());
869 
870   for (unsigned Part = 0, UF = State.UF; Part < UF; ++Part)
871     State.set(this, Res, Part);
872 }
873 
874 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
875 void VPExpandSCEVRecipe::print(raw_ostream &O, const Twine &Indent,
876                                VPSlotTracker &SlotTracker) const {
877   O << Indent << "EMIT ";
878   getVPSingleValue()->printAsOperand(O, SlotTracker);
879   O << " = EXPAND SCEV " << *Expr;
880 }
881 #endif
882 
883 void VPWidenCanonicalIVRecipe::execute(VPTransformState &State) {
884   Value *CanonicalIV = State.get(getOperand(0), 0);
885   Type *STy = CanonicalIV->getType();
886   IRBuilder<> Builder(State.CFG.PrevBB->getTerminator());
887   ElementCount VF = State.VF;
888   Value *VStart = VF.isScalar()
889                       ? CanonicalIV
890                       : Builder.CreateVectorSplat(VF, CanonicalIV, "broadcast");
891   for (unsigned Part = 0, UF = State.UF; Part < UF; ++Part) {
892     Value *VStep = createStepForVF(Builder, STy, VF, Part);
893     if (VF.isVector()) {
894       VStep = Builder.CreateVectorSplat(VF, VStep);
895       VStep =
896           Builder.CreateAdd(VStep, Builder.CreateStepVector(VStep->getType()));
897     }
898     Value *CanonicalVectorIV = Builder.CreateAdd(VStart, VStep, "vec.iv");
899     State.set(this, CanonicalVectorIV, Part);
900   }
901 }
902 
903 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
904 void VPWidenCanonicalIVRecipe::print(raw_ostream &O, const Twine &Indent,
905                                      VPSlotTracker &SlotTracker) const {
906   O << Indent << "EMIT ";
907   printAsOperand(O, SlotTracker);
908   O << " = WIDEN-CANONICAL-INDUCTION ";
909   printOperands(O, SlotTracker);
910 }
911 #endif
912 
913 void VPFirstOrderRecurrencePHIRecipe::execute(VPTransformState &State) {
914   auto &Builder = State.Builder;
915   // Create a vector from the initial value.
916   auto *VectorInit = getStartValue()->getLiveInIRValue();
917 
918   Type *VecTy = State.VF.isScalar()
919                     ? VectorInit->getType()
920                     : VectorType::get(VectorInit->getType(), State.VF);
921 
922   BasicBlock *VectorPH = State.CFG.getPreheaderBBFor(this);
923   if (State.VF.isVector()) {
924     auto *IdxTy = Builder.getInt32Ty();
925     auto *One = ConstantInt::get(IdxTy, 1);
926     IRBuilder<>::InsertPointGuard Guard(Builder);
927     Builder.SetInsertPoint(VectorPH->getTerminator());
928     auto *RuntimeVF = getRuntimeVF(Builder, IdxTy, State.VF);
929     auto *LastIdx = Builder.CreateSub(RuntimeVF, One);
930     VectorInit = Builder.CreateInsertElement(
931         PoisonValue::get(VecTy), VectorInit, LastIdx, "vector.recur.init");
932   }
933 
934   // Create a phi node for the new recurrence.
935   PHINode *EntryPart = PHINode::Create(
936       VecTy, 2, "vector.recur", &*State.CFG.PrevBB->getFirstInsertionPt());
937   EntryPart->addIncoming(VectorInit, VectorPH);
938   State.set(this, EntryPart, 0);
939 }
940 
941 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
942 void VPFirstOrderRecurrencePHIRecipe::print(raw_ostream &O, const Twine &Indent,
943                                             VPSlotTracker &SlotTracker) const {
944   O << Indent << "FIRST-ORDER-RECURRENCE-PHI ";
945   printAsOperand(O, SlotTracker);
946   O << " = phi ";
947   printOperands(O, SlotTracker);
948 }
949 #endif
950 
951 void VPReductionPHIRecipe::execute(VPTransformState &State) {
952   PHINode *PN = cast<PHINode>(getUnderlyingValue());
953   auto &Builder = State.Builder;
954 
955   // In order to support recurrences we need to be able to vectorize Phi nodes.
956   // Phi nodes have cycles, so we need to vectorize them in two stages. This is
957   // stage #1: We create a new vector PHI node with no incoming edges. We'll use
958   // this value when we vectorize all of the instructions that use the PHI.
959   bool ScalarPHI = State.VF.isScalar() || IsInLoop;
960   Type *VecTy =
961       ScalarPHI ? PN->getType() : VectorType::get(PN->getType(), State.VF);
962 
963   BasicBlock *HeaderBB = State.CFG.PrevBB;
964   assert(State.CurrentVectorLoop->getHeader() == HeaderBB &&
965          "recipe must be in the vector loop header");
966   unsigned LastPartForNewPhi = isOrdered() ? 1 : State.UF;
967   for (unsigned Part = 0; Part < LastPartForNewPhi; ++Part) {
968     Value *EntryPart =
969         PHINode::Create(VecTy, 2, "vec.phi", &*HeaderBB->getFirstInsertionPt());
970     State.set(this, EntryPart, Part);
971   }
972 
973   BasicBlock *VectorPH = State.CFG.getPreheaderBBFor(this);
974 
975   // Reductions do not have to start at zero. They can start with
976   // any loop invariant values.
977   VPValue *StartVPV = getStartValue();
978   Value *StartV = StartVPV->getLiveInIRValue();
979 
980   Value *Iden = nullptr;
981   RecurKind RK = RdxDesc.getRecurrenceKind();
982   if (RecurrenceDescriptor::isMinMaxRecurrenceKind(RK) ||
983       RecurrenceDescriptor::isSelectCmpRecurrenceKind(RK)) {
984     // MinMax reduction have the start value as their identify.
985     if (ScalarPHI) {
986       Iden = StartV;
987     } else {
988       IRBuilderBase::InsertPointGuard IPBuilder(Builder);
989       Builder.SetInsertPoint(VectorPH->getTerminator());
990       StartV = Iden =
991           Builder.CreateVectorSplat(State.VF, StartV, "minmax.ident");
992     }
993   } else {
994     Iden = RdxDesc.getRecurrenceIdentity(RK, VecTy->getScalarType(),
995                                          RdxDesc.getFastMathFlags());
996 
997     if (!ScalarPHI) {
998       Iden = Builder.CreateVectorSplat(State.VF, Iden);
999       IRBuilderBase::InsertPointGuard IPBuilder(Builder);
1000       Builder.SetInsertPoint(VectorPH->getTerminator());
1001       Constant *Zero = Builder.getInt32(0);
1002       StartV = Builder.CreateInsertElement(Iden, StartV, Zero);
1003     }
1004   }
1005 
1006   for (unsigned Part = 0; Part < LastPartForNewPhi; ++Part) {
1007     Value *EntryPart = State.get(this, Part);
1008     // Make sure to add the reduction start value only to the
1009     // first unroll part.
1010     Value *StartVal = (Part == 0) ? StartV : Iden;
1011     cast<PHINode>(EntryPart)->addIncoming(StartVal, VectorPH);
1012   }
1013 }
1014 
1015 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1016 void VPReductionPHIRecipe::print(raw_ostream &O, const Twine &Indent,
1017                                  VPSlotTracker &SlotTracker) const {
1018   O << Indent << "WIDEN-REDUCTION-PHI ";
1019 
1020   printAsOperand(O, SlotTracker);
1021   O << " = phi ";
1022   printOperands(O, SlotTracker);
1023 }
1024 #endif
1025 
1026 void VPWidenPHIRecipe::execute(VPTransformState &State) {
1027   assert(EnableVPlanNativePath &&
1028          "Non-native vplans are not expected to have VPWidenPHIRecipes.");
1029 
1030   // Currently we enter here in the VPlan-native path for non-induction
1031   // PHIs where all control flow is uniform. We simply widen these PHIs.
1032   // Create a vector phi with no operands - the vector phi operands will be
1033   // set at the end of vector code generation.
1034   VPBasicBlock *Parent = getParent();
1035   VPRegionBlock *LoopRegion = Parent->getEnclosingLoopRegion();
1036   unsigned StartIdx = 0;
1037   // For phis in header blocks of loop regions, use the index of the value
1038   // coming from the preheader.
1039   if (LoopRegion->getEntryBasicBlock() == Parent) {
1040     for (unsigned I = 0; I < getNumOperands(); ++I) {
1041       if (getIncomingBlock(I) ==
1042           LoopRegion->getSinglePredecessor()->getExitingBasicBlock())
1043         StartIdx = I;
1044     }
1045   }
1046   Value *Op0 = State.get(getOperand(StartIdx), 0);
1047   Type *VecTy = Op0->getType();
1048   Value *VecPhi = State.Builder.CreatePHI(VecTy, 2, "vec.phi");
1049   State.set(this, VecPhi, 0);
1050 }
1051 
1052 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1053 void VPWidenPHIRecipe::print(raw_ostream &O, const Twine &Indent,
1054                              VPSlotTracker &SlotTracker) const {
1055   O << Indent << "WIDEN-PHI ";
1056 
1057   auto *OriginalPhi = cast<PHINode>(getUnderlyingValue());
1058   // Unless all incoming values are modeled in VPlan  print the original PHI
1059   // directly.
1060   // TODO: Remove once all VPWidenPHIRecipe instances keep all relevant incoming
1061   // values as VPValues.
1062   if (getNumOperands() != OriginalPhi->getNumOperands()) {
1063     O << VPlanIngredient(OriginalPhi);
1064     return;
1065   }
1066 
1067   printAsOperand(O, SlotTracker);
1068   O << " = phi ";
1069   printOperands(O, SlotTracker);
1070 }
1071 #endif
1072