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