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
20using namespace llvm;
21using namespace llvm::VPlanPatternMatch;
22using namespace llvm::SCEVPatternMatch;
23
25 return all_of(Def->users(),
26 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
27}
28
30 return all_of(Def->users(),
31 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
32}
33
35 return all_of(Def->users(),
36 [Def](const VPUser *U) { return U->usesScalars(Def); });
37}
38
40 if (auto *E = dyn_cast<SCEVConstant>(Expr))
41 return Plan.getOrAddLiveIn(E->getValue());
42 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
43 // value. Otherwise the value may be defined in a loop and using it directly
44 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
45 // form.
46 auto *U = dyn_cast<SCEVUnknown>(Expr);
47 if (U && !isa<Instruction>(U->getValue()))
48 return Plan.getOrAddLiveIn(U->getValue());
49 auto *Expanded = new VPExpandSCEVRecipe(Expr);
50 Plan.getEntry()->appendRecipe(Expanded);
51 return Expanded;
52}
53
54bool vputils::isHeaderMask(const VPValue *V, const VPlan &Plan) {
56 return true;
57
58 auto IsWideCanonicalIV = [](VPValue *A) {
62 };
63
64 VPValue *A, *B;
65
66 auto m_CanonicalScalarIVSteps = m_ScalarIVSteps(
69 m_One(), m_Specific(&Plan.getVF()));
70
72 return B == Plan.getTripCount() &&
73 (match(A, m_CanonicalScalarIVSteps) || IsWideCanonicalIV(A));
74
75 // For scalar plans, the header mask uses the scalar steps.
76 if (match(V, m_ICmp(m_CanonicalScalarIVSteps,
78 assert(Plan.hasScalarVFOnly() &&
79 "Non-scalar VF using scalar IV steps for header mask?");
80 return true;
81 }
82
83 auto MaskMatch = m_ICmp(m_VPValue(A), m_VPValue(B));
84 return (match(V, m_CombineOr(MaskMatch, m_Reverse(MaskMatch)))) &&
85 IsWideCanonicalIV(A) && B == Plan.getBackedgeTakenCount();
86}
87
88/// Returns true if \p R propagates poison from any operand to its result.
92 [](const VPRecipeBase *) { return true; })
93 .Case([](const VPReplicateRecipe *Rep) {
94 // GEP and casts propagate poison from all operands.
95 unsigned Opcode = Rep->getOpcode();
96 return Opcode == Instruction::GetElementPtr ||
97 Instruction::isCast(Opcode);
98 })
99 .Default([](const VPRecipeBase *) { return false; });
100}
101
102/// Returns true if \p V being poison is guaranteed to trigger UB because it
103/// propagates to the address of a memory recipe.
104static bool poisonGuaranteesUB(const VPValue *V) {
107
108 Worklist.push_back(V);
109
110 while (!Worklist.empty()) {
111 const VPValue *Current = Worklist.pop_back_val();
112 if (!Visited.insert(Current).second)
113 continue;
114
115 for (VPUser *U : Current->users()) {
116 // Check if Current is used as an address operand for load/store.
118 if (MemR->getAddr() == Current)
119 return true;
120 continue;
121 }
122 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
123 unsigned Opcode = Rep->getOpcode();
124 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
125 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
126 return true;
127 }
128
129 // Check if poison propagates through this recipe to any of its users.
130 auto *R = cast<VPRecipeBase>(U);
131 for (const VPValue *Op : R->operands()) {
132 if (Op == Current && propagatesPoisonFromRecipeOp(R)) {
133 Worklist.push_back(R->getVPSingleValue());
134 break;
135 }
136 }
137 }
138 }
139
140 return false;
141}
142
144 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
145 // casts to find a root GEP VPInstruction.
146 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
147 unsigned Opcode = PtrVPI->getOpcode();
148 if (Opcode == Instruction::GetElementPtr) {
149 if (any_of(drop_begin(PtrVPI->operands()),
150 [](VPValue *Op) { return !match(Op, m_ZeroInt()); }))
151 return PtrVPI->getGEPNoWrapFlags();
152 Ptr = PtrVPI->getOperand(0);
153 continue;
154 }
155 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
156 break;
157 Ptr = PtrVPI->getOperand(0);
158 }
159 return GEPNoWrapFlags::none();
160}
161
164 const Loop *L) {
165 ScalarEvolution &SE = *PSE.getSE();
167 Value *LiveIn = V->getUnderlyingValue();
168 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
169 return SE.getSCEV(LiveIn);
170 return SE.getCouldNotCompute();
171 }
172
173 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
174 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
175 "RegionValue must be canonical IV");
176 if (!L)
177 return SE.getCouldNotCompute();
178 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
180 }
181
182 // Helper to create SCEVs for binary and unary operations.
183 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
184 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
185 -> const SCEV * {
187 for (VPValue *Op : Ops) {
188 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
190 return SE.getCouldNotCompute();
191 SCEVOps.push_back(S);
192 }
193 return CreateFn(SCEVOps);
194 };
195
196 VPValue *LHSVal, *RHSVal;
197 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
198 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
199 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
200 });
201 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
202 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
203 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
204 });
205 if (match(V, m_Not(m_VPValue(LHSVal)))) {
206 // not X = xor X, -1 = -1 - X
207 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
208 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
209 });
210 }
211 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
212 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
213 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
214 });
215 if (match(V,
217 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
218 return SE.getUDivExpr(Ops[0], Ops[1]);
219 });
220 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
221 const APInt *Mask;
222 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
223 (*Mask + 1).isPowerOf2())
224 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
225 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
226 });
227 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
228 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
229 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
230 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
231 return SE.getTruncateExpr(Ops[0], DestTy);
232 });
233 }
234 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
235 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
236 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
237 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
238 return SE.getZeroExtendExpr(Ops[0], DestTy);
239 });
240 }
241 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
242 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
243 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
244
245 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
246 // onto the operands before computing the subtraction.
247 VPValue *SubLHS, *SubRHS;
248 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
249 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
250 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
251 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
252 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
254 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
255 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
256 }
257
258 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
259 return SE.getSignExtendExpr(Ops[0], DestTy);
260 });
261 }
262 if (match(V,
264 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
265 return SE.getUMaxExpr(Ops[0], Ops[1]);
266 });
267 if (match(V,
269 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
270 return SE.getSMaxExpr(Ops[0], Ops[1]);
271 });
272 if (match(V,
274 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
275 return SE.getUMinExpr(Ops[0], Ops[1]);
276 });
277 if (match(V,
279 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
280 return SE.getSMinExpr(Ops[0], Ops[1]);
281 });
283 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
284 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
285 // not proof that the input is never INT_MIN, nor that poison reaches
286 // UB. Do not translate it to SCEV's global IsNSW flag.
287 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
288 });
289
291 Type *SourceElementType;
292 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
293 const SCEV *GEPExpr = CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
294 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
295 });
296 return PSE.getPredicatedSCEV(GEPExpr);
297 }
298
299 // TODO: Support constructing SCEVs for more recipes as needed.
300 const VPRecipeBase *DefR = V->getDefiningRecipe();
301 const SCEV *Expr =
303 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
304 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
305 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
306 if (!L || isa<SCEVCouldNotCompute>(Step))
307 return SE.getCouldNotCompute();
308 const SCEV *Start =
309 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
310 const SCEV *AddRec =
311 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
312 if (R->getTruncInst())
313 return SE.getTruncateExpr(AddRec, R->getScalarType());
314 return AddRec;
315 })
316 .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
317 const SCEV *Start =
318 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
319 if (!L || isa<SCEVCouldNotCompute>(Start))
320 return SE.getCouldNotCompute();
321 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
322 if (isa<SCEVCouldNotCompute>(Step))
323 return SE.getCouldNotCompute();
324 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
325 })
326 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
327 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
328 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
329 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
330 if (any_of(ArrayRef({Start, IV, Scale}),
332 return SE.getCouldNotCompute();
333
334 return SE.getAddExpr(
335 SE.getTruncateOrSignExtend(Start, IV->getType()),
336 SE.getMulExpr(
337 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
338 })
339 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
340 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
341 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
343 return SE.getCouldNotCompute();
344 return SE.getTruncateOrSignExtend(IV, Step->getType());
345 })
346 .Default(
347 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
348
349 return PSE.getPredicatedSCEV(Expr);
350}
351
353 const Loop *L) {
354 // If address is an SCEVAddExpr, we require that all operands must be either
355 // be invariant or a (possibly sign-extend) affine AddRec.
356 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
357 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
358 return SE.isLoopInvariant(Op, L) ||
359 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
360 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
361 });
362 }
363
364 // Otherwise, check if address is loop invariant or an affine add recurrence.
365 return SE.isLoopInvariant(Addr, L) ||
367}
368
369/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
370/// uniform, the result will also be uniform.
371static bool preservesUniformity(unsigned Opcode) {
372 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
373 return true;
374 switch (Opcode) {
375 case Instruction::Freeze:
376 case Instruction::GetElementPtr:
377 case Instruction::ICmp:
378 case Instruction::FCmp:
379 case Instruction::Select:
384 return true;
385 default:
386 return false;
387 }
388}
389
391 // Live-in, symbolic and region-values represent single-scalar values.
393 return true;
394
395 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
396 const VPRegionBlock *RegionOfR = Rep->getRegion();
397 // Don't consider recipes in replicate regions as uniform yet; their first
398 // lane cannot be accessed when executing the replicate region for other
399 // lanes.
400 if (RegionOfR && RegionOfR->isReplicator())
401 return false;
402 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
403 all_of(Rep->operands(), isSingleScalar));
404 }
407 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
408 return preservesUniformity(WidenR->getOpcode()) &&
409 all_of(WidenR->operands(), isSingleScalar);
410 }
411 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
412 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
413 (preservesUniformity(VPI->getOpcode()) &&
414 all_of(VPI->operands(), isSingleScalar));
415 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
416 return !RR->isPartialReduction();
418 VPV))
419 return true;
420 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
421 return Expr->isSingleScalar();
422
423 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
424 return isa<VPExpandSCEVRecipe>(VPV);
425}
426
428 // Live-ins and region values are uniform.
430 return true;
431
432 const VPRecipeBase *R = V->getDefiningRecipe();
433 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
434 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
435 if (VPBB) {
436 if ((VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
437 if (match(V->getDefiningRecipe(),
439 return false;
440 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
441 }
442 }
443
445 .Case([](const VPDerivedIVRecipe *R) { return true; })
446 .Case([](const VPReplicateRecipe *R) {
447 // Be conservative about side-effects, except for the
448 // known-side-effecting assumes and stores, which we know will be
449 // uniform.
450 return R->isSingleScalar() &&
451 (!R->mayHaveSideEffects() ||
452 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
453 all_of(R->operands(), isUniformAcrossVFsAndUFs);
454 })
455 .Case([](const VPWidenRecipe *R) {
456 return preservesUniformity(R->getOpcode()) &&
457 all_of(R->operands(), isUniformAcrossVFsAndUFs);
458 })
459 .Case([](const VPPhi *) {
460 // Bail out on VPPhi, as we can end up in infinite cycles.
461 return false;
462 })
463 .Case([](const VPInstruction *VPI) {
464 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
467 })
468 .Case([](const VPWidenCastRecipe *R) {
469 // A cast is uniform according to its operand.
470 return isUniformAcrossVFsAndUFs(R->getOperand(0));
471 })
472 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
473 // unless proven otherwise.
474 return false;
475 });
476}
477
479 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
480 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
481 return VPBlockUtils::isHeader(VPB, VPDT);
482 });
483 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
484}
485
487 if (!R)
488 return 1;
489 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
490 return RR->getVFScaleFactor();
491 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
492 return RR->getVFScaleFactor();
493 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
494 return ER->getVFScaleFactor();
495 assert(
496 (!isa<VPInstruction>(R) || cast<VPInstruction>(R)->getOpcode() !=
498 "getting scaling factor of reduction-start-vector not implemented yet");
499 return 1;
500}
501
502bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
503 // Assumes don't alias anything or throw; as long as they're guaranteed to
504 // execute, they're safe to hoist. They should however not be sunk, as it
505 // would destroy information.
507 return Sinking;
508 // TODO: Relax checks in the future, e.g. we could also hoist reads, if their
509 // memory location is not modified in the vector loop.
510 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
511 return true;
512 // Allocas cannot be hoisted.
513 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
514 return RepR && RepR->getOpcode() == Instruction::Alloca;
515}
516
517std::optional<VPValue *>
520 VPBasicBlock *LatchVPBB) {
521 // Given a plain CFG VPlan loop with countable latch exiting block
522 // \p LatchVPBB, we're looking to match the recipes contributing to the
523 // uncountable exit condition comparison (here, vp<%4>) back to either
524 // live-ins or the address nodes for the load used as part of the uncountable
525 // exit comparison so that we can either move them within the loop, or copy
526 // them to the preheader depending on the chosen method for dealing with
527 // stores in uncountable exit loops.
528 //
529 // Currently, the address of the load is restricted to a GEP with 2 operands
530 // and a live-in base address. This constraint may be relaxed later.
531 //
532 // VPlan ' for UF>=1' {
533 // Live-in vp<%0> = VF * UF
534 // Live-in vp<%1> = vector-trip-count
535 // Live-in ir<20> = original trip-count
536 //
537 // ir-bb<entry>:
538 // Successor(s): scalar.ph, vector.ph
539 //
540 // vector.ph:
541 // Successor(s): for.body
542 //
543 // for.body:
544 // EMIT vp<%2> = phi ir<0>, vp<%index.next>
545 // EMIT-SCALAR ir<%iv> = phi [ ir<0>, vector.ph ], [ ir<%iv.next>, for.inc ]
546 // EMIT ir<%uncountable.addr> = getelementptr inbounds nuw ir<%pred>,ir<%iv>
547 // EMIT ir<%uncountable.val> = load ir<%uncountable.addr>
548 // EMIT ir<%uncountable.cond> = icmp sgt ir<%uncountable.val>, ir<500>
549 // EMIT vp<%3> = masked-cond ir<%uncountable.cond>
550 // Successor(s): for.inc
551 //
552 // for.inc:
553 // EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
554 // EMIT ir<%countable.cond> = icmp eq ir<%iv.next>, ir<20>
555 // EMIT vp<%index.next> = add nuw vp<%2>, vp<%0>
556 // EMIT vp<%4> = any-of ir<%3>
557 // EMIT vp<%5> = icmp eq vp<%index.next>, vp<%1>
558 // EMIT vp<%6> = or vp<%4>, vp<%5>
559 // EMIT branch-on-cond vp<%6>
560 // Successor(s): middle.block, for.body
561 //
562 // middle.block:
563 // Successor(s): ir-bb<exit>, scalar.ph
564 //
565 // ir-bb<exit>:
566 // No successors
567 //
568 // scalar.ph:
569 // }
570
571 // Find the uncountable loop exit condition.
572 VPValue *UncountableCondition = nullptr;
573 if (!match(LatchVPBB->getTerminator(),
575 m_AnyOf(m_VPValue(UncountableCondition)), m_VPValue()))))
576 return std::nullopt;
577
579 Worklist.push_back(UncountableCondition);
580 while (!Worklist.empty()) {
581 VPValue *V = Worklist.pop_back_val();
582
583 // Any value defined outside the loop does not need to be copied.
584 if (V->isDefinedOutsideLoopRegions())
585 continue;
586
587 // FIXME: Remove the single user restriction; it's here because we're
588 // starting with the simplest set of loops we can, and multiple
589 // users means needing to add PHI nodes in the transform.
590 if (V->getNumUsers() > 1)
591 return std::nullopt;
592
593 VPValue *Op1, *Op2;
594 // Walk back through recipes until we find at least one load from memory.
595 if (match(V, m_ICmp(m_VPValue(Op1), m_VPValue(Op2)))) {
596 Worklist.push_back(Op1);
597 Worklist.push_back(Op2);
598 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
600 VPRecipeBase *GepR = Op1->getDefiningRecipe();
601 // Only matching base + single offset term for now.
602 if (GepR->getNumOperands() != 2)
603 return std::nullopt;
604 // Matching a GEP with a loop-invariant base ptr.
606 m_LiveIn(), m_VPValue())))
607 return std::nullopt;
608 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
609 Recipes.push_back(cast<VPInstruction>(GepR));
610 GEPs.push_back(cast<VPInstruction>(GepR));
612 m_VPValue(Op1)))) {
613 Worklist.push_back(Op1);
614 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
615 } else
616 return std::nullopt;
617 }
618
619 // If we couldn't match anything, don't return the condition. It may be
620 // defined outside the loop.
621 if (Recipes.empty() || GEPs.empty())
622 return std::nullopt;
623
624 return UncountableCondition;
625}
626
628 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
629 SmallVector<VPValue *> WideCanonicalIVs;
630 auto *WideCanonicalIV = vputils::findUserOf<VPWidenCanonicalIVRecipe>(
631 LoopRegion->getCanonicalIV());
632 assert(count_if(LoopRegion->getCanonicalIV()->users(),
634 "Must have at most one VPWideCanonicalIVRecipe");
635 if (WideCanonicalIV)
636 WideCanonicalIVs.push_back(WideCanonicalIV);
637
638 // Also include VPWidenIntOrFpInductionRecipes that represent a widened
639 // version of the canonical induction.
640 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
641 for (VPRecipeBase &Phi : HeaderVPBB->phis()) {
642 auto *WidenOriginalIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi);
643 if (WidenOriginalIV && WidenOriginalIV->isCanonical())
644 WideCanonicalIVs.push_back(WidenOriginalIV);
645 }
646
647 // Walk users of wide canonical IVs and find the single compare of the form
648 // (ICMP_ULE, WideCanonicalIV, backedge-taken-count).
649 VPSingleDefRecipe *HeaderMask = nullptr;
650 for (auto *Wide : WideCanonicalIVs) {
651 for (VPUser *U : Wide->users()) {
652 auto *VPI = dyn_cast<VPInstruction>(U);
653 if (!VPI || !vputils::isHeaderMask(VPI, Plan))
654 continue;
655
656 assert(VPI->getOperand(0) == Wide &&
657 "WidenCanonicalIV must be the first operand of the compare");
658 assert(!HeaderMask && "Multiple header masks found?");
659 HeaderMask = VPI;
660 }
661 }
662 return HeaderMask;
663}
664
667 VPBasicBlock *LastBB) {
668 assert(FirstBB->getParent() == LastBB->getParent() &&
669 "FirstBB and LastBB from different regions");
670#ifndef NDEBUG
671 bool InSingleSuccChain = false;
672 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
673 InSingleSuccChain |= (Succ == LastBB);
674 assert(InSingleSuccChain &&
675 "LastBB unreachable from FirstBB in single-successor chain");
676#endif
677 auto Blocks = to_vector(
679 auto *LastIt = find(Blocks, LastBB);
680 assert(LastIt != Blocks.end() &&
681 "LastBB unreachable from FirstBB in depth-first traversal");
682 Blocks.erase(std::next(LastIt), Blocks.end());
683 return Blocks;
684}
685
687 const VPDominatorTree &VPDT) {
688 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
689 if (!VPBB)
690 return false;
691
692 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
693 // VPBB as its entry, i.e., free of predecessors.
694 if (auto *R = VPBB->getParent())
695 return !R->isReplicator() && !VPBB->hasPredecessors();
696
697 // A header dominates its second predecessor (the latch), with the other
698 // predecessor being the preheader
699 return VPB->getPredecessors().size() == 2 &&
700 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
701}
702
704 const VPDominatorTree &VPDT) {
705 // A latch has a header as its last successor, with its other successors
706 // leaving the loop. A preheader OTOH has a header as its first (and only)
707 // successor.
708 return VPB->getNumSuccessors() >= 2 &&
710}
711
712std::pair<VPBasicBlock *, VPBasicBlock *>
714 auto *Header = cast<VPBasicBlock>(
715 Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
716 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
717 return {Header, Latch};
718}
719
723
724std::optional<MemoryLocation>
726 auto *M = dyn_cast<VPIRMetadata>(&R);
727 if (!M)
728 return std::nullopt;
730 // Populate noalias metadata from VPIRMetadata.
731 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
732 Loc.AATags.NoAlias = NoAliasMD;
733 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
734 Loc.AATags.Scope = AliasScopeMD;
735 return Loc;
736}
737
739 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
740 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
741 assert(CanIV && "Expected loop region to have a canonical IV");
742
743 VPSymbolicValue &VFxUF = Plan.getVFxUF();
744
745 // Check if \p Step matches the expected increment step, accounting for
746 // materialization of VFxUF and UF.
747 auto IsIncrementStep = [&](VPValue *Step) -> bool {
748 if (!VFxUF.isMaterialized())
749 return Step == &VFxUF;
750
751 VPSymbolicValue &UF = Plan.getUF();
752 if (!UF.isMaterialized())
753 return Step == &UF ||
754 match(Step, m_c_Mul(m_Specific(&Plan.getUF()),
756
757 unsigned ConcreteUF = Plan.getConcreteUF();
758 // Fixed VF: step is just the concrete UF.
759 if (match(Step, m_SpecificInt(ConcreteUF)))
760 return true;
761
762 // Scalable VF: step involves VScale.
763 if (ConcreteUF == 1)
765 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF),
767 return true;
768 // mul(VScale, ConcreteUF) may have been simplified to
769 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
770 return isPowerOf2_32(ConcreteUF) &&
773 m_SpecificInt(Log2_32(ConcreteUF))));
774 };
775
776 VPInstruction *Increment = nullptr;
777 for (VPUser *U : CanIV->users()) {
778 VPValue *Step;
779 if (isa<VPInstruction>(U) &&
780 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
781 IsIncrementStep(Step)) {
782 assert(!Increment && "There must be a unique increment");
784 }
785 }
786
787 assert((!VFxUF.isMaterialized() || Increment) &&
788 "After materializing VFxUF, an increment must exist");
789 assert((!Increment ||
790 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
791 "NUW flag in region and increment must match");
792 return Increment;
793}
794
795/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
796/// inserted for predicated reductions or tail folding.
798 VPValue *BackedgeVal = PhiR->getBackedgeValue();
800 BackedgeVal))
801 return Res;
802
803 // Look through selects inserted for tail folding or predicated reductions.
805 BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
806 if (!SelR)
807 return nullptr;
810}
811
814 SmallVector<const VPValue *> WorkList = {V};
815
816 while (!WorkList.empty()) {
817 const VPValue *Cur = WorkList.pop_back_val();
818 if (!Seen.insert(Cur).second)
819 continue;
820
821 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
822 // Skip blends that use V only through a compare by checking if any incoming
823 // value was already visited.
824 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
825 [&](unsigned I) {
826 return Seen.contains(Blend->getIncomingValue(I));
827 }))
828 continue;
829
830 for (VPUser *U : Cur->users()) {
831 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
832 if (InterleaveR->getAddr() == Cur)
833 return true;
834 if (auto *RepR = dyn_cast<VPReplicateRecipe>(U)) {
835 if (RepR->getOpcode() == Instruction::Load &&
836 RepR->getOperand(0) == Cur)
837 return true;
838 if (RepR->getOpcode() == Instruction::Store &&
839 RepR->getOperand(1) == Cur)
840 return true;
841 }
843 if (MemR->getAddr() == Cur && MemR->isConsecutive())
844 return true;
845 }
846 }
847
848 // The legacy cost model only supports scalarization loads/stores with phi
849 // addresses, if the phi is directly used as load/store address. Don't
850 // traverse further for Blends.
851 if (Blend)
852 continue;
853
854 // Only traverse further through users that also define a value (and can
855 // thus have their own users walked).
856 for (VPUser *U : Cur->users())
857 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
858 WorkList.push_back(SDR);
859 }
860 return false;
861}
862
863VPValue *VPBuilder::VPSCEVExpander::expand(const SCEV *S) {
864 switch (S->getSCEVType()) {
865 case scConstant:
866 return Plan.getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
867 case scUnknown:
868 return Plan.getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
869 case scVScale:
870 return Builder.createNaryOp(VPInstruction::VScale, {}, S->getType());
871 case scMulExpr: {
872 auto *Mul = cast<SCEVMulExpr>(S);
874 for (const SCEVUse &Op : Mul->operands()) {
875 VPValue *OpV = expand(Op);
876 if (!OpV)
877 return nullptr;
878 Ops.push_back(OpV);
879 }
880 VPIRFlags::WrapFlagsTy WrapFlags(Mul->hasNoUnsignedWrap(),
881 Mul->hasNoSignedWrap());
882 // Chain the operands with Mul, matching SCEVExpander behavior of applying
883 // wrap flags to all chained multiplies.
884 VPValue *Result = Ops.front();
885 for (VPValue *Op : drop_begin(Ops))
886 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, Op},
887 WrapFlags, DL);
888 return Result;
889 }
890 default:
891 return nullptr;
892 }
893}
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 Expected< BitVector > expand(StringRef S, StringRef Original)
static constexpr Value * getValue(Ty &ValueOrUse)
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 ...
BinaryOperator * Mul
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
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
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:1080
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.
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)
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 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
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4263
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4338
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4351
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:661
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:93
VPRegionBlock * getParent()
Definition VPlan.h:185
size_t getNumSuccessors() const
Definition VPlan.h:236
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:221
VPlan * getPlan()
Definition VPlan.cpp:211
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:216
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:226
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:210
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:295
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:4038
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:3877
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2442
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1227
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1312
@ VScale
Returns the value for vscale.
Definition VPlan.h:1345
unsigned getOpcode() const
Definition VPlan.h:1410
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:401
A recipe for handling reduction phis.
Definition VPlan.h:2789
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4473
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4549
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4598
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4585
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:3304
unsigned getOpcode() const
Definition VPlan.h:3376
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4108
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:610
An analysis for type-inference for VPValues.
Type * inferScalarType(const VPValue *V)
Infer the type of V. Returns the scalar type of V.
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:455
unsigned getNumOperands() const
Definition VPlanValue.h:422
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:1848
A recipe for handling GEP instructions.
Definition VPlan.h:2175
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2554
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1790
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4621
VPBasicBlock * getEntry()
Definition VPlan.h:4717
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:4780
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:4820
VPValue * getBackedgeTakenCount() const
Definition VPlan.h:4807
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:4894
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1098
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:4872
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4722
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:4817
bool hasScalarVFOnly() const
Definition VPlan.h:4862
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4760
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:4813
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)
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::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)
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)
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()
AllRecipe_commutative_match< Instruction::Or, Op0_t, Op1_t > m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_match< Opcode, Op0_t, Op1_t > m_Binary(const Op0_t &Op0, const Op1_t &Op1)
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)
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
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.
VPSingleDefRecipe * findHeaderMask(VPlan &Plan)
Collect the header mask with the pattern: (ICMP_ULE, WideCanonicalIV, backedge-taken-count) TODO: Int...
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
static VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
Definition VPlanUtils.h:137
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
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
@ Mul
Product of integers.
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