LLVM 23.0.0git
VPlanUtils.cpp
Go to the documentation of this file.
1//===- VPlanUtils.cpp - VPlan-related utilities ---------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "VPlanUtils.h"
11#include "VPlanAnalysis.h"
12#include "VPlanCFG.h"
13#include "VPlanDominatorTree.h"
14#include "VPlanPatternMatch.h"
15#include "llvm/ADT/TypeSwitch.h"
19#include "llvm/IR/Dominators.h"
21
22using namespace llvm;
23using namespace llvm::VPlanPatternMatch;
24using namespace llvm::SCEVPatternMatch;
25
27 return all_of(Def->users(),
28 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
29}
30
32 return all_of(Def->users(),
33 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
34}
35
37 return all_of(Def->users(),
38 [Def](const VPUser *U) { return U->usesScalars(Def); });
39}
40
42 if (auto *E = dyn_cast<SCEVConstant>(Expr))
43 return Plan.getOrAddLiveIn(E->getValue());
44 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
45 // value. Otherwise the value may be defined in a loop and using it directly
46 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
47 // form.
48 auto *U = dyn_cast<SCEVUnknown>(Expr);
49 if (U && !isa<Instruction>(U->getValue()))
50 return Plan.getOrAddLiveIn(U->getValue());
51 auto *Expanded = new VPExpandSCEVRecipe(Expr);
52 VPBasicBlock *EntryVPBB = Plan.getEntry();
53 auto Iter = EntryVPBB->getFirstNonPhi();
54 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
55 ++Iter;
56 EntryVPBB->insert(Expanded, Iter);
57 return Expanded;
58}
59
60/// Returns true if \p R propagates poison from any operand to its result.
64 [](const VPRecipeBase *) { return true; })
65 .Case([](const VPReplicateRecipe *Rep) {
66 // GEP and casts propagate poison from all operands.
67 unsigned Opcode = Rep->getOpcode();
68 return Opcode == Instruction::GetElementPtr ||
69 Instruction::isCast(Opcode);
70 })
71 .Default([](const VPRecipeBase *) { return false; });
72}
73
74/// Returns true if \p V being poison is guaranteed to trigger UB because it
75/// propagates to the address of a memory recipe.
76static bool poisonGuaranteesUB(const VPValue *V) {
79
80 Worklist.push_back(V);
81
82 while (!Worklist.empty()) {
83 const VPValue *Current = Worklist.pop_back_val();
84 if (!Visited.insert(Current).second)
85 continue;
86
87 for (VPUser *U : Current->users()) {
88 // Check if Current is used as an address operand for load/store.
90 if (MemR->getAddr() == Current)
91 return true;
92 continue;
93 }
94 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
95 unsigned Opcode = Rep->getOpcode();
96 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
97 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
98 return true;
99 }
100
101 // Check if poison propagates through this recipe to any of its users.
102 auto *R = cast<VPRecipeBase>(U);
103 for (const VPValue *Op : R->operands()) {
104 if (Op == Current && propagatesPoisonFromRecipeOp(R)) {
105 Worklist.push_back(R->getVPSingleValue());
106 break;
107 }
108 }
109 }
110 }
111
112 return false;
113}
114
116 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
117 // casts to find a root GEP VPInstruction.
118 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
119 unsigned Opcode = PtrVPI->getOpcode();
120 if (Opcode == Instruction::GetElementPtr) {
121 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
122 return PtrVPI->getGEPNoWrapFlags();
123 Ptr = PtrVPI->getOperand(0);
124 continue;
125 }
126 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
127 break;
128 Ptr = PtrVPI->getOperand(0);
129 }
130 return GEPNoWrapFlags::none();
131}
132
135 const Loop *L) {
136 ScalarEvolution &SE = *PSE.getSE();
137 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
138 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
139 "RegionValue must be canonical IV");
140 if (!L)
141 return SE.getCouldNotCompute();
142 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
144 }
145
147 Value *LiveIn = V->getUnderlyingValue();
148 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
149 return SE.getSCEV(LiveIn);
150 return SE.getCouldNotCompute();
151 }
152
153 // Helper to create SCEVs for binary and unary operations.
154 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
155 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
156 -> const SCEV * {
158 for (VPValue *Op : Ops) {
159 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
161 return SE.getCouldNotCompute();
162 SCEVOps.push_back(S);
163 }
164 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
165 };
166
167 VPValue *LHSVal, *RHSVal;
168 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
169 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
170 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
171 });
172 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
173 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
174 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
175 });
176 if (match(V, m_Not(m_VPValue(LHSVal)))) {
177 // not X = xor X, -1 = -1 - X
178 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
179 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
180 });
181 }
182 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
183 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
184 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
185 });
186 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
187 // amount >= the bit width produces poison; do not rewrite it, as
188 // getPowerOfTwo requires the power to be in range.
189 uint64_t ShiftAmt;
190 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
191 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
192 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
193 return SE.getMulExpr(Ops[0],
194 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
195 });
196 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
197 Type *Ty = V->getScalarType();
198 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
199 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
200 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
201 });
202 }
203 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
204 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
205 return SE.getUDivExpr(Ops[0], Ops[1]);
206 });
207 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
208 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
209 return SE.getURemExpr(Ops[0], Ops[1]);
210 });
211 // A SRem with non-negative operands is equivalent to an URem.
212 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
213 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
214 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
215 return SE.getCouldNotCompute();
216 return SE.getURemExpr(Ops[0], Ops[1]);
217 });
218 }
219 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
220 const APInt *Mask;
221 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
222 (*Mask + 1).isPowerOf2())
223 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
224 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
225 });
226 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
227 Type *DestTy = V->getScalarType();
228 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
229 return SE.getTruncateExpr(Ops[0], DestTy);
230 });
231 }
232 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
233 Type *DestTy = V->getScalarType();
234 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
235 return SE.getZeroExtendExpr(Ops[0], DestTy);
236 });
237 }
238 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
239 Type *DestTy = V->getScalarType();
240
241 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
242 // onto the operands before computing the subtraction.
243 VPValue *SubLHS, *SubRHS;
244 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
245 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
246 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
247 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
248 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
250 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
251 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
252 }
253
254 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
255 return SE.getSignExtendExpr(Ops[0], DestTy);
256 });
257 }
258 if (match(V,
260 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
261 return SE.getUMaxExpr(Ops[0], Ops[1]);
262 });
263 if (match(V,
265 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
266 return SE.getSMaxExpr(Ops[0], Ops[1]);
267 });
268 if (match(V,
270 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
271 return SE.getUMinExpr(Ops[0], Ops[1]);
272 });
273 if (match(V,
275 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
276 return SE.getSMinExpr(Ops[0], Ops[1]);
277 });
279 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
280 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
281 // not proof that the input is never INT_MIN, nor that poison reaches
282 // UB. Do not translate it to SCEV's global IsNSW flag.
283 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
284 });
285
287 Type *SourceElementType;
288 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
289 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
290 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
291 });
292 }
293
294 // TODO: Support constructing SCEVs for more recipes as needed.
295 const VPRecipeBase *DefR = V->getDefiningRecipe();
296 const SCEV *Expr =
298 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
299 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
300 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
301 if (!L || isa<SCEVCouldNotCompute>(Step))
302 return SE.getCouldNotCompute();
303 const SCEV *Start =
304 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
305 const SCEV *AddRec =
306 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
307 if (R->getTruncInst())
308 return SE.getTruncateExpr(AddRec, R->getScalarType());
309 return AddRec;
310 })
311 .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
312 const SCEV *Start =
313 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
314 if (!L || isa<SCEVCouldNotCompute>(Start))
315 return SE.getCouldNotCompute();
316 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
317 if (isa<SCEVCouldNotCompute>(Step))
318 return SE.getCouldNotCompute();
319 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
320 })
321 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
322 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
323 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
324 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
325 if (any_of(ArrayRef({Start, IV, Scale}),
327 return SE.getCouldNotCompute();
328
329 return SE.getAddExpr(
330 SE.getTruncateOrSignExtend(Start, IV->getType()),
331 SE.getMulExpr(
332 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
333 })
334 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
335 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
336 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
338 return SE.getCouldNotCompute();
339 return SE.getTruncateOrSignExtend(IV, Step->getType());
340 })
341 .Default(
342 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
343
344 return PSE.getPredicatedSCEV(Expr);
345}
346
348 const Loop *L) {
349 // If address is an SCEVAddExpr, we require that all operands must be either
350 // be invariant or a (possibly sign-extend) affine AddRec.
351 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
352 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
353 return SE.isLoopInvariant(Op, L) ||
354 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
355 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
356 });
357 }
358
359 // Otherwise, check if address is loop invariant or an affine add recurrence.
360 return SE.isLoopInvariant(Addr, L) ||
362}
363
364/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
365/// uniform, the result will also be uniform.
366static bool preservesUniformity(unsigned Opcode) {
367 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
368 return true;
369 switch (Opcode) {
370 case Instruction::Freeze:
371 case Instruction::GetElementPtr:
372 case Instruction::ICmp:
373 case Instruction::FCmp:
374 case Instruction::Select:
379 return true;
380 default:
381 return false;
382 }
383}
384
386 unsigned Opcode = TypeSwitch<const VPValue *, unsigned>(V)
388 [](auto *R) { return R->getOpcode(); })
389 .Default([](auto *) { return 0; });
390 // TODO: Handle more opcodes and recipes.
391 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
392}
393
395 // Live-in, symbolic and canonical-IV region values are single-scalar.
396 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
397 return RV == RV->getDefiningRegion()->getCanonicalIV();
399 return true;
400
401 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
402 const VPRegionBlock *RegionOfR = Rep->getRegion();
403 // Don't consider recipes in replicate regions as uniform yet; their first
404 // lane cannot be accessed when executing the replicate region for other
405 // lanes.
406 if (RegionOfR && RegionOfR->isReplicator())
407 return false;
408 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
409 all_of(Rep->operands(), isSingleScalar));
410 }
413 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
414 return preservesUniformity(WidenR->getOpcode()) &&
415 all_of(WidenR->operands(), isSingleScalar);
416 }
417 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
418 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
419 (preservesUniformity(VPI->getOpcode()) &&
420 all_of(VPI->operands(), isSingleScalar));
421 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
422 return !RR->isPartialReduction();
424 VPV))
425 return true;
426 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
427 return Expr->isVectorToScalar();
428
429 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
430 return isa<VPExpandSCEVRecipe>(VPV);
431}
432
434 // Live-ins, symbolic and canonical-IV region values are uniform.
435 if (auto *RV = dyn_cast<VPRegionValue>(V))
436 return RV == RV->getDefiningRegion()->getCanonicalIV();
438 return true;
439
440 const VPRecipeBase *R = V->getDefiningRecipe();
441 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
442 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
443 if (VPBB) {
444 if ((VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
445 if (match(V->getDefiningRecipe(),
447 return false;
448 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
449 }
450 }
451
453 .Case([](const VPDerivedIVRecipe *R) { return true; })
454 .Case([](const VPReplicateRecipe *R) {
455 // Be conservative about side-effects, except for the
456 // known-side-effecting assumes and stores, which we know will be
457 // uniform.
458 return R->isSingleScalar() &&
459 (!R->mayHaveSideEffects() ||
460 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
461 all_of(R->operands(), isUniformAcrossVFsAndUFs);
462 })
463 .Case([](const VPWidenRecipe *R) {
464 return preservesUniformity(R->getOpcode()) &&
465 all_of(R->operands(), isUniformAcrossVFsAndUFs);
466 })
467 .Case([](const VPPhi *) {
468 // Bail out on VPPhi, as we can end up in infinite cycles.
469 return false;
470 })
471 .Case([](const VPInstruction *VPI) {
472 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
475 })
476 .Case([](const VPWidenCastRecipe *R) {
477 // A cast is uniform according to its operand.
478 return isUniformAcrossVFsAndUFs(R->getOperand(0));
479 })
480 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
481 // unless proven otherwise.
482 return false;
483 });
484}
485
487 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
488 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
489 return VPBlockUtils::isHeader(VPB, VPDT);
490 });
491 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
492}
493
495 if (!R)
496 return 1;
497 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
498 return RR->getVFScaleFactor();
499 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
500 return RR->getVFScaleFactor();
501 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
502 return ER->getVFScaleFactor();
503 assert(
504 (!isa<VPInstruction>(R) || cast<VPInstruction>(R)->getOpcode() !=
506 "getting scaling factor of reduction-start-vector not implemented yet");
507 return 1;
508}
509
510bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
511 // Assumes don't alias anything or throw; as long as they're guaranteed to
512 // execute, they're safe to hoist. They should however not be sunk, as it
513 // would destroy information.
515 return Sinking;
516 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
517 return true;
518 // Allocas cannot be hoisted.
519 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
520 return RepR && RepR->getOpcode() == Instruction::Alloca;
521}
522
525 VPBasicBlock *LastBB) {
526 assert(FirstBB->getParent() == LastBB->getParent() &&
527 "FirstBB and LastBB from different regions");
528#ifndef NDEBUG
529 bool InSingleSuccChain = false;
530 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
531 InSingleSuccChain |= (Succ == LastBB);
532 assert(InSingleSuccChain &&
533 "LastBB unreachable from FirstBB in single-successor chain");
534#endif
535 auto Blocks = to_vector(
537 auto *LastIt = find(Blocks, LastBB);
538 assert(LastIt != Blocks.end() &&
539 "LastBB unreachable from FirstBB in depth-first traversal");
540 Blocks.erase(std::next(LastIt), Blocks.end());
541 return Blocks;
542}
543
545 for (VPRecipeBase &R : *Plan.getVectorPreheader())
547 return cast<VPInstruction>(&R);
548 return nullptr;
549}
550
552 const VPDominatorTree &VPDT) {
553 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
554 if (!VPBB)
555 return false;
556
557 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
558 // VPBB as its entry, i.e., free of predecessors.
559 if (auto *R = VPBB->getParent())
560 return !R->isReplicator() && !VPBB->hasPredecessors();
561
562 // A header dominates its second predecessor (the latch), with the other
563 // predecessor being the preheader
564 return VPB->getPredecessors().size() == 2 &&
565 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
566}
567
569 const VPDominatorTree &VPDT) {
570 // A latch has a header as its last successor, with its other successors
571 // leaving the loop. A preheader OTOH has a header as its first (and only)
572 // successor.
573 return VPB->getNumSuccessors() >= 2 &&
575}
576
577std::pair<VPBasicBlock *, VPBasicBlock *>
579 auto *Header = cast<VPBasicBlock>(
580 Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
581 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
582 return {Header, Latch};
583}
584
588
589std::optional<MemoryLocation>
591 auto *M = dyn_cast<VPIRMetadata>(&R);
592 if (!M)
593 return std::nullopt;
595 // Populate noalias metadata from VPIRMetadata.
596 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
597 Loc.AATags.NoAlias = NoAliasMD;
598 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
599 Loc.AATags.Scope = AliasScopeMD;
600 return Loc;
601}
602
604 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
605 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
606 assert(CanIV && "Expected loop region to have a canonical IV");
607
608 VPSymbolicValue &VFxUF = Plan.getVFxUF();
609
610 // Check if \p Step matches the expected increment step, accounting for
611 // materialization of VFxUF and UF.
612 auto IsIncrementStep = [&](VPValue *Step) -> bool {
613 if (!VFxUF.isMaterialized())
614 return Step == &VFxUF;
615
616 VPSymbolicValue &UF = Plan.getUF();
617 if (!UF.isMaterialized())
618 return Step == &UF ||
619 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
620
621 // Alias masking: step is number of active lanes of a dependence mask.
622 if (match(Step, m_ZExtOrTruncOrSelf(
624 return true;
625
626 unsigned ConcreteUF = Plan.getConcreteUF();
627 // Fixed VF: step is just the concrete UF.
628 if (match(Step, m_SpecificInt(ConcreteUF)))
629 return true;
630
631 // Scalable VF: step involves VScale.
632 if (ConcreteUF == 1)
633 return match(Step, m_VScale());
634 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
635 return true;
636 // mul(VScale, ConcreteUF) may have been simplified to
637 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
638 return isPowerOf2_32(ConcreteUF) &&
639 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
640 };
641
642 VPInstruction *Increment = nullptr;
643 for (VPUser *U : CanIV->users()) {
644 VPValue *Step;
645 if (isa<VPInstruction>(U) &&
646 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
647 IsIncrementStep(Step)) {
648 assert(!Increment && "There must be a unique increment");
650 }
651 }
652
653 assert((!VFxUF.isMaterialized() || Increment) &&
654 "After materializing VFxUF, an increment must exist");
655 assert((!Increment ||
656 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
657 "NUW flag in region and increment must match");
658 return Increment;
659}
660
661/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
662/// inserted for predicated reductions or tail folding.
664 VPValue *BackedgeVal = PhiR->getBackedgeValue();
665 if (auto *Res =
667 return Res;
668
669 // Look through selects inserted for tail folding or predicated reductions.
670 VPRecipeBase *SelR =
671 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
672 if (!SelR)
673 return nullptr;
676}
677
680 SmallVector<const VPValue *> WorkList = {V};
681
682 while (!WorkList.empty()) {
683 const VPValue *Cur = WorkList.pop_back_val();
684 if (!Seen.insert(Cur).second)
685 continue;
686
687 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
688 // Skip blends that use V only through a compare by checking if any incoming
689 // value was already visited.
690 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
691 [&](unsigned I) {
692 return Seen.contains(Blend->getIncomingValue(I));
693 }))
694 continue;
695
696 for (VPUser *U : Cur->users()) {
697 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
698 if (InterleaveR->getAddr() == Cur)
699 return true;
700 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
701 // store (operand 1).
704 m_Specific(Cur)))))
705 return true;
707 if (MemR->getAddr() == Cur && MemR->isConsecutive())
708 return true;
709 }
710 }
711
712 // The legacy cost model only supports scalarization loads/stores with phi
713 // addresses, if the phi is directly used as load/store address. Don't
714 // traverse further for Blends.
715 if (Blend)
716 continue;
717
718 // Only traverse further through users that also define a value (and can
719 // thus have their own users walked). Skip when Cur is only used as mask ,
720 // as well as loads: a loaded value does not depend on the load's operand.
721 for (VPUser *U : Cur->users()) {
722 auto *VPI = dyn_cast<VPInstruction>(U);
723 if (VPI && VPI->getMask() == Cur &&
724 none_of(VPI->operandsWithoutMask(),
725 [Cur](VPValue *Op) { return Op == Cur; }))
726 continue;
728 continue;
729 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
730 WorkList.push_back(SDR);
731 }
732 }
733 return false;
734}
735
736/// Try to find a loop-invariant IR value for \p S in the plan's entry block
737/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
738/// if no reusable IR value is found.
739VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
741 return nullptr;
742 VPlan &Plan = Builder.getPlan();
743 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
744 for (Value *V : SE.getSCEVValues(S)) {
745 // Only reuse instructions in the plan's entry block, or, when a
746 // DominatorTree is available, any instruction that dominates it.
747 // Instructions in sibling branches may not dominate the entry block.
748 auto *I = dyn_cast<Instruction>(V);
749 if (!I)
750 return Plan.getOrAddLiveIn(V);
751 if (!SE.DT.dominates(I->getParent(), PH))
752 continue;
753 SmallVector<Instruction *> DropPoisonGeneratingInsts;
754 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
755 continue;
756 for (Instruction *DropI : DropPoisonGeneratingInsts)
758 return Plan.getOrAddLiveIn(V);
759 }
760 return nullptr;
761}
762
764 if (VPValue *V = tryToReuseIRValue(S))
765 return V;
766
767 switch (S->getSCEVType()) {
768 case scConstant:
769 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
770 case scUnknown:
771 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
772 case scVScale:
773 return Builder.createVScale(S->getType(), DL);
774 case scAddExpr:
775 case scMulExpr: {
776 auto *NAry = cast<SCEVNAryExpr>(S);
777 VPIRFlags::WrapFlagsTy WrapFlags(NAry->hasNoUnsignedWrap(),
778 NAry->hasNoSignedWrap());
779
780 // Expanded poiner SCEVAddExpr as a ptradd of the pointer base and the
781 // integer offset, matching SCEVExpander.
782 if (S->getType()->isPointerTy()) {
783 VPValue *Base = tryToExpand(SE.getPointerBase(S));
784 if (!Base)
785 return nullptr;
786 VPValue *Offset = tryToExpand(SE.removePointerBase(S));
787 if (!Offset)
788 return nullptr;
789 GEPNoWrapFlags GEPFlags = WrapFlags.HasNUW
792 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
793 }
794
795 unsigned Opcode =
796 S->getSCEVType() == scAddExpr ? Instruction::Add : Instruction::Mul;
797 // Iterate in reverse so that constants are emitted last.
799 for (const SCEVUse &Op : reverse(NAry->operands())) {
800 VPValue *OpV = tryToExpand(Op);
801 if (!OpV)
802 return nullptr;
803 Ops.push_back(OpV);
804 }
805 VPValue *Result = Ops.front();
806 for (VPValue *Op : drop_begin(Ops))
807 Result = Builder.createOverflowingOp(Opcode, {Result, Op}, WrapFlags, DL);
808 return Result;
809 }
810 case scUDivExpr: {
811 auto *UDiv = cast<SCEVUDivExpr>(S);
812 VPValue *LHS = tryToExpand(UDiv->getLHS());
813 if (!LHS)
814 return nullptr;
815 VPValue *RHS = tryToExpand(UDiv->getRHS());
816 if (!RHS)
817 return nullptr;
818 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
819 VPIRFlags::getDefaultFlags(Instruction::UDiv),
820 DL);
821 }
822 case scTruncate:
823 case scZeroExtend:
824 case scSignExtend: {
825 auto *Cast = cast<SCEVCastExpr>(S);
826 VPValue *Op = tryToExpand(Cast->getOperand());
827 if (!Op)
828 return nullptr;
830 switch (S->getSCEVType()) {
831 case scTruncate:
832 Opcode = Instruction::Trunc;
833 break;
834 case scZeroExtend:
835 Opcode = Instruction::ZExt;
836 break;
837 case scSignExtend:
838 Opcode = Instruction::SExt;
839 break;
840 default:
841 llvm_unreachable("Unhandled cast SCEV");
842 }
843 return Builder.createScalarCast(Opcode, Op, S->getType(), DL);
844 }
845 case scUMaxExpr:
846 case scSMaxExpr:
847 case scUMinExpr:
848 case scSMinExpr: {
849 auto *MinMax = cast<SCEVMinMaxExpr>(S);
850 Intrinsic::ID IntrinsicID;
851 switch (S->getSCEVType()) {
852 case scUMaxExpr:
853 IntrinsicID = Intrinsic::umax;
854 break;
855 case scSMaxExpr:
856 IntrinsicID = Intrinsic::smax;
857 break;
858 case scUMinExpr:
859 IntrinsicID = Intrinsic::umin;
860 break;
861 case scSMinExpr:
862 IntrinsicID = Intrinsic::smin;
863 break;
864 default:
865 llvm_unreachable("Unexpected min/max SCEV type");
866 }
867 // Chain operands in reverse order matching SCEVExpander's expansion of
868 // min/max expressions.
870 for (const SCEVUse &Op : reverse(MinMax->operands())) {
871 VPValue *OpV = tryToExpand(Op);
872 if (!OpV)
873 return nullptr;
874 Ops.push_back(OpV);
875 }
876 Type *ResultTy = MinMax->getType();
877 VPValue *Result = Ops.front();
878 for (VPValue *Op : drop_begin(Ops))
879 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
880 ResultTy, DL);
881 return Result;
882 }
883 default:
884 return nullptr;
885 }
886}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
#define I(x, y, z)
Definition MD5.cpp:57
This file provides utility analysis objects describing memory locations.
static unsigned getScalarSizeInBits(Type *Ty)
This file implements the TypeSwitch template, which mimics a switch() statement whose cases are type ...
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
static bool propagatesPoisonFromRecipeOp(const VPRecipeBase *R)
Returns true if R propagates poison from any operand to its result.
static bool preservesUniformity(unsigned Opcode)
Returns true if Opcode preserves uniformity, i.e., if all operands are uniform, the result will also ...
static bool poisonGuaranteesUB(const VPValue *V)
Returns true if V being poison is guaranteed to trigger UB because it propagates to the address of a ...
static const uint32_t IV[8]
Definition blake3_impl.h:83
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags noUnsignedWrap()
static GEPNoWrapFlags none()
bool isCast() const
bool isBinaryOp() const
bool isUnaryOp() const
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1069
Representation for a specific memory location.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEV * getPredicatedSCEV(const SCEV *Expr)
Returns the rewritten SCEV for Expr in the context of the current SCEV predicate.
static LLVM_ABI void dropPoisonGeneratingAnnotationsAndReinfer(ScalarEvolution &SE, Instruction *I)
Drop poison-generating flags from I, then try re-infer via SCEV.
This class represents an analyzed expression in the program.
static constexpr auto FlagAnyWrap
static constexpr auto FlagNSW
SCEVTypes getSCEVType() const
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getUDivExpr(SCEVUse LHS, SCEVUse RHS)
Get a canonical unsigned division expression, or something simpler if possible.
LLVM_ABI bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
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 uint64_t getTypeSizeInBits(Type *Ty) const
Return the size in bits of the specified type, for which isSCEVable must return true.
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.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
Definition TypeSwitch.h:89
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
Definition TypeSwitch.h:98
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4357
iterator end()
Definition VPlan.h:4394
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:266
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4423
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
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:309
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:4155
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:3987
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2474
static VPIRFlags getDefaultFlags(unsigned Opcode)
Returns default flags for Opcode for opcodes that support it, asserts otherwise.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1217
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1306
unsigned getOpcode() const
Definition VPlan.h:1408
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:396
A recipe for handling reduction phis.
Definition VPlan.h:2839
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4582
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4658
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4738
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4694
VPValues defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:250
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3373
unsigned getOpcode() const
Definition VPlan.h:3466
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:4215
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:217
bool isMaterialized() const
Returns true if this value has been materialized.
Definition VPlanValue.h:235
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:399
operand_range operands()
Definition VPlanValue.h:472
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:1869
A recipe for handling GEP instructions.
Definition VPlan.h:2197
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2601
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1808
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4761
VPBasicBlock * getEntry()
Definition VPlan.h:4857
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:4962
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:5036
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1060
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5014
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4862
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:4959
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4906
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
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)
auto m_VScale()
Matches a call to llvm.vscale().
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.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(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.
AllRecipe_match< Opcode, Op0_t, Op1_t > m_Binary(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_match< Opcode, Op0_t > m_Unary(const Op0_t &Op0)
auto m_GetElementPtr(const Op0_t &Op0, const Op1_t &Op1)
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
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.
bool isElementwise(const VPValue *V)
Return true if V is elementwise, i.e. none of the lanes are permuted.
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.
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.
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
@ Offset
Definition DWP.cpp:573
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:1765
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:1739
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:250
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:285
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:1746
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1753
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
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:1772
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