LLVM 24.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/MapVector.h"
16#include "llvm/ADT/SetVector.h"
18#include "llvm/ADT/TypeSwitch.h"
27#include "llvm/IR/Dominators.h"
30
31using namespace llvm;
32using namespace llvm::VPlanPatternMatch;
33using namespace llvm::SCEVPatternMatch;
34
36 if (isa<VPBlendRecipe>(U))
37 return true;
38 auto *VPI = dyn_cast<VPInstruction>(U);
39 if (!VPI)
40 return false;
41 unsigned Opcode = VPI->getOpcode();
42 switch (Opcode) {
43 case Instruction::ExtractValue:
44 case Instruction::FCmp:
45 case Instruction::ICmp:
46 case Instruction::Select:
47 case Instruction::Freeze:
49 // TODO: Cover additional opcodes.
50 return true;
52 return Op != VPI->getOperand(0);
53 default:
54 return Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode);
55 }
56}
57
60 Worklist.insert(Def);
61 for (unsigned I = 0; I != Worklist.size(); ++I) {
62 const VPValue *Cur = Worklist[I];
63 for (const VPUser *U : Cur->users()) {
64 if (propagatesFirstLaneUse(U, Cur))
66 else if (!U->usesFirstLaneOnly(Cur))
67 return false;
68 }
69 }
70 return true;
71}
72
74 return all_of(Def->users(),
75 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
76}
77
79 return all_of(Def->users(),
80 [Def](const VPUser *U) { return U->usesScalars(Def); });
81}
82
84 if (auto *E = dyn_cast<SCEVConstant>(Expr))
85 return Plan.getOrAddLiveIn(E->getValue());
86 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
87 // value. Otherwise the value may be defined in a loop and using it directly
88 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
89 // form.
90 auto *U = dyn_cast<SCEVUnknown>(Expr);
91 if (U && !isa<Instruction>(U->getValue()))
92 return Plan.getOrAddLiveIn(U->getValue());
93 auto *Expanded = new VPExpandSCEVRecipe(Expr);
94 VPBasicBlock *EntryVPBB = Plan.getEntry();
95 auto Iter = EntryVPBB->getFirstNonPhi();
96 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
97 ++Iter;
98 EntryVPBB->insert(Expanded, Iter);
99 return Expanded;
100}
101
102/// Returns true if \p V being poison is guaranteed to trigger UB because it
103/// propagates to the address of a memory recipe.
104static bool poisonGuaranteesUB(const VPValue *V) {
107
108 auto PropagatesPoisonFromRecipeOp = [](const VPRecipeBase *R) {
110 return false;
111 unsigned Opcode = vputils::getOpcode(R->getVPSingleValue());
112 return Instruction::isCast(Opcode) || Opcode == Instruction::GetElementPtr;
113 };
114
115 Worklist.push_back(V);
116
117 while (!Worklist.empty()) {
118 const VPValue *Current = Worklist.pop_back_val();
119 if (!Visited.insert(Current).second)
120 continue;
121
122 for (VPUser *U : Current->users()) {
123 // Check if Current is used as an address operand for load/store.
124 auto *R = cast<VPRecipeBase>(U);
125 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(R)) {
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 for (const VPValue *Op : R->operands()) {
139 if (Op == Current && PropagatesPoisonFromRecipeOp(R)) {
140 Worklist.push_back(R->getVPSingleValue());
141 break;
142 }
143 }
144 }
145 }
146
147 return false;
148}
149
151 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
152 // casts to find a root GEP VPInstruction.
153 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
154 unsigned Opcode = PtrVPI->getOpcode();
155 if (Opcode == Instruction::GetElementPtr) {
156 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
157 return PtrVPI->getGEPNoWrapFlags();
158 Ptr = PtrVPI->getOperand(0);
159 continue;
160 }
161 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
162 break;
163 Ptr = PtrVPI->getOperand(0);
164 }
165 return GEPNoWrapFlags::none();
166}
167
170 const Loop *L) {
171 ScalarEvolution &SE = *PSE.getSE();
172 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
173 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
174 "RegionValue must be canonical IV");
175 if (!L)
176 return SE.getCouldNotCompute();
177 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
178 L, SCEV::FlagNone);
179 }
180
182 Value *LiveIn = V->getUnderlyingValue();
183 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
184 return SE.getSCEV(LiveIn);
185 return SE.getCouldNotCompute();
186 }
187
188 // Helper to create SCEVs for binary and unary operations.
189 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
190 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
191 -> const SCEV * {
193 for (VPValue *Op : Ops) {
194 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
196 return SE.getCouldNotCompute();
197 SCEVOps.push_back(S);
198 }
199 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
200 };
201
202 VPValue *LHSVal, *RHSVal;
203 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
204 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
205 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
206 });
207 if (match(V, m_BinaryOr(m_VPValue(LHSVal), m_VPValue(RHSVal))))
208 if (cast<VPRecipeWithIRFlags>(V->getDefiningRecipe())->isDisjoint())
209 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
210 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
211 });
212 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
213 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
214 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagNone, 0);
215 });
216 if (match(V, m_Not(m_VPValue(LHSVal)))) {
217 // not X = xor X, -1 = -1 - X
218 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
219 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
220 });
221 }
222 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
223 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
224 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
225 });
226 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
227 // amount >= the bit width produces poison; do not rewrite it, as
228 // getPowerOfTwo requires the power to be in range.
229 uint64_t ShiftAmt;
230 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
231 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
232 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
233 return SE.getMulExpr(Ops[0],
234 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
235 });
236 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
237 Type *Ty = V->getScalarType();
238 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
239 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
240 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
241 });
242 }
243 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
244 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
245 return SE.getUDivExpr(Ops[0], Ops[1]);
246 });
247 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
248 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
249 return SE.getURemExpr(Ops[0], Ops[1]);
250 });
251 // A SDiv with non-negative operands is equivalent to an UDiv.
252 if (match(V, m_SDiv(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
253 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
254 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
255 return SE.getCouldNotCompute();
256 return SE.getUDivExpr(Ops[0], Ops[1]);
257 });
258 }
259 // A SRem with non-negative operands is equivalent to an URem.
260 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
261 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
262 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
263 return SE.getCouldNotCompute();
264 return SE.getURemExpr(Ops[0], Ops[1]);
265 });
266 }
267 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
268 const APInt *Mask;
269 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
270 (*Mask + 1).isPowerOf2())
271 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
272 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
273 });
274 // SCEV models ptrtoaddr, but not ptrtoint, mirroring createSCEV.
275 if (match(V, m_PtrToAddr(m_VPValue(LHSVal))))
276 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
277 return SE.getPtrToAddrExpr(Ops[0]);
278 });
279 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
280 Type *DestTy = V->getScalarType();
281 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
282 return SE.getTruncateExpr(Ops[0], DestTy);
283 });
284 }
285 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
286 Type *DestTy = V->getScalarType();
287 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
288 return SE.getZeroExtendExpr(Ops[0], DestTy);
289 });
290 }
291 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
292 Type *DestTy = V->getScalarType();
293
294 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
295 // onto the operands before computing the subtraction.
296 VPValue *SubLHS, *SubRHS;
297 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
298 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
299 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
300 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
301 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
303 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
304 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
305 }
306
307 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
308 return SE.getSignExtendExpr(Ops[0], DestTy);
309 });
310 }
311 if (match(V,
313 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
314 return SE.getUMaxExpr(Ops[0], Ops[1]);
315 });
316 if (match(V,
318 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
319 return SE.getSMaxExpr(Ops[0], Ops[1]);
320 });
321 if (match(V,
323 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
324 return SE.getUMinExpr(Ops[0], Ops[1]);
325 });
326 if (match(V,
328 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
329 return SE.getSMinExpr(Ops[0], Ops[1]);
330 });
332 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
333 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
334 // not proof that the input is never INT_MIN, nor that poison reaches
335 // UB. Do not translate it to SCEV's global IsNSW flag.
336 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
337 });
338
340 Type *SourceElementType;
341 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
342 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
343 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
344 });
345 }
346
347 // TODO: Support constructing SCEVs for more recipes as needed.
348 const VPRecipeBase *DefR = V->getDefiningRecipe();
349 const SCEV *Expr =
351 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
352 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
353 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
354 if (!L || isa<SCEVCouldNotCompute>(Step))
355 return SE.getCouldNotCompute();
356 const SCEV *Start =
357 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
358 const SCEV *AddRec =
359 SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
360 if (R->isTruncated())
361 return SE.getTruncateExpr(AddRec, R->getScalarType());
362 return AddRec;
363 })
364 .Case([&SE, &PSE,
365 L](const VPWidenPointerInductionRecipe *R) -> const SCEV * {
366 const SCEV *Start =
367 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
368 if (!L || isa<SCEVCouldNotCompute>(Start))
369 return SE.getCouldNotCompute();
370 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
371 if (isa<SCEVCouldNotCompute>(Step))
372 return SE.getCouldNotCompute();
373 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
374 })
375 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) -> const SCEV * {
376 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
377 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
378 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
379 if (any_of(ArrayRef({Start, IV, Scale}),
381 return SE.getCouldNotCompute();
382
383 return SE.getAddExpr(
384 SE.getTruncateOrSignExtend(Start, IV->getType()),
385 SE.getMulExpr(
386 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
387 })
388 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
389 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
390 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
392 return SE.getCouldNotCompute();
393 return SE.getTruncateOrSignExtend(IV, Step->getType());
394 })
395 .Default(
396 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
397
398 return PSE.getPredicatedSCEV(Expr);
399}
400
401std::optional<int64_t>
403 PredicatedScalarEvolution &PSE, const Loop *L) {
404 assert(!hasIrregularType(AccessTy, L->getHeader()->getDataLayout()) &&
405 "should not try to widen irregular types");
406 const SCEV *AddrSCEV = getSCEVExprForVPValue(Addr, PSE, L);
407 auto *AddRec = dyn_cast<SCEVAddRecExpr>(AddrSCEV);
408 if (!AddRec)
409 return {};
410
411 return getStrideFromAddRec(AddRec, L, AccessTy, /*Ptr=*/nullptr, PSE);
412}
413
415 const Loop *L) {
416 // If address is an SCEVAddExpr, we require that all operands must be either
417 // be invariant or a (possibly sign-extend) affine AddRec.
418 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
419 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
420 return SE.isLoopInvariant(Op, L) ||
421 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
422 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
423 });
424 }
425
426 // Otherwise, check if address is loop invariant or an affine add recurrence.
427 return SE.isLoopInvariant(Addr, L) ||
429}
430
431unsigned vputils::getOpcode(const VPValue *V) {
435 VPWidenLoadEVLRecipe>([](auto *I) { return I->getOpcode(); })
436 .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe, VPScalarIVStepsRecipe>(
437 [](auto *I) {
438 // For recipes that do not directly map to LLVM IR instructions,
439 // assign opcodes after the last VPInstruction opcode (which is also
440 // after the last IR Instruction opcode), based on the VPRecipeID.
441 return VPInstruction::OpsEnd + 1 + I->getVPRecipeID();
442 })
443 .Default([](auto *) { return 0; });
444}
445
446std::optional<std::pair<bool, unsigned>>
449 return std::make_pair(true, IID);
450 if (unsigned Opcode = vputils::getOpcode(V))
451 return std::make_pair(false, Opcode);
452 return {};
453}
454
455/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
456/// uniform, the result will also be uniform.
457static bool preservesUniformity(unsigned Opcode) {
458 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
459 return true;
460 switch (Opcode) {
461 case Instruction::Freeze:
462 case Instruction::GetElementPtr:
463 case Instruction::ICmp:
464 case Instruction::FCmp:
465 case Instruction::Select:
470 return true;
471 default:
472 return false;
473 }
474}
475
477 // TODO: Handle more opcodes and recipes.
479 return false;
480 unsigned Opcode = getOpcode(V);
481 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
482}
483
485 // Live-in, symbolic and canonical-IV region values are single-scalar.
486 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
487 return RV == RV->getDefiningRegion()->getCanonicalIV();
489 return true;
490
491 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
492 const VPRegionBlock *RegionOfR = Rep->getRegion();
493 // Don't consider recipes in replicate regions as uniform yet; their first
494 // lane cannot be accessed when executing the replicate region for other
495 // lanes.
496 if (RegionOfR && RegionOfR->isReplicator())
497 return false;
498 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
499 all_of(Rep->operands(), isSingleScalar));
500 }
503 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
504 return preservesUniformity(WidenR->getOpcode()) &&
505 all_of(WidenR->operands(), isSingleScalar);
506 }
507 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
508 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
509 (preservesUniformity(VPI->getOpcode()) &&
510 all_of(VPI->operands(), isSingleScalar));
511 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
512 return !RR->isPartialReduction();
514 VPV))
515 return true;
516 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
517 return Expr->isVectorToScalar();
518
519 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
520 return isa<VPExpandSCEVRecipe>(VPV);
521}
522
524 // Live-ins, symbolic and canonical-IV region values are uniform.
525 if (auto *RV = dyn_cast<VPRegionValue>(V))
526 return RV == RV->getDefiningRegion()->getCanonicalIV();
528 return true;
529
530 const VPRecipeBase *R = V->getDefiningRecipe();
531 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
532 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
533 if (VPBB &&
534 (VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
535 if (match(R,
538 return false;
539 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
540 }
541
543 .Case([](const VPDerivedIVRecipe *R) { return true; })
544 .Case([](const VPReplicateRecipe *R) {
545 // Be conservative about side-effects, except for the
546 // known-side-effecting assumes and stores, which we know will be
547 // uniform. Each alloca creates a distinct allocation, so allocas are
548 // never uniform.
549 return R->isSingleScalar() && R->getOpcode() != Instruction::Alloca &&
550 (!R->mayHaveSideEffects() ||
551 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
552 all_of(R->operands(), isUniformAcrossVFsAndUFs);
553 })
554 .Case([](const VPWidenRecipe *R) {
555 return preservesUniformity(R->getOpcode()) &&
556 all_of(R->operands(), isUniformAcrossVFsAndUFs);
557 })
558 .Case([](const VPPhi *) {
559 // Bail out on VPPhi, as we can end up in infinite cycles.
560 return false;
561 })
562 .Case([](const VPInstruction *VPI) {
563 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
566 })
567 .Case([](const VPWidenCastRecipe *R) {
568 // A cast is uniform according to its operand.
569 return isUniformAcrossVFsAndUFs(R->getOperand(0));
570 })
571 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
572 // unless proven otherwise.
573 return false;
574 });
575}
576
578 if (auto *RepR = dyn_cast<VPReplicateRecipe>(R))
579 return RepR->doesGeneratePerAllLanes();
580 if (auto *VPI = dyn_cast<VPInstruction>(R))
581 return VPI->doesGeneratePerAllLanes();
582 if (auto *SIVSteps = dyn_cast<VPScalarIVStepsRecipe>(R))
583 return SIVSteps->doesGeneratePerAllLanes();
584 return false;
585}
586
588 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
589 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
590 return VPBlockUtils::isHeader(VPB, VPDT);
591 });
592 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
593}
594
596 if (!R)
597 return 1;
598 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
599 return RR->getVFScaleFactor();
600 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
601 return RR->getVFScaleFactor();
602 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
603 return ER->getVFScaleFactor();
604 assert(
607 "getting scaling factor of reduction-start-vector not implemented yet");
608 return 1;
609}
610
611bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
612 // Assumes don't alias anything or throw; as long as they're guaranteed to
613 // execute, they're safe to hoist. They should however not be sunk, as it
614 // would destroy information.
616 return Sinking;
617 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
618 return true;
619 // Allocas cannot be hoisted.
620 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
621 return RepR && RepR->getOpcode() == Instruction::Alloca;
622}
623
626 VPBasicBlock *LastBB) {
627 assert(FirstBB->getParent() == LastBB->getParent() &&
628 "FirstBB and LastBB from different regions");
629#ifndef NDEBUG
630 bool InSingleSuccChain = false;
631 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
632 InSingleSuccChain |= (Succ == LastBB);
633 assert(InSingleSuccChain &&
634 "LastBB unreachable from FirstBB in single-successor chain");
635#endif
636 auto Blocks = to_vector(
638 auto *LastIt = find(Blocks, LastBB);
639 assert(LastIt != Blocks.end() &&
640 "LastBB unreachable from FirstBB in depth-first traversal");
641 Blocks.erase(std::next(LastIt), Blocks.end());
642 return Blocks;
643}
644
646 for (VPRecipeBase &R : *Plan.getVectorPreheader())
648 return cast<VPInstruction>(&R);
649 return nullptr;
650}
651
653vputils::getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB) {
655 for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks())
656 for (VPBlockBase *Pred : ExitVPBB->getPredecessors())
657 if (Pred != MiddleVPBB)
658 Exits.emplace_back(cast<VPBasicBlock>(Pred), ExitVPBB);
659 return Exits;
660}
661
664 Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp,
665 Type *ResultTy, VPValue *StartV, VPValue *Step, DebugLoc DL,
666 VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags) {
667 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
668 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
669 VPValue *CanonicalIV = LoopRegion->getCanonicalIV();
670 VPValue *BaseIV =
671 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
672
673 // Truncate BaseIV and Step to ResultTy.
674 if (ResultTy->isIntegerTy()) {
675 [[maybe_unused]] Type *BaseIVTy = BaseIV->getScalarType();
676 assert(BaseIVTy->isIntegerTy() && "Integral BaseIV type expected");
677 assert(BaseIVTy->getPrimitiveSizeInBits() >=
678 ResultTy->getPrimitiveSizeInBits() &&
679 "BaseIV's type must be at least as large as ResultTy");
680 BaseIV = Builder.createScalarZExtOrTrunc(BaseIV, ResultTy, DL);
681 [[maybe_unused]] Type *StepTy = Step->getScalarType();
682 assert(StepTy->isIntegerTy() && "Integral Step type expected");
683 assert(StepTy->getPrimitiveSizeInBits() >=
684 ResultTy->getPrimitiveSizeInBits() &&
685 "Step's type must be at least as large as ResultTy");
686 auto *VecPreheader =
688 VPBuilder::InsertPointGuard Guard(Builder);
689 Builder.setInsertPoint(VecPreheader);
690 Step = Builder.createScalarZExtOrTrunc(Step, ResultTy, DL);
691 }
692 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
693 &Plan.getVF(), DL);
694}
695
696VPValue *
698 VPlan &Plan, VPBuilder &Builder) {
699 const InductionDescriptor &ID = PtrIV->getInductionDescriptor();
700 VPIRValue *StartV = Plan.getZero(ID.getStep()->getType());
701 VPValue *StepV = PtrIV->getOperand(1);
703 Plan, InductionDescriptor::IK_IntInduction, Instruction::Add, nullptr,
704 StartV->getScalarType(), StartV, StepV, PtrIV->getDebugLoc(), Builder);
705
706 return Builder.createPtrAdd(PtrIV->getStartValue(), Steps,
707 PtrIV->getDebugLoc(), "next.gep");
708}
709
711 const VPDominatorTree &VPDT) {
712 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
713 if (!VPBB)
714 return false;
715
716 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
717 // VPBB as its entry, i.e., free of predecessors.
718 if (auto *R = VPBB->getParent())
719 return !R->isReplicator() && !VPBB->hasPredecessors();
720
721 // A header dominates its second predecessor (the latch), with the other
722 // predecessor being the preheader
723 return VPB->getPredecessors().size() == 2 &&
724 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
725}
726
728 const VPDominatorTree &VPDT) {
729 // A latch has a header as its last successor, with its other successors
730 // leaving the loop. A preheader OTOH has a header as its first (and only)
731 // successor.
732 return VPB->getNumSuccessors() >= 2 &&
734}
735
736std::pair<VPBasicBlock *, VPBasicBlock *>
739 Plan.getEntry()->getNumSuccessors() == 1
740 ? Plan.getEntry()->getSingleSuccessor()
741 : Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
742 assert(Header->getNumPredecessors() == 2 &&
743 "Header must have exactly 2 predecessors");
744 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
745 return {Header, Latch};
746}
747
751
753 const VPPhi *PhiR) {
754 if (ID.getKind() == InductionDescriptor::IK_FpInduction)
755 return ID.getInductionBinOp()->getFastMathFlags();
756
757 // The flags only bound the induction values if the increment directly
758 // updates PhiR.
759 VPValue *Inc = PhiR->getOperand(1);
760 if (match(Inc, m_c_Add(m_Specific(PhiR), m_VPValue())))
761 return cast<VPInstruction>(Inc)->getNoWrapFlagsOrNone();
762
763 if (match(Inc, m_Sub(m_Specific(PhiR), m_VPValue()))) {
764 // The step of a sub induction is negated, so NUW cannot be preserved. NSW
765 // can, if the step is not the signed minimum.
766 ConstantInt *Step = ID.getConstIntStepValue();
767 bool NSW = cast<VPInstruction>(Inc)->getNoWrapFlagsOrNone().HasNSW &&
768 Step && !Step->isMinValue(/*IsSigned=*/true);
769 return VPIRFlags::WrapFlagsTy(/*NUW*/ false, NSW);
770 }
771
772 return VPIRFlags::WrapFlagsTy(false, false);
773}
774
775std::optional<MemoryLocation>
777 auto *M = dyn_cast<VPIRMetadata>(&R);
778 if (!M)
779 return std::nullopt;
781 // Populate noalias metadata from VPIRMetadata.
782 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
783 Loc.AATags.NoAlias = NoAliasMD;
784 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
785 Loc.AATags.Scope = AliasScopeMD;
786 return Loc;
787}
788
790 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
791 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
792 assert(CanIV && "Expected loop region to have a canonical IV");
793
794 VPSymbolicValue &VFxUF = Plan.getVFxUF();
795
796 // Check if \p Step matches the expected increment step, accounting for
797 // materialization of VFxUF and UF.
798 auto IsIncrementStep = [&](VPValue *Step) -> bool {
799 if (!VFxUF.isMaterialized())
800 return Step == &VFxUF;
801
802 VPSymbolicValue &UF = Plan.getUF();
803 if (!UF.isMaterialized())
804 return Step == &UF ||
805 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
806
807 // Alias masking: step is number of active lanes of a dependence mask.
808 if (match(Step, m_ZExtOrTruncOrSelf(
810 return true;
811
812 unsigned ConcreteUF = Plan.getConcreteUF();
813 // Fixed VF: step is just the concrete UF.
814 if (match(Step, m_SpecificInt(ConcreteUF)))
815 return true;
816
817 // Scalable VF: step involves VScale.
818 if (ConcreteUF == 1)
819 return match(Step, m_VScale());
820 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
821 return true;
822 // mul(VScale, ConcreteUF) may have been simplified to
823 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
824 return isPowerOf2_32(ConcreteUF) &&
825 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
826 };
827
828 VPInstruction *Increment = nullptr;
829 for (VPUser *U : CanIV->users()) {
830 VPValue *Step;
831 if (isa<VPInstruction>(U) &&
832 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
833 IsIncrementStep(Step)) {
834 assert(!Increment && "There must be a unique increment");
836 }
837 }
838
839 assert((!VFxUF.isMaterialized() || Increment) &&
840 "After materializing VFxUF, an increment must exist");
841 assert((!Increment ||
842 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
843 "NUW flag in region and increment must match");
844 return Increment;
845}
846
847/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
848/// inserted for predicated reductions or tail folding.
850 VPValue *BackedgeVal = PhiR->getBackedgeValue();
851 if (auto *Res =
853 return Res;
854
855 // Look through selects inserted for tail folding or predicated reductions.
856 VPRecipeBase *SelR =
857 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
858 if (!SelR)
859 return nullptr;
862}
863
866 SmallVector<const VPValue *> WorkList = {V};
867
868 while (!WorkList.empty()) {
869 const VPValue *Cur = WorkList.pop_back_val();
870 if (!Seen.insert(Cur).second)
871 continue;
872
873 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
874 // Skip blends that use V only through a compare by checking if any incoming
875 // value was already visited.
876 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
877 [&](unsigned I) {
878 return Seen.contains(Blend->getIncomingValue(I));
879 }))
880 continue;
881
882 for (VPUser *U : Cur->users()) {
883 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
884 if (InterleaveR->getAddr() == Cur)
885 return true;
886 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
887 // store (operand 1).
890 m_Specific(Cur)))))
891 return true;
893 if (MemR->getAddr() == Cur && MemR->isConsecutive())
894 return true;
895 }
896 }
897
898 // The legacy cost model only supports scalarization loads/stores with phi
899 // addresses, if the phi is directly used as load/store address. Don't
900 // traverse further for Blends and first-order recurrence splices.
901 if (Blend ||
902 match(Cur,
904 continue;
905
906 // Only traverse further through users that also define a value (and can
907 // thus have their own users walked). Skip when Cur is only used as mask ,
908 // as well as loads: a loaded value does not depend on the load's operand.
909 for (VPUser *U : Cur->users()) {
910 auto *VPI = dyn_cast<VPInstruction>(U);
911 if (VPI && VPI->getMask() == Cur &&
912 none_of(VPI->operandsWithoutMask(), equal_to(Cur)))
913 continue;
915 continue;
916 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
917 WorkList.push_back(SDR);
918 }
919 }
920 return false;
921}
922
923/// Try to find a loop-invariant IR value for \p S in the plan's entry block
924/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
925/// if no reusable IR value is found.
926VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
928 return nullptr;
929 VPlan &Plan = Builder.getPlan();
930 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
931 for (Value *V : SE.getSCEVValues(S)) {
932 // Only reuse instructions in the plan's entry block, or, when a
933 // DominatorTree is available, any instruction that dominates it.
934 // Instructions in sibling branches may not dominate the entry block.
935 auto *I = dyn_cast<Instruction>(V);
936 if (!I)
937 return Plan.getOrAddLiveIn(V);
938 if (!SE.DT.dominates(I->getParent(), PH))
939 continue;
940 Loop *IL = SE.LI.getLoopFor(I->getParent());
941 if (IL && !IL->contains(PH))
942 continue;
943 SmallVector<Instruction *> DropPoisonGeneratingInsts;
944 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
945 continue;
946 for (Instruction *DropI : DropPoisonGeneratingInsts)
948 return Plan.getOrAddLiveIn(V);
949 }
950 return nullptr;
951}
952
953VPValue *VPSCEVExpander::expandAsPtrAdd(const SCEVNAryExpr *S) {
954 VPValue *Base = expand(SE.getPointerBase(S));
955 VPValue *Offset = expand(SE.removePointerBase(S));
956 GEPNoWrapFlags GEPFlags = S->hasNoUnsignedWrap()
958 : GEPNoWrapFlags::none();
959 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
960}
961
963 if (VPValue *V = tryToReuseIRValue(S))
964 return V;
965
966 switch (S->getSCEVType()) {
967 case scConstant:
968 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
969 case scUnknown:
970 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
971 case scVScale:
972 return Builder.createVScale(S->getType(), DL);
973 case scAddExpr: {
974 auto *AddE = cast<SCEVAddExpr>(S);
975 VPIRFlags::WrapFlagsTy WrapFlags(AddE->hasNoUnsignedWrap(),
976 AddE->hasNoSignedWrap());
977
978 // Expand pointer SCEVAddExpr as a ptradd of the pointer base and the
979 // integer offset, matching SCEVExpander.
980 if (S->getType()->isPointerTy())
981 return expandAsPtrAdd(AddE);
982
983 // Non-constant-negative add operands are expanded negated and subtracted
984 // from the running result below, instead of being negated and added.
985 auto UseSubtract = [](const SCEV *Op) {
986 return Op->isNonConstantNegative();
987 };
988 // Iterate in reverse so that constants are emitted last, and move the
989 // subtracted operands last, matching SCEVExpander's LoopCompare, so that
990 // they don't start the running result.
991 SmallVector<const SCEV *, 2> SCEVOps(reverse(AddE->operands()));
992 stable_sort(SCEVOps, [&](const SCEV *L, const SCEV *R) {
993 return !UseSubtract(L) && UseSubtract(R);
994 });
996 for (const SCEV *Op : SCEVOps) {
997 // The first operand starts the result, so it is never subtracted.
998 bool Negate = !Ops.empty() && UseSubtract(Op);
999 Ops.push_back(expand(Negate ? SE.getNegativeSCEV(Op) : Op));
1000 }
1001 VPValue *Result = Ops.front();
1002 for (auto [Op, OpV] : drop_begin(zip_equal(SCEVOps, Ops))) {
1003 if (UseSubtract(Op)) {
1004 // Result + (-Op) == Result - Op, which saves the multiply for the
1005 // negation. NSW only transfers if negating Op cannot overflow, see
1006 // ScalarEvolution::getMinusSCEV.
1007 bool HasNSW =
1008 WrapFlags.HasNSW && !SE.getSignedRangeMin(Op).isMinSignedValue();
1009 Result = Builder.createOverflowingOp(Instruction::Sub, {Result, OpV},
1010 {/*HasNUW=*/false, HasNSW}, DL);
1011 continue;
1012 }
1013 Result = Builder.createOverflowingOp(Instruction::Add, {Result, OpV},
1014 WrapFlags, DL);
1015 }
1016 return Result;
1017 }
1018 case scMulExpr: {
1019 auto *MulE = cast<SCEVMulExpr>(S);
1020 VPIRFlags::WrapFlagsTy WrapFlags(MulE->hasNoUnsignedWrap(),
1021 MulE->hasNoSignedWrap());
1023 for (const SCEV *Op : reverse(MulE->operands()))
1024 Ops.push_back(expand(Op));
1025 VPValue *Result = Ops.front();
1026 for (VPValue *OpV : drop_begin(Ops)) {
1027 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, OpV},
1028 WrapFlags, DL);
1029 }
1030 return Result;
1031 }
1032 case scUDivExpr: {
1033 auto *UDiv = cast<SCEVUDivExpr>(S);
1034 VPValue *LHS = expand(UDiv->getLHS());
1035 const SCEV *RHSExpr = UDiv->getRHS();
1036 VPValue *RHS = expand(RHSExpr);
1037 if (SafeUDivMode) {
1038 // Make sure the UDiv's divisor is guaranteed to not be zero/poison, to
1039 // avoid UB.
1040 Type *Ty = UDiv->getType();
1041 bool GuaranteedNotPoison =
1043 if (!GuaranteedNotPoison)
1044 RHS = Builder.createFreeze(RHS, DL);
1045 if (!SE.isKnownNonZero(RHSExpr) || !GuaranteedNotPoison)
1046 RHS = Builder.createScalarIntrinsic(
1047 Intrinsic::umax, {RHS, Builder.getPlan().getConstantInt(Ty, 1)}, Ty,
1048 DL);
1049 }
1050 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
1051 VPIRFlags::getDefaultFlags(Instruction::UDiv),
1052 DL);
1053 }
1054 case scTruncate:
1055 case scZeroExtend:
1056 case scSignExtend:
1057 case scPtrToAddr: {
1058 auto *Cast = cast<SCEVCastExpr>(S);
1059 VPValue *Op = expand(Cast->getOperand());
1060 Instruction::CastOps Opcode;
1061 switch (S->getSCEVType()) {
1062 case scTruncate:
1063 Opcode = Instruction::Trunc;
1064 break;
1065 case scZeroExtend:
1066 Opcode = Instruction::ZExt;
1067 break;
1068 case scSignExtend:
1069 Opcode = Instruction::SExt;
1070 break;
1071 case scPtrToAddr:
1072 Opcode = Instruction::PtrToAddr;
1073 break;
1074 default:
1075 llvm_unreachable("Unhandled cast SCEV");
1076 }
1077
1078 // For ptrtoaddr of an IR value, reuse an existing cast dominating the
1079 // entry if there is one. Otherwise leave it to SCEVExpander, which places
1080 // the cast right after the IR value's definition, so all users can share
1081 // it.
1082 if (Opcode == Instruction::PtrToAddr) {
1083 VPlan &Plan = Builder.getPlan();
1084 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1085 if (auto *IRV = dyn_cast<VPIRValue>(Op)) {
1087 IRV->getValue(), S->getType(), PH->getDataLayout(),
1088 [&](const CastInst *CI) {
1089 return SE.DT.dominates(CI->getParent(), PH);
1090 }))
1091 return Plan.getOrAddLiveIn(CI);
1093 }
1094 }
1095
1096 std::optional<VPIRFlags> Flags;
1097 if (Opcode == Instruction::ZExt)
1098 Flags =
1099 VPIRFlags::NonNegFlagsTy(SE.isKnownNonNegative(Cast->getOperand()));
1100
1101 return Builder.createScalarCast(Opcode, Op, S->getType(), DL, Flags);
1102 }
1103 case scUMaxExpr:
1104 case scSMaxExpr:
1105 case scUMinExpr:
1106 case scSMinExpr:
1107 case scSequentialUMinExpr: {
1108 auto *MinMax = cast<SCEVNAryExpr>(S);
1109 Intrinsic::ID IntrinsicID;
1110 switch (S->getSCEVType()) {
1111 case scUMaxExpr:
1112 IntrinsicID = Intrinsic::umax;
1113 break;
1114 case scSMaxExpr:
1115 IntrinsicID = Intrinsic::smax;
1116 break;
1117 case scUMinExpr:
1119 IntrinsicID = Intrinsic::umin;
1120 break;
1121 case scSMinExpr:
1122 IntrinsicID = Intrinsic::smin;
1123 break;
1124 default:
1125 llvm_unreachable("Unexpected min/max SCEV type");
1126 }
1127 // Chain operands in reverse order matching SCEVExpander's expansion of
1128 // min/max expressions. In SafeUDivMode freeze expansion results of operands
1129 // other than the first for sequential UMins, to avoid short-circuiting
1130 // divide-by-0/poison.
1131 bool IsSequential = S->getSCEVType() == scSequentialUMinExpr;
1132 Type *ResultTy = MinMax->getType();
1133 bool PrevSafeMode = SafeUDivMode;
1135 for (const SCEV *SCEVOp : reverse(MinMax->operands())) {
1136 bool MayShortCircuit =
1137 IsSequential && Ops.size() != MinMax->getNumOperands() - 1;
1138 SafeUDivMode = MayShortCircuit || PrevSafeMode;
1139 VPValue *OpV = expand(SCEVOp);
1140 SafeUDivMode = PrevSafeMode;
1141 if (MayShortCircuit)
1142 OpV = Builder.createFreeze(OpV, DL);
1143 Ops.push_back(OpV);
1144 }
1145 VPValue *Result = Ops.front();
1146 for (VPValue *Op : drop_begin(Ops)) {
1147 if (!ResultTy->isPointerTy()) {
1148 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
1149 ResultTy, DL);
1150 continue;
1151 }
1152 // The min/max intrinsics don't support pointer operands, so expand
1153 // pointer-typed min/max as cmp + select, matching SCEVExpander.
1154 VPValue *Cmp = Builder.createICmp(
1155 MinMaxIntrinsic::getPredicate(IntrinsicID), Result, Op, DL);
1156 Result = Builder.createSelect(Cmp, Result, Op, DL);
1157 Function &F = *Builder.getPlan().getIRFunction();
1158 if (MDNode *MD =
1160 cast<VPInstruction>(Result)->setMetadata(LLVMContext::MD_prof, MD);
1161 }
1162 return Result;
1163 }
1164 case scAddRecExpr: {
1165 auto *AR = cast<SCEVAddRecExpr>(S);
1166 VPlan &Plan = Builder.getPlan();
1167 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1168 assert(SE.DT.dominates(AR->getLoop()->getHeader(), PH) &&
1169 "can only expand AddRecs for loops outside VPlan's scope");
1170
1171 Type *Ty = AR->getType();
1172 if (auto [LCSSAPhi, Diff] = SCEVExpander::findReusableLCSSAPhi(SE, AR, PH);
1173 LCSSAPhi) {
1174 VPValue *DiffV = expand(Diff);
1175 VPValue *BaseV = Plan.getOrAddLiveIn(LCSSAPhi);
1176 if (LCSSAPhi->getType()->isPointerTy()) {
1177 if (Ty->isPointerTy())
1178 return Builder.createPtrAdd(BaseV, DiffV, DL);
1179 BaseV = Builder.createScalarCast(Instruction::PtrToAddr, BaseV, Ty, DL);
1180 }
1181 return Builder.createAdd(BaseV, DiffV, DL);
1182 }
1183
1184 // Mirror SCEVExpander::visitAddRecExpr, but only expand the canonical IV
1185 // {0,+,1} and non-affine AddRecs to IR (which will be created outside the
1186 // scope of VPlan). The AddRec is then scaled and offset using
1187 // VPInstructions.
1188 const Loop *L = AR->getLoop();
1189 auto m_scev_CanonicalIV = // NOLINT
1191 if (!AR->isAffine() || match(AR, m_scev_CanonicalIV))
1193
1194 const SCEV *Step = AR->getStepRecurrence(SE);
1195 // {0,+,F} --> {0,+,1} * F
1196 if (AR->getStart()->isZero()) {
1197 const SCEV *CanIV =
1198 SE.getAddRecExpr(SE.getZero(Ty), SE.getOne(Ty), L, SCEV::FlagNone);
1199 return Builder.createOverflowingOp(
1200 Instruction::Mul, {expand(CanIV), expand(Step)},
1201 {SE.willNotOverflow(Instruction::Mul, /*Signed=*/false, CanIV, Step),
1202 SE.willNotOverflow(Instruction::Mul, /*Signed=*/true, CanIV, Step)},
1203 DL);
1204 }
1205
1206 // {X,+,F} --> X + {0,+,F}
1207 if (Ty->isPointerTy())
1208 return expandAsPtrAdd(AR);
1209 VPValue *Start = expand(AR->getStart());
1210 VPValue *Rest = expand(SE.getAddRecExpr(SE.getZero(Ty), Step, L,
1211 AR->getNoWrapFlags(SCEV::FlagNW)));
1212 return Builder.createAdd(Start, Rest, DL, "",
1213 {AR->hasNoUnsignedWrap(), false});
1214 }
1215 case scCouldNotCompute:
1216 llvm_unreachable("Attempt to expand a SCEVCouldNotCompute");
1217 }
1218 llvm_unreachable("Unknown SCEV kind!");
1219}
1220
1222 // Do remove conditional assume instructions as their conditions may be
1223 // flattened.
1224 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1225 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1227 if (IsConditionalAssume)
1228 return true;
1229
1230 if (R.mayHaveSideEffects())
1231 return false;
1232
1233 // Forbid removing trip-count expressions.
1234 if (isa<VPExpandSCEVRecipe>(R) &&
1235 R.getVPSingleValue() == R.getParent()->getPlan()->getTripCount())
1236 return false;
1237
1238 // Recipe is dead if no user keeps the recipe alive.
1239 return all_of(R.definedValues(), [](VPValue *V) { return V->user_empty(); });
1240}
1241
1243 SmallVector<VPValue *> WorkList;
1245 WorkList.push_back(V);
1246
1247 while (!WorkList.empty()) {
1248 VPValue *Cur = WorkList.pop_back_val();
1249 if (!Seen.insert(Cur).second)
1250 continue;
1251 VPRecipeBase *R = Cur->getDefiningRecipe();
1252 if (!R)
1253 continue;
1254 if (!isDeadRecipe(*R))
1255 continue;
1256 append_range(WorkList, R->operands());
1257 R->eraseFromParent();
1258 }
1259}
1260
1263 for (unsigned I = 0; I != Users.size(); ++I) {
1265 for (VPValue *V : Cur->definedValues())
1266 Users.insert_range(V->users());
1267 }
1268 return Users.takeVector();
1269}
1270
1271/// Returns \p Num / \p Denom as a BranchProbability, clamped so a ratio that is
1272/// neither zero nor one does not round to zero or one. BlockFrequencyInfo also
1273/// keeps a zero-weight edge distinguishable from an unreachable one.
1275 uint64_t Denom) {
1277 if (Num == 0 || Num == Denom)
1278 return P;
1279 return BranchProbability::getRaw(std::clamp(
1280 P.getNumerator(), 1u, BranchProbability::getDenominator() - 1));
1281}
1282
1288
1289/// Returns the probability of each successor edge of \p VPBB, computed via
1290/// BranchProbabilityInfo::getEdgeProbabilitiesFromWeights from the branch
1291/// weights recorded on its terminator, or std::nullopt if not available.
1292static std::optional<SmallVector<BranchProbability>>
1294 // With a single successor the edge is always taken and needs no weights.
1295 if (VPBB->getSingleSuccessor())
1297
1298 SmallVector<uint32_t> Weights;
1300 if (!Term || !extractBranchWeights(Term->getBranchWeights(), Weights) ||
1301 Weights.size() != VPBB->getNumSuccessors())
1302 return std::nullopt;
1304}
1305
1308 using BFIBase = BlockFrequencyInfoImplBase;
1309 assert(!Blocks.empty() && "expected at least the header block");
1310 // Distribute the header's frequency using BFI. Nodes for blocks are numbered
1311 // in reverse post-order. Edges leaving Blocks, i.e. a plain CFG's edges to
1312 // the middle block or to an exit block, exit to a node outside the loop.
1313 BFIBase BFI;
1314 BFIBase::BlockNode Header(0), Outside(Blocks.size());
1315 BFIBase::LoopData &Loop = BFI.Loops.emplace_back(nullptr, Header);
1317 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1318 Nodes[VPBB] = BFIBase::BlockNode(Idx);
1319 BFI.Working.emplace_back(BFIBase::BlockNode(Idx)).Loop = &Loop;
1320 }
1321 BFI.Working.emplace_back(Outside);
1322 BFI.Working[Header.Index].getMass() = BFIBase::BlockMass::getFull();
1323
1324 // Keep track nodes reached via an edge without branch weighs or with
1325 // estimated ones
1326 SmallVector<bool> IsUnknown(Blocks.size()), IsEstimated(Blocks.size());
1327 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1328 BFIBase::BlockNode Node(Idx);
1329 auto Probs = getSuccessorProbabilities(VPBB);
1330 auto *Term = dyn_cast_if_present<VPInstruction>(VPBB->getTerminator());
1331 bool TermIsEstimated = Term && Term->hasEstimatedBranchWeights();
1332 BFIBase::Distribution Dist;
1333 for (auto [SuccIdx, Succ] : enumerate(VPBB->getSuccessors())) {
1334 BFIBase::BlockNode SuccNode = Nodes.lookup_or(Succ, Outside);
1335 if (SuccNode != Header && SuccNode != Outside) {
1336 IsUnknown[SuccNode.Index] |= IsUnknown[Idx] || !Probs;
1337 IsEstimated[SuccNode.Index] |= IsEstimated[Idx] || TermIsEstimated;
1338 }
1339 if (Probs)
1340 BFI.addToDist(Dist, &Loop, Node, SuccNode,
1341 getWeightFromBranchProb((*Probs)[SuccIdx]));
1342 }
1343 if (Probs)
1344 BFI.distributeMass(Node, &Loop, Dist);
1345 }
1346
1347 // Round frequencies up to at least 1, so all edges are reached with a
1348 // non-zero frequency, to distinguish rarely executed blocks from unreachable
1349 // ones. blocks distinguishable from unreachable ones.
1351 Frequencies;
1352 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1353 std::optional<VPExecutionFrequency> &Freq = Frequencies[VPBB];
1354 if (IsUnknown[Idx])
1355 continue;
1356 uint64_t Mass = BFI.Working[Idx].getMass().getMass();
1357 Freq.emplace(BlockFrequency(std::max<uint64_t>(Mass, 1)), IsEstimated[Idx]);
1358 }
1359 return Frequencies;
1360}
1361
1364 const DataLayout &DL) {
1365 auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
1366 if (!OpcodeOrIID)
1367 return nullptr;
1368
1370 for (VPValue *Op : Operands) {
1371 VPValue *Candidate = Op;
1372 match(Op, m_Broadcast(m_VPValue(Candidate)));
1373 if (!match(Candidate, m_LiveIn()))
1374 return nullptr;
1375 Value *V = Candidate->getUnderlyingValue();
1376 if (!V)
1377 return nullptr;
1378 Ops.push_back(V);
1379 }
1380
1381 VPlan &Plan = *R.getParent()->getPlan();
1382 auto FoldToIRValue = [&]() -> Value * {
1383 InstSimplifyFolder Folder(DL);
1384 if (OpcodeOrIID->first) {
1385 // VPInstructions store the called intrinsic as last operand.
1386 if (isa<VPInstruction>(R))
1387 Ops.pop_back();
1388
1389 auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(&R);
1390 return Folder.FoldIntrinsic(OpcodeOrIID->second, Ops, R.getScalarType(),
1391 RFlags ? RFlags->getFastMathFlagsOrNone()
1392 : FastMathFlags());
1393 }
1394 unsigned Opcode = OpcodeOrIID->second;
1395 if (Instruction::isBinaryOp(Opcode))
1396 return Folder.FoldBinOp(static_cast<Instruction::BinaryOps>(Opcode),
1397 Ops[0], Ops[1]);
1398 if (Instruction::isCast(Opcode))
1399 return Folder.FoldCast(static_cast<Instruction::CastOps>(Opcode), Ops[0],
1400 R.getVPSingleValue()->getScalarType());
1401 switch (Opcode) {
1402 case VPInstruction::Not:
1403 return Folder.FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
1405 case Instruction::Select:
1406 return Folder.FoldSelect(Ops[0], Ops[1], Ops[2]);
1407 case Instruction::ICmp:
1408 case Instruction::FCmp:
1409 return Folder.FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
1410 Ops[1]);
1411 case Instruction::GetElementPtr: {
1412 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
1413 auto *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
1414 return Folder.FoldGEP(DL, GEP->getSourceElementType(), Ops[0],
1415 drop_begin(Ops), RFlags.getGEPNoWrapFlags());
1416 }
1419 return Folder.FoldGEP(DL, IntegerType::getInt8Ty(Plan.getContext()),
1420 Ops[0], Ops[1],
1421 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
1422 // An extract of a live-in is an extract of a broadcast, so return the
1423 // broadcasted element.
1424 case Instruction::ExtractElement:
1425 assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
1426 return Ops[0];
1429 uint64_t Multiplier = 1;
1430 if (Opcode == VPInstruction::WideActiveLaneMask) {
1431 // Optimizing WideALM can only happen after the Plan is unrolled.
1432 if (!Plan.isUnrolled())
1433 return nullptr;
1434 Multiplier = cast<ConstantInt>(Ops[2])->getZExtValue();
1435 Ops.pop_back();
1436 }
1437
1438 // We rely on the fact that different VPlans are created for the
1439 // fixed-vector and scalable-vector cases.
1440 ElementCount MaxVF =
1442 Multiplier;
1443
1444 Type *I1Ty = IntegerType::getInt1Ty(Plan.getContext());
1445 if (auto *C = dyn_cast_if_present<Constant>(Folder.FoldIntrinsic(
1446 Intrinsic::get_active_lane_mask, Ops,
1447 VectorType::get(I1Ty, MaxVF), {}, Plan.getIRFunction()))) {
1448 // We cannot handle vector constants that are not all-true or all-false,
1449 // because they would not be collapsable to a scalar constant, that
1450 // would be necessary for live-in simplification.
1451 if (C->isOneValue())
1452 return ConstantInt::getTrue(I1Ty);
1453 if (C->isNullValue())
1454 return ConstantInt::getFalse(I1Ty);
1455 }
1456 }
1457 }
1458 return nullptr;
1459 };
1460
1461 if (Value *V = FoldToIRValue())
1462 return Plan.getOrAddLiveIn(V);
1463 return nullptr;
1464}
1465
1467 VPlan &Plan, function_ref<VPValue *(VPValue *Op)> MatchPerm,
1470 vp_depth_first_deep(Plan.getEntry()))) {
1471 for (VPSingleDefRecipe &Def :
1473 if (!isElementwise(&Def))
1474 continue;
1475
1476 // At least one of the ops must be a permutation.
1477 if (none_of(Def.operands(), MatchPerm))
1478 continue;
1479
1480 // All operands must be a single-use permutation or a live in (splat).
1481 if (!all_of(Def.operands(), [&MatchPerm](VPValue *Op) {
1482 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1483 }))
1484 continue;
1485
1486 // Remove the inner permutations.
1487 for (unsigned I = 0, E = Def.getNumOperands(); I != E; ++I)
1488 if (VPValue *X = MatchPerm(Def.getOperand(I)))
1489 Def.setOperand(I, X);
1490
1491 VPSingleDefRecipe *Res = BuildPerm(&Def);
1492 Res->insertAfter(&Def);
1493 Def.replaceUsesWithIf(Res, not_equal_to(Res));
1494 }
1495 }
1496}
1497
1498// Implements the algorithm described in "Simple and Efficient Construction of
1499// Static Single Assignment Form" by Braun et al.
1502 assert(!Defs.empty() && "Defs shouldn't be empty");
1503 assert(
1505 "VPBB isn't reachable from entry");
1506 if (VPValue *Def = Defs.lookup(VPBB))
1507 return Def;
1508 // If the entry block is reached and there's still no def, then Defs is
1509 // missing a definition that covers this path.
1510 assert(VPBB->getNumPredecessors() && "Not all paths have def");
1511
1512 if (VPBlockBase *Pred = VPBB->getSinglePredecessor())
1513 return reconstructSSA(cast<VPBasicBlock>(Pred), Defs);
1514
1515 // Multiple predecessors, create a join.
1516 Type *Ty = Defs.begin()->second->getScalarType();
1517 VPPhi *Phi = VPBuilder(VPBB, VPBB->getFirstNonPhi())
1518 .createScalarPhi({}, DebugLoc::getUnknown(), "", {}, Ty);
1519 Defs[VPBB] = Phi;
1520 for (auto *Pred : VPBB->predecessors())
1521 Phi->addIncoming(reconstructSSA(cast<VPBasicBlock>(Pred), Defs));
1522
1523 // Fold away trivial phis.
1524 // TODO: Remove phi users which have become trivial too.
1525 if (all_equal(Phi->incoming_values())) {
1526 VPValue *Common = Phi->getIncomingValue(0);
1527 Phi->replaceAllUsesWith(Common);
1528 for (auto &[_, V] : Defs)
1529 if (V == Phi)
1530 V = Common;
1531 Defs[VPBB] = Common;
1532 Phi->eraseFromParent();
1533 return Common;
1534 }
1535
1536 return Phi;
1537}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
Hexagon Common GEP
#define _
iv Induction Variable Users
Definition IVUsers.cpp:48
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file implements a map that provides insertion order iteration.
This file provides utility analysis objects describing memory locations.
#define P(N)
This file contains the declarations for profiling metadata utility functions.
SI Fold Operands
This file implements a set that has insertion order iteration characteristics.
This file defines less commonly used SmallVector utilities.
static unsigned getScalarSizeInBits(Type *Ty)
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
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 BranchProbability getBranchProbabilityKeepingPartial(uint64_t Num, uint64_t Denom)
Returns Num / Denom as a BranchProbability, clamped so a ratio that is neither zero nor one does not ...
static std::optional< SmallVector< BranchProbability > > getSuccessorProbabilities(const VPBasicBlock *VPBB)
Returns the probability of each successor edge of VPBB, computed via BranchProbabilityInfo::getEdgePr...
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
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
Base class for BlockFrequencyInfoImpl.
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
static LLVM_ABI SmallVector< BranchProbability > getEdgeProbabilitiesFromWeights(ArrayRef< uint32_t > Weights)
Returns the probabilities of edges with branch weights Weights.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
static constexpr BranchProbability getOne()
static uint32_t getDenominator()
static constexpr BranchProbability getRaw(uint32_t N)
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:512
This is the shared class of boolean and integer constants.
Definition Constants.h:87
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isMinValue(bool IsSigned) const
This function will return true iff this constant represents the smallest value that may be represente...
Definition Constants.h:250
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
static DebugLoc getUnknown()
Definition DebugLoc.h:153
bool empty() const
Definition DenseMap.h:716
ValueT lookup_or(const_arg_type_t< KeyT > Val, U &&Default) const
Definition DenseMap.h:803
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:793
iterator begin()
Definition DenseMap.h:682
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.
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition Operator.h:202
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags noUnsignedWrap()
static GEPNoWrapFlags none()
A struct for saving information about induction variables.
InductionKind
This enum represents the kinds of inductions that we support.
@ IK_FpInduction
Floating point induction variable.
@ IK_IntInduction
Integer induction variable. Step = C.
InstSimplifyFolder - Use InstructionSimplify to fold operations to existing values.
bool isCast() const
bool isBinaryOp() const
bool isUnaryOp() const
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1081
Representation for a specific memory location.
static ICmpInst::Predicate getPredicate(Intrinsic::ID ID)
Returns the comparison predicate underlying the intrinsic.
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.
static LLVM_ABI CastInst * findReusableCastForPtrToAddr(Value *PtrOp, Type *Ty, const DataLayout &DL, function_ref< bool(const CastInst *)> Dominates)
Find an existing cast among PtrOp's users that computes the same value as a ptrtoaddr of PtrOp to Ty ...
static LLVM_ABI std::pair< PHINode *, const SCEV * > findReusableLCSSAPhi(ScalarEvolution &SE, SCEVUseT< const SCEVAddRecExpr * > S, const BasicBlock *InsertBB)
Find a phi in the exit block of S's loop, which must dominate InsertBB, such that S can be expanded i...
This node is a base class providing common functionality for n'ary operators.
This class represents an analyzed expression in the program.
static constexpr auto FlagNSW
Type * getType() const
Return the LLVM type of this SCEV expression.
static constexpr auto FlagNone
SCEVTypes getSCEVType() const
static constexpr auto FlagNW
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 * getZeroExtendExpr(SCEVUse Op, Type *Ty, unsigned Depth=0)
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 * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags=SCEV::FlagNone, unsigned Depth=0)
Return LHS-RHS.
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.
static LLVM_ABI bool isGuaranteedNotToBePoison(const SCEV *Op)
Returns true if Op is guaranteed to not be poison.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI SCEVUse getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEVFlagsPair Flags)
Get an add recurrence expression for the specified loop.
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 * getTruncateExpr(SCEVUse Op, Type *Ty, unsigned Depth=0)
LLVM_ABI SCEVUse getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getSignExtendExpr(SCEVUse 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 SCEVUse getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
const SCEV * getPowerOfTwo(Type *Ty, unsigned Power)
Return a SCEV for the constant Power of two.
LLVM_ABI const SCEV * getPtrToAddrExpr(const SCEV *Op)
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.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
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.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
reference emplace_back(ArgTypes &&... Args)
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:277
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4465
iterator end()
Definition VPlan.h:4502
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:228
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:607
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4531
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:99
VPRegionBlock * getParent()
Definition VPlan.h:197
iterator_range< VPBlockBase ** > predecessors()
Definition VPlan.h:230
size_t getNumSuccessors() const
Definition VPlan.h:247
size_t getNumPredecessors() const
Definition VPlan.h:248
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:232
VPlan * getPlan()
Definition VPlan.h:201
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:243
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:183
VPBlockBase * getSingleHierarchicalPredecessor()
Definition VPlan.h:273
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:237
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:221
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:422
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.
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt, Type *ResultTy=nullptr)
Create a phi with IncomingValues, using the default flags for the result type, unless Flags is set.
ArrayRef< VPRecipeValue * > definedValues()
Returns an ArrayRef of the values defined by the VPDef.
Definition VPlanValue.h:572
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4246
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:4078
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2538
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition VPlan.h:2527
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4618
Class to record and manage LLVM IR flags.
Definition VPlan.h:690
static LLVM_ABI_FOR_TEST VPIRFlags getDefaultFlags(unsigned Opcode, Type *ResultTy=nullptr)
Returns default flags for Opcode and scalar ResultTy for opcodes that support it, asserts otherwise.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1315
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1416
unsigned getOpcode() const
Definition VPlan.h:1507
bool isVectorToScalar() const
Returns true if this VPInstruction produces a scalar value from a vector, e.g.
bool isSingleScalar() const
Returns true if the recipe produces a single scalar value.
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:405
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:555
void insertAfter(VPRecipeBase *InsertPos)
Insert an unlinked Recipe into a basic block immediately after the specified Recipe.
A recipe for handling reduction phis.
Definition VPlan.h:2898
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4690
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4766
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4854
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4810
VPValues are defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:247
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3448
VPValue * expand(const SCEV *S)
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:4307
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:613
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:212
bool isMaterialized() const
Returns true if this value has been materialized.
Definition VPlanValue.h:230
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:396
operand_range operands()
Definition VPlanValue.h:472
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:437
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:142
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:123
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
Definition VPlanValue.h:75
user_range users()
Definition VPlanValue.h:157
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1907
A recipe for handling GEP instructions.
Definition VPlan.h:2265
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition VPlan.h:2622
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2651
A recipe for widened phis.
Definition VPlan.h:2785
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1840
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4877
LLVMContext & getContext() const
Definition VPlan.h:5087
VPBasicBlock * getEntry()
Definition VPlan.h:4973
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
Definition VPlan.h:5120
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5085
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:5039
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:5163
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5189
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
Definition VPlan.h:5154
Function * getIRFunction() const
Definition VPlan.h:5095
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1030
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5141
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4978
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:5082
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:5029
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5078
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:217
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.
CastOperator_match< OpTy, Instruction::PtrToAddr > m_PtrToAddr(const OpTy &Op)
Matches PtrToAddr.
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::SDiv > m_SDiv(const LHS &L, const RHS &R)
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.
cst_pred_ty< is_one > m_scev_One()
Match an integer 1.
specificloop_ty m_SpecificLoop(const Loop *L)
cst_pred_ty< is_zero > m_scev_Zero()
Match an integer 0.
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< Instruction::Or, Op0_t, Op1_t > m_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
Match a binary OR 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.
VPInstruction_match< VPInstruction::ExtractVectorForPart, Op0_t, Op1_t > m_ExtractVectorForPart(const Op0_t &Op0, const Op1_t &Op1)
VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
VPInstruction_match< VPInstruction::Broadcast, Op0_t > m_Broadcast(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
void pullOutPermutationsImpl(VPlan &Plan, function_ref< VPValue *(VPValue *Op)> Perm, function_ref< VPSingleDefRecipe *(VPSingleDefRecipe *X)> Build)
Template-independent implementation for pullOutPermutations.
BranchProbability getExecutionProbability(BlockFrequency Freq)
Returns Freq as a BranchProbability, relative to the full mass.
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.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
std::optional< int64_t > getConstantStride(VPValue *Addr, Type *AccessTy, PredicatedScalarEvolution &PSE, const Loop *L)
If the pointer operand Addr of a memory access is an affine AddRec w.r.t.
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,...
LLVM_ABI_FOR_TEST VPValue * reconstructSSA(VPBasicBlock *VPBB, DenseMap< VPBasicBlock *, VPValue * > &Defs)
Insert phis to reconstruct SSA for a single value starting from VPBB.
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used by all users.
Intrinsic::ID getIntrinsicID(const Ty *R)
Return the intrinsic ID underlying a call.
Definition VPlanUtils.h:98
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 by all users.
VPIRValue * tryToFoldLiveIns(VPSingleDefRecipe &R, ArrayRef< VPValue * > Operands, const DataLayout &DL)
Try to fold R using InstSimplifyFolder.
SmallVector< std::pair< VPBasicBlock *, VPIRBasicBlock * > > getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB)
Returns the (early exiting block, exit block) pairs of Plan, i.e.
VPValue * findIncomingAliasMask(const VPlan &Plan)
Finds the incoming alias-mask within the vector preheader.
DenseMap< const VPBasicBlock *, std::optional< VPExecutionFrequency > > computeExecutionFrequencies(ArrayRef< VPBasicBlock * > Blocks)
Computes for each block in Blocks, which must be in reverse post-order, the frequency with which it e...
VPScalarIVStepsRecipe * createScalarIVSteps(VPlan &Plan, InductionDescriptor::InductionKind Kind, Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, Type *ResultTy, VPValue *StartV, VPValue *Step, DebugLoc DL, VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags={})
Create a scalar-iv-steps recipe over Plan's canonical IV for an induction of Kind with InductionOpcod...
bool propagatesFirstLaneUse(const VPUser *U, const VPValue *Op)
Returns true if checking whether U uses the first lane of Op requires recursively checking Op's users...
void recursivelyDeleteDeadRecipes(VPValue *V)
Recursively delete V and any of its operands that become dead.
bool doesGeneratePerAllLanes(const VPRecipeBase *R)
Returns true if R produces scalar values for all VF lanes.
VPIRFlags getFlagsForInduction(const InductionDescriptor &ID, const VPPhi *PhiR)
Extracts and returns NoWrap flags from PhiR and fast-math flags from ID.
bool isDeadRecipe(VPRecipeBase &R)
Returns true if R is dead, i.e.
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.
LLVM_ABI_FOR_TEST 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.
std::optional< std::pair< bool, unsigned > > getOpcodeOrIntrinsicID(const VPValue *V)
Get the instruction opcode or intrinsic ID for the recipe defining V.
VPValue * scalarizeVPWidenPointerInduction(VPWidenPointerInductionRecipe *PtrIV, VPlan &Plan, VPBuilder &Builder)
Scalarize a VPWidenPointerInductionRecipe by replacing it with a PtrAdd (IndStart,...
GEPNoWrapFlags getGEPFlagsForPtr(VPValue *Ptr)
Returns the GEP nowrap flags for Ptr, looking through pointer casts mirroring Value::stripPointerCast...
LLVM_ABI_FOR_TEST 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.
SmallVector< VPUser * > collectUsersRecursively(VPValue *V)
Collect all users of V, looking through recipes that define other values.
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:316
@ Offset
Definition DWP.cpp:577
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Definition STLExtras.h:2196
void stable_sort(R &&Range)
Definition STLExtras.h:2132
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:1781
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:1755
uint32_t getWeightFromBranchProb(const BranchProbability Prob)
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:856
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
VPBuilderBase<> VPBuilder
Definition VPlan.h:69
constexpr from_range_t from_range
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
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
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
Definition STLExtras.h:2189
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
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:1762
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:326
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool hasIrregularType(Type *Ty, const DataLayout &DL)
A helper function that returns true if the given type is irregular.
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:1769
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
LLVM_ABI MDNode * getExplicitlyUnknownBranchWeightsIfProfiled(Function &F, StringRef PassName)
Returns a metadata node containing unknown branch weights if the function has an entry count,...
DWARFExpression::Operation Op
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2104
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
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:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
Definition STLExtras.h:2182
LLVM_ABI std::optional< int64_t > getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy, Value *Ptr, PredicatedScalarEvolution &PSE)
If AR is an affine AddRec for Lp with a constant step, return the step in units of AccessTy's allocat...
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:274
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
Definition VPlan.h:3918
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3865