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 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
247 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
248 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
249 return SE.getTruncateExpr(Ops[0], DestTy);
250 });
251 }
252 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
253 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
254 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
255 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
256 return SE.getZeroExtendExpr(Ops[0], DestTy);
257 });
258 }
259 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
260 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
261 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
262
263 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
264 // onto the operands before computing the subtraction.
265 VPValue *SubLHS, *SubRHS;
266 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
267 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
268 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
269 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
270 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
272 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
273 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
274 }
275
276 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
277 return SE.getSignExtendExpr(Ops[0], DestTy);
278 });
279 }
280 if (match(V,
282 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
283 return SE.getUMaxExpr(Ops[0], Ops[1]);
284 });
285 if (match(V,
287 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
288 return SE.getSMaxExpr(Ops[0], Ops[1]);
289 });
290 if (match(V,
292 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
293 return SE.getUMinExpr(Ops[0], Ops[1]);
294 });
295 if (match(V,
297 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
298 return SE.getSMinExpr(Ops[0], Ops[1]);
299 });
301 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
302 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
303 // not proof that the input is never INT_MIN, nor that poison reaches
304 // UB. Do not translate it to SCEV's global IsNSW flag.
305 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
306 });
307
309 Type *SourceElementType;
310 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
311 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
312 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
313 });
314 }
315
316 // TODO: Support constructing SCEVs for more recipes as needed.
317 const VPRecipeBase *DefR = V->getDefiningRecipe();
318 const SCEV *Expr =
320 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
321 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
322 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
323 if (!L || isa<SCEVCouldNotCompute>(Step))
324 return SE.getCouldNotCompute();
325 const SCEV *Start =
326 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
327 const SCEV *AddRec =
328 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
329 if (R->getTruncInst())
330 return SE.getTruncateExpr(AddRec, R->getScalarType());
331 return AddRec;
332 })
333 .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
334 const SCEV *Start =
335 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
336 if (!L || isa<SCEVCouldNotCompute>(Start))
337 return SE.getCouldNotCompute();
338 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
339 if (isa<SCEVCouldNotCompute>(Step))
340 return SE.getCouldNotCompute();
341 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
342 })
343 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
344 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
345 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
346 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
347 if (any_of(ArrayRef({Start, IV, Scale}),
349 return SE.getCouldNotCompute();
350
351 return SE.getAddExpr(
352 SE.getTruncateOrSignExtend(Start, IV->getType()),
353 SE.getMulExpr(
354 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
355 })
356 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
357 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
358 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
360 return SE.getCouldNotCompute();
361 return SE.getTruncateOrSignExtend(IV, Step->getType());
362 })
363 .Default(
364 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
365
366 return PSE.getPredicatedSCEV(Expr);
367}
368
370 const Loop *L) {
371 // If address is an SCEVAddExpr, we require that all operands must be either
372 // be invariant or a (possibly sign-extend) affine AddRec.
373 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
374 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
375 return SE.isLoopInvariant(Op, L) ||
376 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
377 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
378 });
379 }
380
381 // Otherwise, check if address is loop invariant or an affine add recurrence.
382 return SE.isLoopInvariant(Addr, L) ||
384}
385
386/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
387/// uniform, the result will also be uniform.
388static bool preservesUniformity(unsigned Opcode) {
389 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
390 return true;
391 switch (Opcode) {
392 case Instruction::Freeze:
393 case Instruction::GetElementPtr:
394 case Instruction::ICmp:
395 case Instruction::FCmp:
396 case Instruction::Select:
401 return true;
402 default:
403 return false;
404 }
405}
406
408 // Live-in, symbolic and region-values represent single-scalar values.
410 return true;
411
412 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
413 const VPRegionBlock *RegionOfR = Rep->getRegion();
414 // Don't consider recipes in replicate regions as uniform yet; their first
415 // lane cannot be accessed when executing the replicate region for other
416 // lanes.
417 if (RegionOfR && RegionOfR->isReplicator())
418 return false;
419 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
420 all_of(Rep->operands(), isSingleScalar));
421 }
424 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
425 return preservesUniformity(WidenR->getOpcode()) &&
426 all_of(WidenR->operands(), isSingleScalar);
427 }
428 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
429 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
430 (preservesUniformity(VPI->getOpcode()) &&
431 all_of(VPI->operands(), isSingleScalar));
432 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
433 return !RR->isPartialReduction();
435 VPV))
436 return true;
437 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
438 return Expr->isVectorToScalar();
439
440 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
441 return isa<VPExpandSCEVRecipe>(VPV);
442}
443
445 // Live-ins and region values are uniform.
447 return true;
448
449 const VPRecipeBase *R = V->getDefiningRecipe();
450 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
451 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
452 if (VPBB) {
453 if ((VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
454 if (match(V->getDefiningRecipe(),
456 return false;
457 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
458 }
459 }
460
462 .Case([](const VPDerivedIVRecipe *R) { return true; })
463 .Case([](const VPReplicateRecipe *R) {
464 // Be conservative about side-effects, except for the
465 // known-side-effecting assumes and stores, which we know will be
466 // uniform.
467 return R->isSingleScalar() &&
468 (!R->mayHaveSideEffects() ||
469 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
470 all_of(R->operands(), isUniformAcrossVFsAndUFs);
471 })
472 .Case([](const VPWidenRecipe *R) {
473 return preservesUniformity(R->getOpcode()) &&
474 all_of(R->operands(), isUniformAcrossVFsAndUFs);
475 })
476 .Case([](const VPPhi *) {
477 // Bail out on VPPhi, as we can end up in infinite cycles.
478 return false;
479 })
480 .Case([](const VPInstruction *VPI) {
481 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
484 })
485 .Case([](const VPWidenCastRecipe *R) {
486 // A cast is uniform according to its operand.
487 return isUniformAcrossVFsAndUFs(R->getOperand(0));
488 })
489 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
490 // unless proven otherwise.
491 return false;
492 });
493}
494
496 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
497 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
498 return VPBlockUtils::isHeader(VPB, VPDT);
499 });
500 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
501}
502
504 if (!R)
505 return 1;
506 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
507 return RR->getVFScaleFactor();
508 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
509 return RR->getVFScaleFactor();
510 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
511 return ER->getVFScaleFactor();
512 assert(
515 "getting scaling factor of reduction-start-vector not implemented yet");
516 return 1;
517}
518
519bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
520 // Assumes don't alias anything or throw; as long as they're guaranteed to
521 // execute, they're safe to hoist. They should however not be sunk, as it
522 // would destroy information.
524 return Sinking;
525 // TODO: Relax checks in the future, e.g. we could also hoist reads, if their
526 // memory location is not modified in the vector loop.
527 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
528 return true;
529 // Allocas cannot be hoisted.
530 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
531 return RepR && RepR->getOpcode() == Instruction::Alloca;
532}
533
534std::optional<VPValue *>
537 VPBasicBlock *LatchVPBB) {
538 // Given a plain CFG VPlan loop with countable latch exiting block
539 // \p LatchVPBB, we're looking to match the recipes contributing to the
540 // uncountable exit condition comparison (here, vp<%4>) back to either
541 // live-ins or the address nodes for the load used as part of the uncountable
542 // exit comparison so that we can either move them within the loop, or copy
543 // them to the preheader depending on the chosen method for dealing with
544 // stores in uncountable exit loops.
545 //
546 // Currently, the address of the load is restricted to a GEP with 2 operands
547 // and a live-in base address. This constraint may be relaxed later.
548 //
549 // VPlan ' for UF>=1' {
550 // Live-in vp<%0> = VF * UF
551 // Live-in vp<%1> = vector-trip-count
552 // Live-in ir<20> = original trip-count
553 //
554 // ir-bb<entry>:
555 // Successor(s): scalar.ph, vector.ph
556 //
557 // vector.ph:
558 // Successor(s): for.body
559 //
560 // for.body:
561 // EMIT vp<%2> = phi ir<0>, vp<%index.next>
562 // EMIT-SCALAR ir<%iv> = phi [ ir<0>, vector.ph ], [ ir<%iv.next>, for.inc ]
563 // EMIT ir<%uncountable.addr> = getelementptr inbounds nuw ir<%pred>,ir<%iv>
564 // EMIT ir<%uncountable.val> = load ir<%uncountable.addr>
565 // EMIT ir<%uncountable.cond> = icmp sgt ir<%uncountable.val>, ir<500>
566 // EMIT vp<%3> = masked-cond ir<%uncountable.cond>
567 // Successor(s): for.inc
568 //
569 // for.inc:
570 // EMIT ir<%iv.next> = add nuw nsw ir<%iv>, ir<1>
571 // EMIT ir<%countable.cond> = icmp eq ir<%iv.next>, ir<20>
572 // EMIT vp<%index.next> = add nuw vp<%2>, vp<%0>
573 // EMIT vp<%4> = any-of ir<%3>
574 // EMIT vp<%5> = icmp eq vp<%index.next>, vp<%1>
575 // EMIT vp<%6> = or vp<%4>, vp<%5>
576 // EMIT branch-on-cond vp<%6>
577 // Successor(s): middle.block, for.body
578 //
579 // middle.block:
580 // Successor(s): ir-bb<exit>, scalar.ph
581 //
582 // ir-bb<exit>:
583 // No successors
584 //
585 // scalar.ph:
586 // }
587
588 // Find the uncountable loop exit condition.
589 VPValue *UncountableCondition = nullptr;
590 if (!match(LatchVPBB->getTerminator(),
592 m_AnyOf(m_VPValue(UncountableCondition)), m_VPValue()))))
593 return std::nullopt;
594
596 Worklist.push_back(UncountableCondition);
597 while (!Worklist.empty()) {
598 VPValue *V = Worklist.pop_back_val();
599
600 // Any value defined outside the loop does not need to be copied.
601 if (V->isDefinedOutsideLoopRegions())
602 continue;
603
604 // FIXME: Remove the single user restriction; it's here because we're
605 // starting with the simplest set of loops we can, and multiple
606 // users means needing to add PHI nodes in the transform.
607 if (V->getNumUsers() > 1)
608 return std::nullopt;
609
610 VPValue *Op1, *Op2;
611 // Walk back through recipes until we find at least one load from memory.
612 if (match(V, m_ICmp(m_VPValue(Op1), m_VPValue(Op2)))) {
613 Worklist.push_back(Op1);
614 Worklist.push_back(Op2);
615 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
617 VPRecipeBase *GepR = Op1->getDefiningRecipe();
618 // Only matching base + single offset term for now.
619 if (GepR->getNumOperands() != 2)
620 return std::nullopt;
621 // Matching a GEP with a loop-invariant base ptr.
623 m_LiveIn(), m_VPValue())))
624 return std::nullopt;
625 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
626 Recipes.push_back(cast<VPInstruction>(GepR));
627 GEPs.push_back(cast<VPInstruction>(GepR));
629 m_VPValue(Op1)))) {
630 Worklist.push_back(Op1);
631 Recipes.push_back(cast<VPInstruction>(V->getDefiningRecipe()));
632 } else
633 return std::nullopt;
634 }
635
636 // If we couldn't match anything, don't return the condition. It may be
637 // defined outside the loop.
638 if (Recipes.empty() || GEPs.empty())
639 return std::nullopt;
640
641 return UncountableCondition;
642}
643
645 if (VPValue *AliasMask = findIncomingAliasMask(Plan)) {
646 assert(match(AliasMask->getSingleUser(),
647 m_c_BinaryAnd(m_VPValue(), m_Specific(AliasMask))) &&
648 "AliasMask must only be used with the original header mask");
649 return cast<VPSingleDefRecipe>(AliasMask->getSingleUser());
650 }
651
652 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
653 SmallVector<VPValue *> WideCanonicalIVs;
654 auto *WideCanonicalIV =
656 assert(count_if(LoopRegion->getCanonicalIV()->users(),
658 "Must have at most one VPWideCanonicalIVRecipe");
659 if (WideCanonicalIV)
660 WideCanonicalIVs.push_back(WideCanonicalIV);
661
662 // Also include VPWidenIntOrFpInductionRecipes that represent a widened
663 // version of the canonical induction.
664 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
665 for (VPRecipeBase &Phi : HeaderVPBB->phis()) {
667 if (match(&Phi, m_CanonicalWidenIV(WidenIV)))
668 WideCanonicalIVs.push_back(WidenIV);
669 }
670
671 // Walk users of wide canonical IVs and find the single compare of the form
672 // (ICMP_ULE, WideCanonicalIV, backedge-taken-count).
673 VPSingleDefRecipe *HeaderMask = nullptr;
674 for (auto *Wide : WideCanonicalIVs) {
675 for (VPUser *U : Wide->users()) {
676 auto *VPI = dyn_cast<VPInstruction>(U);
677 if (!VPI || !vputils::isHeaderMask(VPI, Plan))
678 continue;
679
680 assert(VPI->getOperand(0) == Wide &&
681 "WidenCanonicalIV must be the first operand of the compare");
682 assert(!HeaderMask && "Multiple header masks found?");
683 HeaderMask = VPI;
684 }
685 }
686
687 for (VPRecipeBase &R : LoopRegion->getEntryBasicBlock()->phis()) {
688 auto *Def = cast<VPSingleDefRecipe>(&R);
689 if (vputils::isHeaderMask(Def, Plan)) {
690 assert(!HeaderMask && "Multiple header masks found?");
691 HeaderMask = Def;
692 }
693 }
694
695 return HeaderMask;
696}
697
700 VPBasicBlock *LastBB) {
701 assert(FirstBB->getParent() == LastBB->getParent() &&
702 "FirstBB and LastBB from different regions");
703#ifndef NDEBUG
704 bool InSingleSuccChain = false;
705 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
706 InSingleSuccChain |= (Succ == LastBB);
707 assert(InSingleSuccChain &&
708 "LastBB unreachable from FirstBB in single-successor chain");
709#endif
710 auto Blocks = to_vector(
712 auto *LastIt = find(Blocks, LastBB);
713 assert(LastIt != Blocks.end() &&
714 "LastBB unreachable from FirstBB in depth-first traversal");
715 Blocks.erase(std::next(LastIt), Blocks.end());
716 return Blocks;
717}
718
720 for (VPRecipeBase &R : *Plan.getVectorPreheader())
722 return cast<VPInstruction>(&R);
723 return nullptr;
724}
725
727 const VPDominatorTree &VPDT) {
728 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
729 if (!VPBB)
730 return false;
731
732 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
733 // VPBB as its entry, i.e., free of predecessors.
734 if (auto *R = VPBB->getParent())
735 return !R->isReplicator() && !VPBB->hasPredecessors();
736
737 // A header dominates its second predecessor (the latch), with the other
738 // predecessor being the preheader
739 return VPB->getPredecessors().size() == 2 &&
740 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
741}
742
744 const VPDominatorTree &VPDT) {
745 // A latch has a header as its last successor, with its other successors
746 // leaving the loop. A preheader OTOH has a header as its first (and only)
747 // successor.
748 return VPB->getNumSuccessors() >= 2 &&
750}
751
752std::pair<VPBasicBlock *, VPBasicBlock *>
754 auto *Header = cast<VPBasicBlock>(
755 Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
756 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
757 return {Header, Latch};
758}
759
763
764std::optional<MemoryLocation>
766 auto *M = dyn_cast<VPIRMetadata>(&R);
767 if (!M)
768 return std::nullopt;
770 // Populate noalias metadata from VPIRMetadata.
771 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
772 Loc.AATags.NoAlias = NoAliasMD;
773 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
774 Loc.AATags.Scope = AliasScopeMD;
775 return Loc;
776}
777
779 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
780 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
781 assert(CanIV && "Expected loop region to have a canonical IV");
782
783 VPSymbolicValue &VFxUF = Plan.getVFxUF();
784
785 // Check if \p Step matches the expected increment step, accounting for
786 // materialization of VFxUF and UF.
787 auto IsIncrementStep = [&](VPValue *Step) -> bool {
788 if (!VFxUF.isMaterialized())
789 return Step == &VFxUF;
790
791 VPSymbolicValue &UF = Plan.getUF();
792 if (!UF.isMaterialized())
793 return Step == &UF ||
794 match(Step, m_c_Mul(m_Specific(&Plan.getUF()),
796
797 // Alias masking: step is number of active lanes of a dependence mask.
798 if (match(Step, m_ZExtOrTruncOrSelf(
800 return true;
801
802 unsigned ConcreteUF = Plan.getConcreteUF();
803 // Fixed VF: step is just the concrete UF.
804 if (match(Step, m_SpecificInt(ConcreteUF)))
805 return true;
806
807 // Scalable VF: step involves VScale.
808 if (ConcreteUF == 1)
810 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF),
812 return true;
813 // mul(VScale, ConcreteUF) may have been simplified to
814 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
815 return isPowerOf2_32(ConcreteUF) &&
817 m_SpecificInt(Log2_32(ConcreteUF))));
818 };
819
820 VPInstruction *Increment = nullptr;
821 for (VPUser *U : CanIV->users()) {
822 VPValue *Step;
823 if (isa<VPInstruction>(U) &&
824 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
825 IsIncrementStep(Step)) {
826 assert(!Increment && "There must be a unique increment");
828 }
829 }
830
831 assert((!VFxUF.isMaterialized() || Increment) &&
832 "After materializing VFxUF, an increment must exist");
833 assert((!Increment ||
834 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
835 "NUW flag in region and increment must match");
836 return Increment;
837}
838
839/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
840/// inserted for predicated reductions or tail folding.
842 VPValue *BackedgeVal = PhiR->getBackedgeValue();
843 if (auto *Res =
845 return Res;
846
847 // Look through selects inserted for tail folding or predicated reductions.
848 VPRecipeBase *SelR =
849 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
850 if (!SelR)
851 return nullptr;
854}
855
858 SmallVector<const VPValue *> WorkList = {V};
859
860 while (!WorkList.empty()) {
861 const VPValue *Cur = WorkList.pop_back_val();
862 if (!Seen.insert(Cur).second)
863 continue;
864
865 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
866 // Skip blends that use V only through a compare by checking if any incoming
867 // value was already visited.
868 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
869 [&](unsigned I) {
870 return Seen.contains(Blend->getIncomingValue(I));
871 }))
872 continue;
873
874 for (VPUser *U : Cur->users()) {
875 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
876 if (InterleaveR->getAddr() == Cur)
877 return true;
878 if (auto *RepR = dyn_cast<VPReplicateRecipe>(U)) {
879 if (RepR->getOpcode() == Instruction::Load &&
880 RepR->getOperand(0) == Cur)
881 return true;
882 if (RepR->getOpcode() == Instruction::Store &&
883 RepR->getOperand(1) == Cur)
884 return true;
885 }
887 if (MemR->getAddr() == Cur && MemR->isConsecutive())
888 return true;
889 }
890 }
891
892 // The legacy cost model only supports scalarization loads/stores with phi
893 // addresses, if the phi is directly used as load/store address. Don't
894 // traverse further for Blends.
895 if (Blend)
896 continue;
897
898 // Only traverse further through users that also define a value (and can
899 // thus have their own users walked).
900 for (VPUser *U : Cur->users())
901 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
902 WorkList.push_back(SDR);
903 }
904 return false;
905}
906
907/// Try to find a loop-invariant IR value for \p S in the plan's entry block
908/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
909/// if no reusable IR value is found.
910VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
912 return nullptr;
913 VPlan &Plan = Builder.getPlan();
914 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
915 for (Value *V : SE.getSCEVValues(S)) {
916 // Only reuse instructions in the plan's entry block, as instructions in
917 // sibling branches may not dominate the entry block.
918 auto *I = dyn_cast<Instruction>(V);
919 if (!I)
920 return Plan.getOrAddLiveIn(V);
921 if (I->getParent() != PH)
922 continue;
923 SmallVector<Instruction *> DropPoisonGeneratingInsts;
924 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
925 continue;
926 for (Instruction *DropI : DropPoisonGeneratingInsts)
928 return Plan.getOrAddLiveIn(V);
929 }
930 return nullptr;
931}
932
934 if (VPValue *V = tryToReuseIRValue(S))
935 return V;
936
937 switch (S->getSCEVType()) {
938 case scConstant:
939 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
940 case scUnknown:
941 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
942 case scVScale:
943 return Builder.createNaryOp(VPInstruction::VScale, {}, S->getType());
944 case scMulExpr: {
945 auto *Mul = cast<SCEVMulExpr>(S);
947 for (const SCEVUse &Op : Mul->operands()) {
948 VPValue *OpV = tryToExpand(Op);
949 if (!OpV)
950 return nullptr;
951 Ops.push_back(OpV);
952 }
953 VPIRFlags::WrapFlagsTy WrapFlags(Mul->hasNoUnsignedWrap(),
954 Mul->hasNoSignedWrap());
955 VPValue *Result = Ops.front();
956 for (VPValue *Op : drop_begin(Ops))
957 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, Op},
958 WrapFlags, DL);
959 return Result;
960 }
961 default:
962 return nullptr;
963 }
964}
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: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.
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
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4295
iterator end()
Definition VPlan.h:4332
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4383
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:4361
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:93
VPRegionBlock * getParent()
Definition VPlan.h:185
size_t getNumSuccessors() const
Definition VPlan.h:236
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:221
VPlan * getPlan()
Definition VPlan.cpp:211
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:216
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:226
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:210
static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
static VPBasicBlock * getPlainCFGMiddleBlock(const VPlan &Plan)
Returns the middle block of Plan in plain CFG form (before regions are formed).
static bool isHeader(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop header, based on regions or VPDT in their absence.
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h: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:4070
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:3909
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2458
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1231
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1320
@ VScale
Returns the value for vscale.
Definition VPlan.h:1353
unsigned getOpcode() const
Definition VPlan.h:1422
bool isVectorToScalar() const
Returns true if this VPInstruction produces a scalar value from a vector, e.g.
bool isSingleScalar() const
Returns true if this VPInstruction's operands are single scalars and the result is also a single scal...
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:401
A recipe for handling reduction phis.
Definition VPlan.h:2805
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4505
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4581
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4630
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4617
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:3322
unsigned getOpcode() const
Definition VPlan.h:3402
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:4140
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:614
An analysis for type-inference for VPValues.
Type * inferScalarType(const VPValue *V)
Infer the type of V. Returns the scalar type of V.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:384
operand_range operands()
Definition VPlanValue.h:455
unsigned getNumOperands() const
Definition VPlanValue.h:422
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:130
user_range users()
Definition VPlanValue.h:157
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1861
A recipe for handling GEP instructions.
Definition VPlan.h:2188
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:1800
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4653
VPBasicBlock * getEntry()
Definition VPlan.h:4749
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:4812
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:4852
VPValue * getBackedgeTakenCount() const
Definition VPlan.h:4839
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:4926
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:4904
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4754
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:4849
bool hasScalarVFOnly() const
Definition VPlan.h:4894
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4792
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:4845
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()
AllRecipe_commutative_match< Instruction::Or, Op0_t, Op1_t > m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
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)
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
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