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"
10#include "VPlanAnalysis.h"
11#include "VPlanCFG.h"
12#include "VPlanDominatorTree.h"
13#include "VPlanPatternMatch.h"
14#include "llvm/ADT/TypeSwitch.h"
18
19using namespace llvm;
20using namespace llvm::VPlanPatternMatch;
21using namespace llvm::SCEVPatternMatch;
22
24 return all_of(Def->users(),
25 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
26}
27
29 return all_of(Def->users(),
30 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
31}
32
34 return all_of(Def->users(),
35 [Def](const VPUser *U) { return U->usesScalars(Def); });
36}
37
39 if (auto *E = dyn_cast<SCEVConstant>(Expr))
40 return Plan.getOrAddLiveIn(E->getValue());
41 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
42 // value. Otherwise the value may be defined in a loop and using it directly
43 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
44 // form.
45 auto *U = dyn_cast<SCEVUnknown>(Expr);
46 if (U && !isa<Instruction>(U->getValue()))
47 return Plan.getOrAddLiveIn(U->getValue());
48 auto *Expanded = new VPExpandSCEVRecipe(Expr);
49 Plan.getEntry()->appendRecipe(Expanded);
50 return Expanded;
51}
52
53bool vputils::isHeaderMask(const VPValue *V, const VPlan &Plan) {
55 return true;
56
57 auto IsWideCanonicalIV = [](VPValue *A) {
61 };
62
63 VPValue *A, *B;
64
65 auto m_CanonicalScalarIVSteps = m_ScalarIVSteps(
68 m_One(), m_Specific(&Plan.getVF()));
69
71 return B == Plan.getTripCount() &&
72 (match(A, m_CanonicalScalarIVSteps) || IsWideCanonicalIV(A));
73
74 // For scalar plans, the header mask uses the scalar steps.
75 if (match(V, m_ICmp(m_CanonicalScalarIVSteps,
77 assert(Plan.hasScalarVFOnly() &&
78 "Non-scalar VF using scalar IV steps for header mask?");
79 return true;
80 }
81
82 auto MaskMatch = m_ICmp(m_VPValue(A), m_VPValue(B));
83 return (match(V, m_CombineOr(MaskMatch, m_Reverse(MaskMatch)))) &&
84 IsWideCanonicalIV(A) && B == Plan.getBackedgeTakenCount();
85}
86
87/// Returns true if \p R propagates poison from any operand to its result.
91 [](const VPRecipeBase *) { return true; })
92 .Case([](const VPReplicateRecipe *Rep) {
93 // GEP and casts propagate poison from all operands.
94 unsigned Opcode = Rep->getOpcode();
95 return Opcode == Instruction::GetElementPtr ||
96 Instruction::isCast(Opcode);
97 })
98 .Default([](const VPRecipeBase *) { return false; });
99}
100
101/// Returns true if \p V being poison is guaranteed to trigger UB because it
102/// propagates to the address of a memory recipe.
103static bool poisonGuaranteesUB(const VPValue *V) {
106
107 Worklist.push_back(V);
108
109 while (!Worklist.empty()) {
110 const VPValue *Current = Worklist.pop_back_val();
111 if (!Visited.insert(Current).second)
112 continue;
113
114 for (VPUser *U : Current->users()) {
115 // Check if Current is used as an address operand for load/store.
116 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(U)) {
117 if (MemR->getAddr() == Current)
118 return true;
119 continue;
120 }
121 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
122 unsigned Opcode = Rep->getOpcode();
123 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
124 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
125 return true;
126 }
127
128 // Check if poison propagates through this recipe to any of its users.
129 auto *R = cast<VPRecipeBase>(U);
130 for (const VPValue *Op : R->operands()) {
131 if (Op == Current && propagatesPoisonFromRecipeOp(R)) {
132 Worklist.push_back(R->getVPSingleValue());
133 break;
134 }
135 }
136 }
137 }
138
139 return false;
140}
141
143 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
144 // casts to find a root GEP VPInstruction.
145 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
146 unsigned Opcode = PtrVPI->getOpcode();
147 if (Opcode == Instruction::GetElementPtr) {
148 if (any_of(drop_begin(PtrVPI->operands()),
149 [](VPValue *Op) { return !match(Op, m_ZeroInt()); }))
150 return PtrVPI->getGEPNoWrapFlags();
151 Ptr = PtrVPI->getOperand(0);
152 continue;
153 }
154 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
155 break;
156 Ptr = PtrVPI->getOperand(0);
157 }
158 return GEPNoWrapFlags::none();
159}
160
163 const Loop *L) {
164 ScalarEvolution &SE = *PSE.getSE();
166 Value *LiveIn = V->getUnderlyingValue();
167 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
168 return SE.getSCEV(LiveIn);
169 return SE.getCouldNotCompute();
170 }
171
172 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
173 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
174 "RegionValue must be canonical IV");
175 if (!L)
176 return SE.getCouldNotCompute();
177 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
179 }
180
181 // Helper to create SCEVs for binary and unary operations.
182 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
183 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
184 -> const SCEV * {
186 for (VPValue *Op : Ops) {
187 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
189 return SE.getCouldNotCompute();
190 SCEVOps.push_back(S);
191 }
192 return CreateFn(SCEVOps);
193 };
194
195 VPValue *LHSVal, *RHSVal;
196 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
197 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
198 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
199 });
200 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
201 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
202 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
203 });
204 if (match(V, m_Not(m_VPValue(LHSVal)))) {
205 // not X = xor X, -1 = -1 - X
206 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
207 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
208 });
209 }
210 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
211 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
212 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
213 });
214 if (match(V,
216 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
217 return SE.getUDivExpr(Ops[0], Ops[1]);
218 });
219 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
220 const APInt *Mask;
221 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
222 (*Mask + 1).isPowerOf2())
223 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
224 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
225 });
226 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
227 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
228 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
229 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
230 return SE.getTruncateExpr(Ops[0], DestTy);
231 });
232 }
233 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
234 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
235 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
236 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
237 return SE.getZeroExtendExpr(Ops[0], DestTy);
238 });
239 }
240 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
241 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
242 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
243
244 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
245 // onto the operands before computing the subtraction.
246 VPValue *SubLHS, *SubRHS;
247 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
248 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
249 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
250 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
251 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
253 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
254 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
255 }
256
257 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
258 return SE.getSignExtendExpr(Ops[0], DestTy);
259 });
260 }
261 if (match(V,
263 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
264 return SE.getUMaxExpr(Ops[0], Ops[1]);
265 });
266 if (match(V,
268 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
269 return SE.getSMaxExpr(Ops[0], Ops[1]);
270 });
271 if (match(V,
273 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
274 return SE.getUMinExpr(Ops[0], Ops[1]);
275 });
276 if (match(V,
278 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
279 return SE.getSMinExpr(Ops[0], Ops[1]);
280 });
281
283 Type *SourceElementType;
284 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
285 const SCEV *GEPExpr = CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
286 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
287 });
288 return PSE.getPredicatedSCEV(GEPExpr);
289 }
290
291 // TODO: Support constructing SCEVs for more recipes as needed.
292 const VPRecipeBase *DefR = V->getDefiningRecipe();
293 const SCEV *Expr =
295 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
296 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
297 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
298 if (!L || isa<SCEVCouldNotCompute>(Step))
299 return SE.getCouldNotCompute();
300 const SCEV *Start =
301 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
302 const SCEV *AddRec =
303 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
304 if (R->getTruncInst())
305 return SE.getTruncateExpr(AddRec, R->getScalarType());
306 return AddRec;
307 })
308 .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
309 const SCEV *Start =
310 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
311 if (!L || isa<SCEVCouldNotCompute>(Start))
312 return SE.getCouldNotCompute();
313 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
314 if (isa<SCEVCouldNotCompute>(Step))
315 return SE.getCouldNotCompute();
316 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
317 })
318 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
319 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
320 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
321 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
322 if (any_of(ArrayRef({Start, IV, Scale}),
324 return SE.getCouldNotCompute();
325
326 return SE.getAddExpr(
327 SE.getTruncateOrSignExtend(Start, IV->getType()),
328 SE.getMulExpr(
329 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
330 })
331 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
332 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
333 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
335 return SE.getCouldNotCompute();
336 return SE.getTruncateOrSignExtend(IV, Step->getType());
337 })
338 .Default(
339 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
340
341 return PSE.getPredicatedSCEV(Expr);
342}
343
345 const Loop *L) {
346 // If address is an SCEVAddExpr, we require that all operands must be either
347 // be invariant or a (possibly sign-extend) affine AddRec.
348 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
349 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
350 return SE.isLoopInvariant(Op, L) ||
351 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
352 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
353 });
354 }
355
356 // Otherwise, check if address is loop invariant or an affine add recurrence.
357 return SE.isLoopInvariant(Addr, L) ||
359}
360
361/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
362/// uniform, the result will also be uniform.
363static bool preservesUniformity(unsigned Opcode) {
364 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
365 return true;
366 switch (Opcode) {
367 case Instruction::Freeze:
368 case Instruction::GetElementPtr:
369 case Instruction::ICmp:
370 case Instruction::FCmp:
371 case Instruction::Select:
376 return true;
377 default:
378 return false;
379 }
380}
381
383 // Live-in, symbolic and region-values represent single-scalar values.
385 return true;
386
387 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
388 const VPRegionBlock *RegionOfR = Rep->getRegion();
389 // Don't consider recipes in replicate regions as uniform yet; their first
390 // lane cannot be accessed when executing the replicate region for other
391 // lanes.
392 if (RegionOfR && RegionOfR->isReplicator())
393 return false;
394 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
395 all_of(Rep->operands(), isSingleScalar));
396 }
399 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
400 return preservesUniformity(WidenR->getOpcode()) &&
401 all_of(WidenR->operands(), isSingleScalar);
402 }
403 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
404 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
405 (preservesUniformity(VPI->getOpcode()) &&
406 all_of(VPI->operands(), isSingleScalar));
407 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
408 return !RR->isPartialReduction();
410 VPV))
411 return true;
412 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
413 return Expr->isSingleScalar();
414
415 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
416 return isa<VPExpandSCEVRecipe>(VPV);
417}
418
420 // Live-ins and region values are uniform.
422 return true;
423
424 const VPRecipeBase *R = V->getDefiningRecipe();
425 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
426 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
427 if (VPBB) {
428 if ((VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
429 if (match(V->getDefiningRecipe(),
431 return false;
432 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
433 }
434 }
435
437 .Case([](const VPDerivedIVRecipe *R) { return true; })
438 .Case([](const VPReplicateRecipe *R) {
439 // Be conservative about side-effects, except for the
440 // known-side-effecting assumes and stores, which we know will be
441 // uniform.
442 return R->isSingleScalar() &&
443 (!R->mayHaveSideEffects() ||
444 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
445 all_of(R->operands(), isUniformAcrossVFsAndUFs);
446 })
447 .Case([](const VPWidenRecipe *R) {
448 return preservesUniformity(R->getOpcode()) &&
449 all_of(R->operands(), isUniformAcrossVFsAndUFs);
450 })
451 .Case([](const VPInstruction *VPI) {
452 return preservesUniformity(VPI->getOpcode()) &&
454 })
455 .Case([](const VPWidenCastRecipe *R) {
456 // A cast is uniform according to its operand.
457 return isUniformAcrossVFsAndUFs(R->getOperand(0));
458 })
459 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
460 // unless proven otherwise.
461 return false;
462 });
463}
464
466 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
467 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
468 return VPBlockUtils::isHeader(VPB, VPDT);
469 });
470 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
471}
472
474 if (!R)
475 return 1;
476 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
477 return RR->getVFScaleFactor();
478 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
479 return RR->getVFScaleFactor();
480 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
481 return ER->getVFScaleFactor();
482 assert(
483 (!isa<VPInstruction>(R) || cast<VPInstruction>(R)->getOpcode() !=
485 "getting scaling factor of reduction-start-vector not implemented yet");
486 return 1;
487}
488
489bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
490 // Assumes don't alias anything or throw; as long as they're guaranteed to
491 // execute, they're safe to hoist. They should however not be sunk, as it
492 // would destroy information.
494 return Sinking;
495 // TODO: Relax checks in the future, e.g. we could also hoist reads, if their
496 // memory location is not modified in the vector loop.
497 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
498 return true;
499 // Allocas cannot be hoisted.
500 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
501 return RepR && RepR->getOpcode() == Instruction::Alloca;
502}
503
504std::optional<VPValue *>
507 VPBasicBlock *LatchVPBB) {
508 // Given a plain CFG VPlan loop with countable latch exiting block
509 // \p LatchVPBB, we're looking to match the recipes contributing to the
510 // uncountable exit condition comparison (here, vp<%4>) back to either
511 // live-ins or the address nodes for the load used as part of the uncountable
512 // exit comparison so that we can either move them within the loop, or copy
513 // them to the preheader depending on the chosen method for dealing with
514 // stores in uncountable exit loops.
515 //
516 // Currently, the address of the load is restricted to a GEP with 2 operands
517 // and a live-in base address. This constraint may be relaxed later.
518 //
519 // VPlan ' for UF>=1' {
520 // Live-in vp<%0> = VF * UF
521 // Live-in vp<%1> = vector-trip-count
522 // Live-in ir<20> = original trip-count
523 //
524 // ir-bb<entry>:
525 // Successor(s): scalar.ph, vector.ph
526 //
527 // vector.ph:
528 // Successor(s): for.body
529 //
530 // for.body:
531 // EMIT vp<%2> = phi ir<0>, vp<%index.next>
532 // EMIT-SCALAR ir<%iv> = phi [ ir<0>, vector.ph ], [ ir<%iv.next>, for.inc ]
533 // EMIT ir<%uncountable.addr> = getelementptr inbounds nuw ir<%pred>,ir<%iv>
534 // EMIT ir<%uncountable.val> = load ir<%uncountable.addr>
535 // EMIT ir<%uncountable.cond> = icmp sgt ir<%uncountable.val>, ir<500>
536 // EMIT vp<%3> = masked-cond ir<%uncountable.cond>
537 // Successor(s): for.inc
538 //
539 // for.inc:
540 // EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
541 // EMIT ir<%countable.cond> = icmp eq ir<%iv.next>, ir<20>
542 // EMIT vp<%index.next> = add nuw vp<%2>, vp<%0>
543 // EMIT vp<%4> = any-of ir<%3>
544 // EMIT vp<%5> = icmp eq vp<%index.next>, vp<%1>
545 // EMIT vp<%6> = or vp<%4>, vp<%5>
546 // EMIT branch-on-cond vp<%6>
547 // Successor(s): middle.block, for.body
548 //
549 // middle.block:
550 // Successor(s): ir-bb<exit>, scalar.ph
551 //
552 // ir-bb<exit>:
553 // No successors
554 //
555 // scalar.ph:
556 // }
557
558 // Find the uncountable loop exit condition.
559 VPValue *UncountableCondition = nullptr;
560 if (!match(LatchVPBB->getTerminator(),
562 m_AnyOf(m_VPValue(UncountableCondition)), m_VPValue()))))
563 return std::nullopt;
564
566 Worklist.push_back(UncountableCondition);
567 while (!Worklist.empty()) {
568 VPValue *V = Worklist.pop_back_val();
569
570 // Any value defined outside the loop does not need to be copied.
571 if (V->isDefinedOutsideLoopRegions())
572 continue;
573
574 // FIXME: Remove the single user restriction; it's here because we're
575 // starting with the simplest set of loops we can, and multiple
576 // users means needing to add PHI nodes in the transform.
577 if (V->getNumUsers() > 1)
578 return std::nullopt;
579
580 VPValue *Op1, *Op2;
581 // Walk back through recipes until we find at least one load from memory.
582 if (match(V, m_ICmp(m_VPValue(Op1), m_VPValue(Op2)))) {
583 Worklist.push_back(Op1);
584 Worklist.push_back(Op2);
585 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
587 VPRecipeBase *GepR = Op1->getDefiningRecipe();
588 // Only matching base + single offset term for now.
589 if (GepR->getNumOperands() != 2)
590 return std::nullopt;
591 // Matching a GEP with a loop-invariant base ptr.
593 m_LiveIn(), m_VPValue())))
594 return std::nullopt;
595 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
596 Recipes.push_back(cast<VPInstruction>(GepR));
597 GEPs.push_back(cast<VPInstruction>(GepR));
599 m_VPValue(Op1)))) {
600 Worklist.push_back(Op1);
601 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
602 } else
603 return std::nullopt;
604 }
605
606 // If we couldn't match anything, don't return the condition. It may be
607 // defined outside the loop.
608 if (Recipes.empty() || GEPs.empty())
609 return std::nullopt;
610
611 return UncountableCondition;
612}
613
615 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
616 SmallVector<VPValue *> WideCanonicalIVs;
617 auto *WideCanonicalIV = vputils::findUserOf<VPWidenCanonicalIVRecipe>(
618 LoopRegion->getCanonicalIV());
619 assert(count_if(LoopRegion->getCanonicalIV()->users(),
621 "Must have at most one VPWideCanonicalIVRecipe");
622 if (WideCanonicalIV)
623 WideCanonicalIVs.push_back(WideCanonicalIV);
624
625 // Also include VPWidenIntOrFpInductionRecipes that represent a widened
626 // version of the canonical induction.
627 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
628 for (VPRecipeBase &Phi : HeaderVPBB->phis()) {
629 auto *WidenOriginalIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi);
630 if (WidenOriginalIV && WidenOriginalIV->isCanonical())
631 WideCanonicalIVs.push_back(WidenOriginalIV);
632 }
633
634 // Walk users of wide canonical IVs and find the single compare of the form
635 // (ICMP_ULE, WideCanonicalIV, backedge-taken-count).
636 VPSingleDefRecipe *HeaderMask = nullptr;
637 for (auto *Wide : WideCanonicalIVs) {
638 for (VPUser *U : Wide->users()) {
639 auto *VPI = dyn_cast<VPInstruction>(U);
640 if (!VPI || !vputils::isHeaderMask(VPI, Plan))
641 continue;
642
643 assert(VPI->getOperand(0) == Wide &&
644 "WidenCanonicalIV must be the first operand of the compare");
645 assert(!HeaderMask && "Multiple header masks found?");
646 HeaderMask = VPI;
647 }
648 }
649 return HeaderMask;
650}
651
654 VPBasicBlock *LastBB) {
655 assert(FirstBB->getParent() == LastBB->getParent() &&
656 "FirstBB and LastBB from different regions");
657#ifndef NDEBUG
658 bool InSingleSuccChain = false;
659 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
660 InSingleSuccChain |= (Succ == LastBB);
661 assert(InSingleSuccChain &&
662 "LastBB unreachable from FirstBB in single-successor chain");
663#endif
664 auto Blocks = to_vector(
666 auto *LastIt = find(Blocks, LastBB);
667 assert(LastIt != Blocks.end() &&
668 "LastBB unreachable from FirstBB in depth-first traversal");
669 Blocks.erase(std::next(LastIt), Blocks.end());
670 return Blocks;
671}
672
674 const VPDominatorTree &VPDT) {
675 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
676 if (!VPBB)
677 return false;
678
679 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
680 // VPBB as its entry, i.e., free of predecessors.
681 if (auto *R = VPBB->getParent())
682 return !R->isReplicator() && !VPBB->hasPredecessors();
683
684 // A header dominates its second predecessor (the latch), with the other
685 // predecessor being the preheader
686 return VPB->getPredecessors().size() == 2 &&
687 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
688}
689
691 const VPDominatorTree &VPDT) {
692 // A latch has a header as its last successor, with its other successors
693 // leaving the loop. A preheader OTOH has a header as its first (and only)
694 // successor.
695 return VPB->getNumSuccessors() >= 2 &&
697}
698
699std::optional<MemoryLocation>
701 auto *M = dyn_cast<VPIRMetadata>(&R);
702 if (!M)
703 return std::nullopt;
705 // Populate noalias metadata from VPIRMetadata.
706 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
707 Loc.AATags.NoAlias = NoAliasMD;
708 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
709 Loc.AATags.Scope = AliasScopeMD;
710 return Loc;
711}
712
714 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
715 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
716 assert(CanIV && "Expected loop region to have a canonical IV");
717
718 VPSymbolicValue &VFxUF = Plan.getVFxUF();
719
720 // Check if \p Step matches the expected increment step, accounting for
721 // materialization of VFxUF and UF.
722 auto IsIncrementStep = [&](VPValue *Step) -> bool {
723 if (!VFxUF.isMaterialized())
724 return Step == &VFxUF;
725
726 VPSymbolicValue &UF = Plan.getUF();
727 if (!UF.isMaterialized())
728 return Step == &UF;
729
730 unsigned ConcreteUF = Plan.getConcreteUF();
731 // Fixed VF: step is just the concrete UF.
732 if (match(Step, m_SpecificInt(ConcreteUF)))
733 return true;
734
735 // Scalable VF: step involves VScale.
736 if (ConcreteUF == 1)
738 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF),
740 return true;
741 // mul(VScale, ConcreteUF) may have been simplified to
742 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
743 return isPowerOf2_32(ConcreteUF) &&
746 m_SpecificInt(Log2_32(ConcreteUF))));
747 };
748
749 VPInstruction *Increment = nullptr;
750 for (VPUser *U : CanIV->users()) {
751 VPValue *Step;
752 if (isa<VPInstruction>(U) &&
753 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
754 IsIncrementStep(Step)) {
755 assert(!Increment && "There must be a unique increment");
757 }
758 }
759
760 assert((!VFxUF.isMaterialized() || Increment) &&
761 "After materializing VFxUF, an increment must exist");
762 assert((!Increment ||
763 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
764 "NUW flag in region and increment must match");
765 return Increment;
766}
767
768/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
769/// inserted for predicated reductions or tail folding.
771 VPValue *BackedgeVal = PhiR->getBackedgeValue();
773 BackedgeVal))
774 return Res;
775
776 // Look through selects inserted for tail folding or predicated reductions.
778 BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
779 if (!SelR)
780 return nullptr;
783}
784
787 SmallVector<const VPValue *> WorkList = {V};
788
789 while (!WorkList.empty()) {
790 const VPValue *Cur = WorkList.pop_back_val();
791 if (!Seen.insert(Cur).second)
792 continue;
793
794 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
795 // Skip blends that use V only through a compare by checking if any incoming
796 // value was already visited.
797 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
798 [&](unsigned I) {
799 return Seen.contains(Blend->getIncomingValue(I));
800 }))
801 continue;
802
803 for (VPUser *U : Cur->users()) {
804 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
805 if (InterleaveR->getAddr() == Cur)
806 return true;
807 if (auto *RepR = dyn_cast<VPReplicateRecipe>(U)) {
808 if (RepR->getOpcode() == Instruction::Load &&
809 RepR->getOperand(0) == Cur)
810 return true;
811 if (RepR->getOpcode() == Instruction::Store &&
812 RepR->getOperand(1) == Cur)
813 return true;
814 }
815 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(U)) {
816 if (MemR->getAddr() == Cur && MemR->isConsecutive())
817 return true;
818 }
819 }
820
821 // The legacy cost model only supports scalarization loads/stores with phi
822 // addresses, if the phi is directly used as load/store address. Don't
823 // traverse further for Blends.
824 if (Blend)
825 continue;
826
827 // Only traverse further through users that also define a value (and can
828 // thus have their own users walked).
829 for (VPUser *U : Cur->users())
830 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
831 WorkList.push_back(SDR);
832 }
833 return false;
834}
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")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#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
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
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 * 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:4146
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4221
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4234
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:630
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:97
VPRegionBlock * getParent()
Definition VPlan.h:189
size_t getNumSuccessors() const
Definition VPlan.h:240
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:225
VPlan * getPlan()
Definition VPlan.cpp:178
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:183
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:230
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:214
static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
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:294
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:3895
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:3743
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2341
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:1317
unsigned getOpcode() const
Definition VPlan.h:1401
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:405
A recipe for handling reduction phis.
Definition VPlan.h:2685
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4356
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4432
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4481
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4468
VPValues defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:209
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3194
unsigned getOpcode() const
Definition VPlan.h:3259
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:3966
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
Definition VPlan.h:609
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:329
operand_range operands()
Definition VPlanValue.h:397
unsigned getNumOperands() const
Definition VPlanValue.h:367
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:49
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:128
user_range users()
Definition VPlanValue.h:155
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1836
A recipe for handling GEP instructions.
Definition VPlan.h:2086
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2447
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1780
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4504
VPBasicBlock * getEntry()
Definition VPlan.h:4596
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:4659
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:4698
VPValue * getBackedgeTakenCount() const
Definition VPlan.h:4685
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:4772
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1066
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:4750
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4601
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:4695
bool hasScalarVFOnly() const
Definition VPlan.h:4740
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:4691
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:136
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:265
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
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
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:280
bool isMaterialized() const
Returns true if this symbolic value has been materialized.
Definition VPlanValue.h:288