LLVM 23.0.0git
VPlanUtils.cpp
Go to the documentation of this file.
1//===- VPlanUtils.cpp - VPlan-related utilities ---------------------------===//
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#include "VPlanUtils.h"
11#include "VPlanAnalysis.h"
12#include "VPlanCFG.h"
13#include "VPlanDominatorTree.h"
14#include "VPlanPatternMatch.h"
15#include "llvm/ADT/TypeSwitch.h"
19#include "llvm/IR/Dominators.h"
21
22using namespace llvm;
23using namespace llvm::VPlanPatternMatch;
24using namespace llvm::SCEVPatternMatch;
25
27 return all_of(Def->users(),
28 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
29}
30
32 return all_of(Def->users(),
33 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
34}
35
37 return all_of(Def->users(),
38 [Def](const VPUser *U) { return U->usesScalars(Def); });
39}
40
42 if (auto *E = dyn_cast<SCEVConstant>(Expr))
43 return Plan.getOrAddLiveIn(E->getValue());
44 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
45 // value. Otherwise the value may be defined in a loop and using it directly
46 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
47 // form.
48 auto *U = dyn_cast<SCEVUnknown>(Expr);
49 if (U && !isa<Instruction>(U->getValue()))
50 return Plan.getOrAddLiveIn(U->getValue());
51 auto *Expanded = new VPExpandSCEVRecipe(Expr);
52 VPBasicBlock *EntryVPBB = Plan.getEntry();
53 auto Iter = EntryVPBB->getFirstNonPhi();
54 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
55 ++Iter;
56 EntryVPBB->insert(Expanded, Iter);
57 return Expanded;
58}
59
60bool vputils::isHeaderMask(const VPValue *V, const VPlan &Plan) {
62 return true;
63
64 VPValue *A, *B;
65
66 auto m_CanonicalScalarIVSteps = m_ScalarIVSteps(
69 m_One(), m_Specific(&Plan.getVF()));
70
71 // A wide canonical IV is either an explicit VPWidenCanonicalIVRecipe or a
72 // canonical VPWidenIntOrFpInductionRecipe.
73 auto m_WideCanonicalIV =
75
77 return B == Plan.getTripCount() &&
78 (match(A, m_CanonicalScalarIVSteps) || match(A, m_WideCanonicalIV));
79
80 // For scalar plans, the header mask uses the scalar steps.
81 if (match(V, m_ICmp(m_CanonicalScalarIVSteps,
83 assert(Plan.hasScalarVFOnly() &&
84 "Non-scalar VF using scalar IV steps for header mask?");
85 return true;
86 }
87
88 auto MaskMatch = m_ICmp(m_VPValue(A), m_VPValue(B));
89 if (match(V, m_CombineOr(MaskMatch, m_Reverse(MaskMatch))))
90 return match(A, m_WideCanonicalIV) && B == Plan.getBackedgeTakenCount();
91
92 return match(
95}
96
97/// Returns true if \p R propagates poison from any operand to its result.
101 [](const VPRecipeBase *) { return true; })
102 .Case([](const VPReplicateRecipe *Rep) {
103 // GEP and casts propagate poison from all operands.
104 unsigned Opcode = Rep->getOpcode();
105 return Opcode == Instruction::GetElementPtr ||
106 Instruction::isCast(Opcode);
107 })
108 .Default([](const VPRecipeBase *) { return false; });
109}
110
111/// Returns true if \p V being poison is guaranteed to trigger UB because it
112/// propagates to the address of a memory recipe.
113static bool poisonGuaranteesUB(const VPValue *V) {
116
117 Worklist.push_back(V);
118
119 while (!Worklist.empty()) {
120 const VPValue *Current = Worklist.pop_back_val();
121 if (!Visited.insert(Current).second)
122 continue;
123
124 for (VPUser *U : Current->users()) {
125 // Check if Current is used as an address operand for load/store.
127 if (MemR->getAddr() == Current)
128 return true;
129 continue;
130 }
131 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
132 unsigned Opcode = Rep->getOpcode();
133 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
134 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
135 return true;
136 }
137
138 // Check if poison propagates through this recipe to any of its users.
139 auto *R = cast<VPRecipeBase>(U);
140 for (const VPValue *Op : R->operands()) {
141 if (Op == Current && propagatesPoisonFromRecipeOp(R)) {
142 Worklist.push_back(R->getVPSingleValue());
143 break;
144 }
145 }
146 }
147 }
148
149 return false;
150}
151
153 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
154 // casts to find a root GEP VPInstruction.
155 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
156 unsigned Opcode = PtrVPI->getOpcode();
157 if (Opcode == Instruction::GetElementPtr) {
158 if (any_of(drop_begin(PtrVPI->operands()),
159 [](VPValue *Op) { return !match(Op, m_ZeroInt()); }))
160 return PtrVPI->getGEPNoWrapFlags();
161 Ptr = PtrVPI->getOperand(0);
162 continue;
163 }
164 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
165 break;
166 Ptr = PtrVPI->getOperand(0);
167 }
168 return GEPNoWrapFlags::none();
169}
170
173 const Loop *L) {
174 ScalarEvolution &SE = *PSE.getSE();
176 Value *LiveIn = V->getUnderlyingValue();
177 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
178 return SE.getSCEV(LiveIn);
179 return SE.getCouldNotCompute();
180 }
181
182 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
183 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
184 "RegionValue must be canonical IV");
185 if (!L)
186 return SE.getCouldNotCompute();
187 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
189 }
190
191 // Helper to create SCEVs for binary and unary operations.
192 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
193 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
194 -> const SCEV * {
196 for (VPValue *Op : Ops) {
197 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
199 return SE.getCouldNotCompute();
200 SCEVOps.push_back(S);
201 }
202 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
203 };
204
205 VPValue *LHSVal, *RHSVal;
206 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
207 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
208 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
209 });
210 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
211 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
212 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
213 });
214 if (match(V, m_Not(m_VPValue(LHSVal)))) {
215 // not X = xor X, -1 = -1 - X
216 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
217 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
218 });
219 }
220 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
221 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
222 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
223 });
224 // Handle shl by constant: x << c is equivalent to x * (1 << c).
225 uint64_t ShiftAmt;
226 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))))
227 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
228 return SE.getMulExpr(Ops[0],
229 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
230 });
231 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
232 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
233 return SE.getUDivExpr(Ops[0], Ops[1]);
234 });
235 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
236 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
237 return SE.getURemExpr(Ops[0], Ops[1]);
238 });
239 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
240 const APInt *Mask;
241 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
242 (*Mask + 1).isPowerOf2())
243 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
244 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
245 });
246 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
247 Type *DestTy = V->getScalarType();
248 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
249 return SE.getTruncateExpr(Ops[0], DestTy);
250 });
251 }
252 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
253 Type *DestTy = V->getScalarType();
254 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
255 return SE.getZeroExtendExpr(Ops[0], DestTy);
256 });
257 }
258 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
259 Type *DestTy = V->getScalarType();
260
261 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
262 // onto the operands before computing the subtraction.
263 VPValue *SubLHS, *SubRHS;
264 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
265 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
266 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
267 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
268 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
270 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
271 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
272 }
273
274 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
275 return SE.getSignExtendExpr(Ops[0], DestTy);
276 });
277 }
278 if (match(V,
280 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
281 return SE.getUMaxExpr(Ops[0], Ops[1]);
282 });
283 if (match(V,
285 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
286 return SE.getSMaxExpr(Ops[0], Ops[1]);
287 });
288 if (match(V,
290 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
291 return SE.getUMinExpr(Ops[0], Ops[1]);
292 });
293 if (match(V,
295 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
296 return SE.getSMinExpr(Ops[0], Ops[1]);
297 });
299 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
300 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
301 // not proof that the input is never INT_MIN, nor that poison reaches
302 // UB. Do not translate it to SCEV's global IsNSW flag.
303 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
304 });
305
307 Type *SourceElementType;
308 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
309 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
310 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
311 });
312 }
313
314 // TODO: Support constructing SCEVs for more recipes as needed.
315 const VPRecipeBase *DefR = V->getDefiningRecipe();
316 const SCEV *Expr =
318 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
319 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
320 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
321 if (!L || isa<SCEVCouldNotCompute>(Step))
322 return SE.getCouldNotCompute();
323 const SCEV *Start =
324 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
325 const SCEV *AddRec =
326 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
327 if (R->getTruncInst())
328 return SE.getTruncateExpr(AddRec, R->getScalarType());
329 return AddRec;
330 })
331 .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
332 const SCEV *Start =
333 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
334 if (!L || isa<SCEVCouldNotCompute>(Start))
335 return SE.getCouldNotCompute();
336 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
337 if (isa<SCEVCouldNotCompute>(Step))
338 return SE.getCouldNotCompute();
339 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
340 })
341 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
342 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
343 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
344 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
345 if (any_of(ArrayRef({Start, IV, Scale}),
347 return SE.getCouldNotCompute();
348
349 return SE.getAddExpr(
350 SE.getTruncateOrSignExtend(Start, IV->getType()),
351 SE.getMulExpr(
352 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
353 })
354 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
355 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
356 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
358 return SE.getCouldNotCompute();
359 return SE.getTruncateOrSignExtend(IV, Step->getType());
360 })
361 .Default(
362 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
363
364 return PSE.getPredicatedSCEV(Expr);
365}
366
368 const Loop *L) {
369 // If address is an SCEVAddExpr, we require that all operands must be either
370 // be invariant or a (possibly sign-extend) affine AddRec.
371 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
372 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
373 return SE.isLoopInvariant(Op, L) ||
374 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
375 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
376 });
377 }
378
379 // Otherwise, check if address is loop invariant or an affine add recurrence.
380 return SE.isLoopInvariant(Addr, L) ||
382}
383
384/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
385/// uniform, the result will also be uniform.
386static bool preservesUniformity(unsigned Opcode) {
387 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
388 return true;
389 switch (Opcode) {
390 case Instruction::Freeze:
391 case Instruction::GetElementPtr:
392 case Instruction::ICmp:
393 case Instruction::FCmp:
394 case Instruction::Select:
399 return true;
400 default:
401 return false;
402 }
403}
404
406 // Live-in, symbolic and region-values represent single-scalar values.
408 return true;
409
410 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
411 const VPRegionBlock *RegionOfR = Rep->getRegion();
412 // Don't consider recipes in replicate regions as uniform yet; their first
413 // lane cannot be accessed when executing the replicate region for other
414 // lanes.
415 if (RegionOfR && RegionOfR->isReplicator())
416 return false;
417 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
418 all_of(Rep->operands(), isSingleScalar));
419 }
422 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
423 return preservesUniformity(WidenR->getOpcode()) &&
424 all_of(WidenR->operands(), isSingleScalar);
425 }
426 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
427 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
428 (preservesUniformity(VPI->getOpcode()) &&
429 all_of(VPI->operands(), isSingleScalar));
430 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
431 return !RR->isPartialReduction();
433 VPV))
434 return true;
435 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
436 return Expr->isVectorToScalar();
437
438 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
439 return isa<VPExpandSCEVRecipe>(VPV);
440}
441
443 // Live-ins and region values are uniform.
445 return true;
446
447 const VPRecipeBase *R = V->getDefiningRecipe();
448 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
449 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
450 if (VPBB) {
451 if ((VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
452 if (match(V->getDefiningRecipe(),
454 return false;
455 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
456 }
457 }
458
460 .Case([](const VPDerivedIVRecipe *R) { return true; })
461 .Case([](const VPReplicateRecipe *R) {
462 // Be conservative about side-effects, except for the
463 // known-side-effecting assumes and stores, which we know will be
464 // uniform.
465 return R->isSingleScalar() &&
466 (!R->mayHaveSideEffects() ||
467 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
468 all_of(R->operands(), isUniformAcrossVFsAndUFs);
469 })
470 .Case([](const VPWidenRecipe *R) {
471 return preservesUniformity(R->getOpcode()) &&
472 all_of(R->operands(), isUniformAcrossVFsAndUFs);
473 })
474 .Case([](const VPPhi *) {
475 // Bail out on VPPhi, as we can end up in infinite cycles.
476 return false;
477 })
478 .Case([](const VPInstruction *VPI) {
479 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
482 })
483 .Case([](const VPWidenCastRecipe *R) {
484 // A cast is uniform according to its operand.
485 return isUniformAcrossVFsAndUFs(R->getOperand(0));
486 })
487 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
488 // unless proven otherwise.
489 return false;
490 });
491}
492
494 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
495 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
496 return VPBlockUtils::isHeader(VPB, VPDT);
497 });
498 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
499}
500
502 if (!R)
503 return 1;
504 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
505 return RR->getVFScaleFactor();
506 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
507 return RR->getVFScaleFactor();
508 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
509 return ER->getVFScaleFactor();
510 assert(
513 "getting scaling factor of reduction-start-vector not implemented yet");
514 return 1;
515}
516
517bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
518 // Assumes don't alias anything or throw; as long as they're guaranteed to
519 // execute, they're safe to hoist. They should however not be sunk, as it
520 // would destroy information.
522 return Sinking;
523 // TODO: Relax checks in the future, e.g. we could also hoist reads, if their
524 // memory location is not modified in the vector loop.
525 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
526 return true;
527 // Allocas cannot be hoisted.
528 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
529 return RepR && RepR->getOpcode() == Instruction::Alloca;
530}
531
532std::optional<VPValue *>
535 VPBasicBlock *LatchVPBB) {
536 // Given a plain CFG VPlan loop with countable latch exiting block
537 // \p LatchVPBB, we're looking to match the recipes contributing to the
538 // uncountable exit condition comparison (here, vp<%4>) back to either
539 // live-ins or the address nodes for the load used as part of the uncountable
540 // exit comparison so that we can either move them within the loop, or copy
541 // them to the preheader depending on the chosen method for dealing with
542 // stores in uncountable exit loops.
543 //
544 // Currently, the address of the load is restricted to a GEP with 2 operands
545 // and a live-in base address. This constraint may be relaxed later.
546 //
547 // VPlan ' for UF>=1' {
548 // Live-in vp<%0> = VF * UF
549 // Live-in vp<%1> = vector-trip-count
550 // Live-in ir<20> = original trip-count
551 //
552 // ir-bb<entry>:
553 // Successor(s): scalar.ph, vector.ph
554 //
555 // vector.ph:
556 // Successor(s): for.body
557 //
558 // for.body:
559 // EMIT vp<%2> = phi ir<0>, vp<%index.next>
560 // EMIT-SCALAR ir<%iv> = phi [ ir<0>, vector.ph ], [ ir<%iv.next>, for.inc ]
561 // EMIT ir<%uncountable.addr> = getelementptr inbounds nuw ir<%pred>,ir<%iv>
562 // EMIT ir<%uncountable.val> = load ir<%uncountable.addr>
563 // EMIT ir<%uncountable.cond> = icmp sgt ir<%uncountable.val>, ir<500>
564 // EMIT vp<%3> = masked-cond ir<%uncountable.cond>
565 // Successor(s): for.inc
566 //
567 // for.inc:
568 // EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
569 // EMIT ir<%countable.cond> = icmp eq ir<%iv.next>, ir<20>
570 // EMIT vp<%index.next> = add nuw vp<%2>, vp<%0>
571 // EMIT vp<%4> = any-of ir<%3>
572 // EMIT vp<%5> = icmp eq vp<%index.next>, vp<%1>
573 // EMIT branch-on-two-conds vp<%4>, vp<%5>
574 // Successor(s): middle.block, middle.block, for.body
575 //
576 // middle.block:
577 // Successor(s): ir-bb<exit>, scalar.ph
578 //
579 // ir-bb<exit>:
580 // No successors
581 //
582 // scalar.ph:
583 // }
584
585 // Find the uncountable loop exit condition.
586 VPValue *UncountableCondition = nullptr;
587 if (!match(LatchVPBB->getTerminator(),
588 m_BranchOnTwoConds(m_AnyOf(m_VPValue(UncountableCondition)),
589 m_VPValue())))
590 return std::nullopt;
591
593 Worklist.push_back(UncountableCondition);
594 while (!Worklist.empty()) {
595 VPValue *V = Worklist.pop_back_val();
596
597 // Any value defined outside the loop does not need to be copied.
598 if (V->isDefinedOutsideLoopRegions())
599 continue;
600
601 // FIXME: Remove the single user restriction; it's here because we're
602 // starting with the simplest set of loops we can, and multiple
603 // users means needing to add PHI nodes in the transform.
604 if (V->getNumUsers() > 1)
605 return std::nullopt;
606
607 VPValue *Op1, *Op2;
608 // Walk back through recipes until we find at least one load from memory.
609 if (match(V, m_ICmp(m_VPValue(Op1), m_VPValue(Op2)))) {
610 Worklist.push_back(Op1);
611 Worklist.push_back(Op2);
612 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
614 VPRecipeBase *GepR = Op1->getDefiningRecipe();
615 // Only matching base + single offset term for now.
616 if (GepR->getNumOperands() != 2)
617 return std::nullopt;
618 // Matching a GEP with a loop-invariant base ptr.
620 m_LiveIn(), m_VPValue())))
621 return std::nullopt;
622 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
623 Recipes.push_back(cast<VPInstruction>(GepR));
624 GEPs.push_back(cast<VPInstruction>(GepR));
626 m_VPValue(Op1)))) {
627 Worklist.push_back(Op1);
628 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
629 } else
630 return std::nullopt;
631 }
632
633 // If we couldn't match anything, don't return the condition. It may be
634 // defined outside the loop.
635 if (Recipes.empty() || GEPs.empty())
636 return std::nullopt;
637
638 return UncountableCondition;
639}
640
642 if (VPValue *AliasMask = findIncomingAliasMask(Plan)) {
643 assert(match(AliasMask->getSingleUser(),
644 m_c_BinaryAnd(m_VPValue(), m_Specific(AliasMask))) &&
645 "AliasMask must only be used with the original header mask");
646 return cast<VPSingleDefRecipe>(AliasMask->getSingleUser());
647 }
648
649 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
650 SmallVector<VPValue *> WideCanonicalIVs;
651 auto *WideCanonicalIV =
653 assert(count_if(LoopRegion->getCanonicalIV()->users(),
655 "Must have at most one VPWideCanonicalIVRecipe");
656 if (WideCanonicalIV)
657 WideCanonicalIVs.push_back(WideCanonicalIV);
658
659 // Also include VPWidenIntOrFpInductionRecipes that represent a widened
660 // version of the canonical induction.
661 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
662 for (VPRecipeBase &Phi : HeaderVPBB->phis()) {
664 if (match(&Phi, m_CanonicalWidenIV(WidenIV)))
665 WideCanonicalIVs.push_back(WidenIV);
666 }
667
668 // Walk users of wide canonical IVs and find the single compare of the form
669 // (ICMP_ULE, WideCanonicalIV, backedge-taken-count).
670 VPSingleDefRecipe *HeaderMask = nullptr;
671 for (auto *Wide : WideCanonicalIVs) {
672 for (VPUser *U : Wide->users()) {
673 auto *VPI = dyn_cast<VPInstruction>(U);
674 if (!VPI || !vputils::isHeaderMask(VPI, Plan))
675 continue;
676
677 assert(VPI->getOperand(0) == Wide &&
678 "WidenCanonicalIV must be the first operand of the compare");
679 assert(!HeaderMask && "Multiple header masks found?");
680 HeaderMask = VPI;
681 }
682 }
683
684 for (VPRecipeBase &R : LoopRegion->getEntryBasicBlock()->phis()) {
685 auto *Def = cast<VPSingleDefRecipe>(&R);
686 if (vputils::isHeaderMask(Def, Plan)) {
687 assert(!HeaderMask && "Multiple header masks found?");
688 HeaderMask = Def;
689 }
690 }
691
692 return HeaderMask;
693}
694
697 VPBasicBlock *LastBB) {
698 assert(FirstBB->getParent() == LastBB->getParent() &&
699 "FirstBB and LastBB from different regions");
700#ifndef NDEBUG
701 bool InSingleSuccChain = false;
702 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
703 InSingleSuccChain |= (Succ == LastBB);
704 assert(InSingleSuccChain &&
705 "LastBB unreachable from FirstBB in single-successor chain");
706#endif
707 auto Blocks = to_vector(
709 auto *LastIt = find(Blocks, LastBB);
710 assert(LastIt != Blocks.end() &&
711 "LastBB unreachable from FirstBB in depth-first traversal");
712 Blocks.erase(std::next(LastIt), Blocks.end());
713 return Blocks;
714}
715
717 for (VPRecipeBase &R : *Plan.getVectorPreheader())
719 return cast<VPInstruction>(&R);
720 return nullptr;
721}
722
724 const VPDominatorTree &VPDT) {
725 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
726 if (!VPBB)
727 return false;
728
729 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
730 // VPBB as its entry, i.e., free of predecessors.
731 if (auto *R = VPBB->getParent())
732 return !R->isReplicator() && !VPBB->hasPredecessors();
733
734 // A header dominates its second predecessor (the latch), with the other
735 // predecessor being the preheader
736 return VPB->getPredecessors().size() == 2 &&
737 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
738}
739
741 const VPDominatorTree &VPDT) {
742 // A latch has a header as its last successor, with its other successors
743 // leaving the loop. A preheader OTOH has a header as its first (and only)
744 // successor.
745 return VPB->getNumSuccessors() >= 2 &&
747}
748
749std::pair<VPBasicBlock *, VPBasicBlock *>
751 auto *Header = cast<VPBasicBlock>(
752 Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
753 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
754 return {Header, Latch};
755}
756
760
761std::optional<MemoryLocation>
763 auto *M = dyn_cast<VPIRMetadata>(&R);
764 if (!M)
765 return std::nullopt;
767 // Populate noalias metadata from VPIRMetadata.
768 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
769 Loc.AATags.NoAlias = NoAliasMD;
770 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
771 Loc.AATags.Scope = AliasScopeMD;
772 return Loc;
773}
774
776 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
777 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
778 assert(CanIV && "Expected loop region to have a canonical IV");
779
780 VPSymbolicValue &VFxUF = Plan.getVFxUF();
781
782 // Check if \p Step matches the expected increment step, accounting for
783 // materialization of VFxUF and UF.
784 auto IsIncrementStep = [&](VPValue *Step) -> bool {
785 if (!VFxUF.isMaterialized())
786 return Step == &VFxUF;
787
788 VPSymbolicValue &UF = Plan.getUF();
789 if (!UF.isMaterialized())
790 return Step == &UF ||
791 match(Step, m_c_Mul(m_Specific(&Plan.getUF()),
793
794 // Alias masking: step is number of active lanes of a dependence mask.
795 if (match(Step, m_ZExtOrTruncOrSelf(
797 return true;
798
799 unsigned ConcreteUF = Plan.getConcreteUF();
800 // Fixed VF: step is just the concrete UF.
801 if (match(Step, m_SpecificInt(ConcreteUF)))
802 return true;
803
804 // Scalable VF: step involves VScale.
805 if (ConcreteUF == 1)
807 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF),
809 return true;
810 // mul(VScale, ConcreteUF) may have been simplified to
811 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
812 return isPowerOf2_32(ConcreteUF) &&
814 m_SpecificInt(Log2_32(ConcreteUF))));
815 };
816
817 VPInstruction *Increment = nullptr;
818 for (VPUser *U : CanIV->users()) {
819 VPValue *Step;
820 if (isa<VPInstruction>(U) &&
821 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
822 IsIncrementStep(Step)) {
823 assert(!Increment && "There must be a unique increment");
825 }
826 }
827
828 assert((!VFxUF.isMaterialized() || Increment) &&
829 "After materializing VFxUF, an increment must exist");
830 assert((!Increment ||
831 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
832 "NUW flag in region and increment must match");
833 return Increment;
834}
835
836/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
837/// inserted for predicated reductions or tail folding.
839 VPValue *BackedgeVal = PhiR->getBackedgeValue();
840 if (auto *Res =
842 return Res;
843
844 // Look through selects inserted for tail folding or predicated reductions.
845 VPRecipeBase *SelR =
846 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
847 if (!SelR)
848 return nullptr;
851}
852
855 SmallVector<const VPValue *> WorkList = {V};
856
857 while (!WorkList.empty()) {
858 const VPValue *Cur = WorkList.pop_back_val();
859 if (!Seen.insert(Cur).second)
860 continue;
861
862 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
863 // Skip blends that use V only through a compare by checking if any incoming
864 // value was already visited.
865 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
866 [&](unsigned I) {
867 return Seen.contains(Blend->getIncomingValue(I));
868 }))
869 continue;
870
871 for (VPUser *U : Cur->users()) {
872 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
873 if (InterleaveR->getAddr() == Cur)
874 return true;
875 if (auto *RepR = dyn_cast<VPReplicateRecipe>(U)) {
876 if (RepR->getOpcode() == Instruction::Load &&
877 RepR->getOperand(0) == Cur)
878 return true;
879 if (RepR->getOpcode() == Instruction::Store &&
880 RepR->getOperand(1) == Cur)
881 return true;
882 }
884 if (MemR->getAddr() == Cur && MemR->isConsecutive())
885 return true;
886 }
887 }
888
889 // The legacy cost model only supports scalarization loads/stores with phi
890 // addresses, if the phi is directly used as load/store address. Don't
891 // traverse further for Blends.
892 if (Blend)
893 continue;
894
895 // Only traverse further through users that also define a value (and can
896 // thus have their own users walked).
897 for (VPUser *U : Cur->users())
898 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
899 WorkList.push_back(SDR);
900 }
901 return false;
902}
903
904/// Try to find a loop-invariant IR value for \p S in the plan's entry block
905/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
906/// if no reusable IR value is found.
907VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
909 return nullptr;
910 VPlan &Plan = Builder.getPlan();
911 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
912 for (Value *V : SE.getSCEVValues(S)) {
913 // Only reuse instructions in the plan's entry block, or, when a
914 // DominatorTree is available, any instruction that dominates it.
915 // Instructions in sibling branches may not dominate the entry block.
916 auto *I = dyn_cast<Instruction>(V);
917 if (!I)
918 return Plan.getOrAddLiveIn(V);
919 if (!SE.DT.dominates(I->getParent(), PH))
920 continue;
921 SmallVector<Instruction *> DropPoisonGeneratingInsts;
922 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
923 continue;
924 for (Instruction *DropI : DropPoisonGeneratingInsts)
926 return Plan.getOrAddLiveIn(V);
927 }
928 return nullptr;
929}
930
932 if (VPValue *V = tryToReuseIRValue(S))
933 return V;
934
935 switch (S->getSCEVType()) {
936 case scConstant:
937 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
938 case scUnknown:
939 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
940 case scVScale:
941 return Builder.createNaryOp(VPInstruction::VScale, {}, S->getType());
942 case scAddExpr:
943 case scMulExpr: {
944 if (S->getType()->isPointerTy())
945 return nullptr;
946 auto *NAry = cast<SCEVNAryExpr>(S);
947 unsigned Opcode =
948 S->getSCEVType() == scAddExpr ? Instruction::Add : Instruction::Mul;
949 // Iterate in reverse so that constants are emitted last.
951 for (const SCEVUse &Op : reverse(NAry->operands())) {
952 VPValue *OpV = tryToExpand(Op);
953 if (!OpV)
954 return nullptr;
955 Ops.push_back(OpV);
956 }
957 VPIRFlags::WrapFlagsTy WrapFlags(NAry->hasNoUnsignedWrap(),
958 NAry->hasNoSignedWrap());
959 VPValue *Result = Ops.front();
960 for (VPValue *Op : drop_begin(Ops))
961 Result = Builder.createOverflowingOp(Opcode, {Result, Op}, WrapFlags, DL);
962 return Result;
963 }
964 default:
965 return nullptr;
966 }
967}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static constexpr Value * getValue(Ty &ValueOrUse)
static Value * getOpcode(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
#define I(x, y, z)
Definition MD5.cpp:57
This file provides utility analysis objects describing memory locations.
This file implements the TypeSwitch template, which mimics a switch() statement whose cases are type ...
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
static bool propagatesPoisonFromRecipeOp(const VPRecipeBase *R)
Returns true if R propagates poison from any operand to its result.
static bool preservesUniformity(unsigned Opcode)
Returns true if Opcode preserves uniformity, i.e., if all operands are uniform, the result will also ...
static bool poisonGuaranteesUB(const VPValue *V)
Returns true if V being poison is guaranteed to trigger UB because it propagates to the address of a ...
static const uint32_t IV[8]
Definition blake3_impl.h:83
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags none()
bool isCast() const
bool isBinaryOp() const
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1069
Representation for a specific memory location.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEV * getPredicatedSCEV(const SCEV *Expr)
Returns the rewritten SCEV for Expr in the context of the current SCEV predicate.
static LLVM_ABI void dropPoisonGeneratingAnnotationsAndReinfer(ScalarEvolution &SE, Instruction *I)
Drop poison-generating flags from I, then try re-infer via SCEV.
This class represents an analyzed expression in the program.
static constexpr auto FlagAnyWrap
static constexpr auto FlagNSW
SCEVTypes getSCEVType() const
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getUDivExpr(SCEVUse LHS, SCEVUse RHS)
Get a canonical unsigned division expression, or something simpler if possible.
LLVM_ABI const SCEV * getAbsExpr(const SCEV *Op, bool IsNSW)
LLVM_ABI const SCEV * getURemExpr(SCEVUse LHS, SCEVUse RHS)
Represents an unsigned remainder expression based on unsigned division.
LLVM_ABI const SCEV * getSMinExpr(SCEVUse LHS, SCEVUse RHS)
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
LLVM_ABI const SCEV * getConstant(ConstantInt *V)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI const SCEV * getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI const SCEV * getUMaxExpr(SCEVUse LHS, SCEVUse RHS)
const SCEV * getMinusOne(Type *Ty)
Return a SCEV for the constant -1 of a specific type.
LLVM_ABI const SCEV * getCouldNotCompute()
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
LLVM_ABI const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
const SCEV * getPowerOfTwo(Type *Ty, unsigned Power)
Return a SCEV for the constant Power of two.
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI const SCEV * getSMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI bool canReuseInstruction(const SCEV *S, Instruction *I, SmallVectorImpl< Instruction * > &DropPoisonGeneratingInsts)
Check whether it is poison-safe to represent the expression S using the instruction I.
LLVM_ABI const SCEV * getGEPExpr(GEPOperator *GEP, ArrayRef< SCEVUse > IndexExprs)
Returns an expression for a GEP.
LLVM_ABI const SCEV * getUMinExpr(SCEVUse LHS, SCEVUse RHS, bool Sequential=false)
LLVM_ABI const SCEV * getTruncateOrSignExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
Definition TypeSwitch.h:89
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
Definition TypeSwitch.h:98
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4404
iterator end()
Definition VPlan.h:4441
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4492
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:266
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:639
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4470
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:94
VPRegionBlock * getParent()
Definition VPlan.h:186
size_t getNumSuccessors() const
Definition VPlan.h:237
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:222
VPlan * getPlan()
Definition VPlan.cpp:211
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:216
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:227
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:211
static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
static VPBasicBlock * getPlainCFGMiddleBlock(const VPlan &Plan)
Returns the middle block of Plan in plain CFG form (before regions are formed).
static bool isHeader(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop header, based on regions or VPDT in their absence.
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:324
static std::pair< VPBasicBlock *, VPBasicBlock * > getPlainCFGHeaderAndLatch(const VPlan &Plan)
Returns the header and latch of the outermost loop of Plan in plain CFG form (before regions are form...
static SmallVector< VPBasicBlock * > blocksInSingleSuccessorChainBetween(VPBasicBlock *FirstBB, VPBasicBlock *LastBB)
Returns the blocks between FirstBB and LastBB, where FirstBB to LastBB forms a single-sucessor chain.
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Definition VPlan.h:4182
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:4014
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2483
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1226
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1315
@ VScale
Returns the value for vscale.
Definition VPlan.h:1348
unsigned getOpcode() const
Definition VPlan.h:1417
bool isVectorToScalar() const
Returns true if this VPInstruction produces a scalar value from a vector, e.g.
bool isSingleScalar() const
Returns true if this VPInstruction's operands are single scalars and the result is also a single scal...
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:402
A recipe for handling reduction phis.
Definition VPlan.h:2864
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4614
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4690
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4739
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4726
VPValues defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:215
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3398
unsigned getOpcode() const
Definition VPlan.h:3485
VPValue * tryToExpand(const SCEV *S)
Try to expand S into recipes and live-ins using the builder.
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4249
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:609
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:384
operand_range operands()
Definition VPlanValue.h:457
unsigned getNumOperands() const
Definition VPlanValue.h:424
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:130
user_range users()
Definition VPlanValue.h:157
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1878
A recipe for handling GEP instructions.
Definition VPlan.h:2206
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2623
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1817
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4762
VPBasicBlock * getEntry()
Definition VPlan.h:4858
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:4921
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:4961
VPValue * getBackedgeTakenCount() const
Definition VPlan.h:4948
VPIRValue * getOrAddLiveIn(Value *V)
Gets the live-in VPIRValue for V or adds a new live-in (if none exists yet) for V.
Definition VPlan.h:5035
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1068
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5013
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4863
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:4958
bool hasScalarVFOnly() const
Definition VPlan.h:5003
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4901
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:4954
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
An efficient, type-erasing, non-owning reference to a callable.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
auto m_ZExtOrTruncOrSelf(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_commutative_match< Instruction::And, Op0_t, Op1_t > m_c_BinaryAnd(const Op0_t &Op0, const Op1_t &Op1)
Match a binary AND operation.
VPInstruction_match< VPInstruction::AnyOf > m_AnyOf()
VPInstruction_match< VPInstruction::BranchOnTwoConds > m_BranchOnTwoConds()
canonical_widen_iv_match m_CanonicalWidenIV()
VPInstruction_match< VPInstruction::ActiveLaneMask, Op0_t, Op1_t, Op2_t > m_ActiveLaneMask(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
auto m_GetElementPtr(const Op0_t &Op0, const Op1_t &Op1)
canonical_iv_match m_CanonicalIV()
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
auto m_DerivedIV(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
static VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
auto m_ScalarIVSteps(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
VPInstruction_match< VPInstruction::Reverse, Op0_t > m_Reverse(const Op0_t &Op0)
bool isSingleScalar(const VPValue *VPV)
Returns true if VPV is a single scalar, either because it produces the same value for all lanes or on...
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr)
Get or create a VPValue that corresponds to the expansion of Expr.
bool cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking=false)
Return true if we do not know how to (mechanically) hoist or sink R.
VPBasicBlock * getFirstLoopHeader(VPlan &Plan, VPDominatorTree &VPDT)
Returns the header block of the first, top-level loop, or null if none exist.
bool isAddressSCEVForCost(const SCEV *Addr, ScalarEvolution &SE, const Loop *L)
Returns true if Addr is an address SCEV that can be passed to TTI::getAddressComputationCost,...
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used.
VPInstruction * findComputeReductionResult(VPReductionPHIRecipe *PhiR)
Find the ComputeReductionResult recipe for PhiR, looking through selects inserted for predicated redu...
VPInstruction * findCanonicalIVIncrement(VPlan &Plan)
Find the canonical IV increment of Plan's vector loop region.
std::optional< MemoryLocation > getMemoryLocation(const VPRecipeBase &R)
Return a MemoryLocation for R with noalias metadata populated from R, if the recipe is supported and ...
bool onlyFirstLaneUsed(const VPValue *Def)
Returns true if only the first lane of Def is used.
VPValue * findIncomingAliasMask(const VPlan &Plan)
Finds the incoming alias-mask within the vector preheader.
VPSingleDefRecipe * findHeaderMask(VPlan &Plan)
Collect the header mask with the pattern: (ICMP_ULE, WideCanonicalIV, backedge-taken-count) Note: If ...
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
bool isUniformAcrossVFsAndUFs(const VPValue *V)
Checks if V is uniform across all VF lanes and UF parts.
bool isUsedByLoadStoreAddress(const VPValue *V)
Returns true if V is used as part of the address of another load or store.
LLVM_ABI_FOR_TEST std::optional< VPValue * > getRecipesForUncountableExit(SmallVectorImpl< VPInstruction * > &Recipes, SmallVectorImpl< VPInstruction * > &GEPs, VPBasicBlock *LatchVPBB)
Returns the VPValue representing the uncountable exit comparison used by AnyOf if the recipes it depe...
GEPNoWrapFlags getGEPFlagsForPtr(VPValue *Ptr)
Returns the GEP nowrap flags for Ptr, looking through pointer casts mirroring Value::stripPointerCast...
const SCEV * getSCEVExprForVPValue(const VPValue *V, PredicatedScalarEvolution &PSE, const Loop *L=nullptr)
Return the SCEV expression for V.
unsigned getVFScaleFactor(VPRecipeBase *R)
Get the VF scaling factor applied to the recipe's output, if the recipe has one.
bool isHeaderMask(const VPValue *V, const VPlan &Plan)
Return true if V is a header mask in Plan.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1764
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1738
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< df_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_depth_first_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order.
Definition VPlanCFG.h:253
iterator_range< df_iterator< VPBlockDeepTraversalWrapper< VPBlockBase * > > > vp_depth_first_deep(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order while traversing t...
Definition VPlanCFG.h:288
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1745
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1752
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2018
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1771
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:305
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
@ Default
The result value is uniform if and only if all operands are uniform.
Definition Uniformity.h:20
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
SCEVUseT< const SCEV * > SCEVUse
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:286
bool isMaterialized() const
Returns true if this symbolic value has been materialized.
Definition VPlanValue.h:297