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 bool ExpandInIR) {
85 if (auto *E = dyn_cast<SCEVConstant>(Expr))
86 return Plan.getOrAddLiveIn(E->getValue());
87 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
88 // value. Otherwise the value may be defined in a loop and using it directly
89 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
90 // form.
91 auto *U = dyn_cast<SCEVUnknown>(Expr);
92 if (U && !isa<Instruction>(U->getValue()))
93 return Plan.getOrAddLiveIn(U->getValue());
94 auto *Expanded = new VPExpandSCEVRecipe(Expr, ExpandInIR);
95 VPBasicBlock *EntryVPBB = Plan.getEntry();
96 auto Iter = EntryVPBB->getFirstNonPhi();
97 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
98 ++Iter;
99 Expanded->insertBefore(Iter);
100 return Expanded;
101}
102
103/// Returns true if \p V being poison is guaranteed to trigger UB because it
104/// propagates to the address of a memory recipe.
105static bool poisonGuaranteesUB(const VPValue *V) {
108
109 auto PropagatesPoisonFromRecipeOp = [](const VPRecipeBase *R) {
111 return false;
112 unsigned Opcode = vputils::getOpcode(R->getVPSingleValue());
113 return Instruction::isCast(Opcode) || Opcode == Instruction::GetElementPtr;
114 };
115
116 Worklist.push_back(V);
117
118 while (!Worklist.empty()) {
119 const VPValue *Current = Worklist.pop_back_val();
120 if (!Visited.insert(Current).second)
121 continue;
122
123 for (VPUser *U : Current->users()) {
124 // Check if Current is used as an address operand for load/store.
125 auto *R = cast<VPRecipeBase>(U);
126 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(R)) {
127 if (MemR->getAddr() == Current)
128 return true;
129 continue;
130 }
131 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
132 unsigned Opcode = Rep->getOpcode();
133 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
134 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
135 return true;
136 }
137
138 // Check if poison propagates through this recipe to any of its users.
139 for (const VPValue *Op : R->operands()) {
140 if (Op == Current && PropagatesPoisonFromRecipeOp(R)) {
141 Worklist.push_back(R->getVPSingleValue());
142 break;
143 }
144 }
145 }
146 }
147
148 return false;
149}
150
152 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
153 // casts to find a root GEP VPInstruction.
154 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
155 unsigned Opcode = PtrVPI->getOpcode();
156 if (Opcode == Instruction::GetElementPtr) {
157 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
158 return PtrVPI->getGEPNoWrapFlags();
159 Ptr = PtrVPI->getOperand(0);
160 continue;
161 }
162 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
163 break;
164 Ptr = PtrVPI->getOperand(0);
165 }
166 return GEPNoWrapFlags::none();
167}
168
171 const Loop *L) {
172 ScalarEvolution &SE = *PSE.getSE();
173 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
174 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
175 "RegionValue must be canonical IV");
176 if (!L)
177 return SE.getCouldNotCompute();
178 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
179 L, SCEV::FlagNone);
180 }
181
183 Value *LiveIn = V->getUnderlyingValue();
184 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
185 return SE.getSCEV(LiveIn);
186 return SE.getCouldNotCompute();
187 }
188
189 // Helper to create SCEVs for binary and unary operations.
190 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
191 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
192 -> const SCEV * {
194 for (VPValue *Op : Ops) {
195 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
197 return SE.getCouldNotCompute();
198 SCEVOps.push_back(S);
199 }
200 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
201 };
202
203 VPValue *LHSVal, *RHSVal;
204 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
205 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
206 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
207 });
208 if (match(V, m_BinaryOr(m_VPValue(LHSVal), m_VPValue(RHSVal))))
209 if (cast<VPRecipeWithIRFlags>(V->getDefiningRecipe())->isDisjoint())
210 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
211 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
212 });
213 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
214 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
215 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagNone, 0);
216 });
217 if (match(V, m_Not(m_VPValue(LHSVal)))) {
218 // not X = xor X, -1 = -1 - X
219 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
220 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
221 });
222 }
223 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
224 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
225 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
226 });
227 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
228 // amount >= the bit width produces poison; do not rewrite it, as
229 // getPowerOfTwo requires the power to be in range.
230 uint64_t ShiftAmt;
231 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
232 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
233 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
234 return SE.getMulExpr(Ops[0],
235 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
236 });
237 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
238 Type *Ty = V->getScalarType();
239 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
240 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
241 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
242 });
243 }
244 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
245 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
246 return SE.getUDivExpr(Ops[0], Ops[1]);
247 });
248 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
249 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
250 return SE.getURemExpr(Ops[0], Ops[1]);
251 });
252 // A SDiv with non-negative operands is equivalent to an UDiv.
253 if (match(V, m_SDiv(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
254 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
255 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
256 return SE.getCouldNotCompute();
257 return SE.getUDivExpr(Ops[0], Ops[1]);
258 });
259 }
260 // A SRem with non-negative operands is equivalent to an URem.
261 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
262 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
263 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
264 return SE.getCouldNotCompute();
265 return SE.getURemExpr(Ops[0], Ops[1]);
266 });
267 }
268 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
269 const APInt *Mask;
270 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
271 (*Mask + 1).isPowerOf2())
272 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
273 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
274 });
275 // SCEV models ptrtoaddr, but not ptrtoint, mirroring createSCEV.
276 if (match(V, m_PtrToAddr(m_VPValue(LHSVal))))
277 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
278 return SE.getPtrToAddrExpr(Ops[0]);
279 });
280 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
281 Type *DestTy = V->getScalarType();
282 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
283 return SE.getTruncateExpr(Ops[0], DestTy);
284 });
285 }
286 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
287 Type *DestTy = V->getScalarType();
288 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
289 return SE.getZeroExtendExpr(Ops[0], DestTy);
290 });
291 }
292 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
293 Type *DestTy = V->getScalarType();
294
295 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
296 // onto the operands before computing the subtraction.
297 VPValue *SubLHS, *SubRHS;
298 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
299 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
300 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
301 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
302 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
304 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
305 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
306 }
307
308 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
309 return SE.getSignExtendExpr(Ops[0], DestTy);
310 });
311 }
312 if (match(V,
314 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
315 return SE.getUMaxExpr(Ops[0], Ops[1]);
316 });
317 if (match(V,
319 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
320 return SE.getSMaxExpr(Ops[0], Ops[1]);
321 });
322 if (match(V,
324 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
325 return SE.getUMinExpr(Ops[0], Ops[1]);
326 });
327 if (match(V,
329 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
330 return SE.getSMinExpr(Ops[0], Ops[1]);
331 });
333 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
334 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
335 // not proof that the input is never INT_MIN, nor that poison reaches
336 // UB. Do not translate it to SCEV's global IsNSW flag.
337 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
338 });
339
341 Type *SourceElementType;
342 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
343 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
344 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
345 });
346 }
347
348 // TODO: Support constructing SCEVs for more recipes as needed.
349 const VPRecipeBase *DefR = V->getDefiningRecipe();
350 const SCEV *Expr =
352 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
353 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
354 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
355 if (!L || isa<SCEVCouldNotCompute>(Step))
356 return SE.getCouldNotCompute();
357 const SCEV *Start =
358 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
359 const SCEV *AddRec =
360 SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
361 if (R->isTruncated())
362 return SE.getTruncateExpr(AddRec, R->getScalarType());
363 return AddRec;
364 })
365 .Case([&SE, &PSE,
366 L](const VPWidenPointerInductionRecipe *R) -> const SCEV * {
367 const SCEV *Start =
368 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
369 if (!L || isa<SCEVCouldNotCompute>(Start))
370 return SE.getCouldNotCompute();
371 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
372 if (isa<SCEVCouldNotCompute>(Step))
373 return SE.getCouldNotCompute();
374 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
375 })
376 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) -> const SCEV * {
377 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
378 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
379 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
380 if (any_of(ArrayRef({Start, IV, Scale}),
382 return SE.getCouldNotCompute();
383
384 return SE.getAddExpr(
385 SE.getTruncateOrSignExtend(Start, IV->getType()),
386 SE.getMulExpr(
387 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
388 })
389 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
390 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
391 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
393 return SE.getCouldNotCompute();
394 return SE.getTruncateOrSignExtend(IV, Step->getType());
395 })
396 .Default(
397 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
398
399 return PSE.getPredicatedSCEV(Expr);
400}
401
402std::optional<int64_t>
404 PredicatedScalarEvolution &PSE, const Loop *L) {
405 assert(!hasIrregularType(AccessTy, L->getHeader()->getDataLayout()) &&
406 "should not try to widen irregular types");
407 const SCEV *AddrSCEV = getSCEVExprForVPValue(Addr, PSE, L);
408 auto *AddRec = dyn_cast<SCEVAddRecExpr>(AddrSCEV);
409 if (!AddRec)
410 return {};
411
412 return getStrideFromAddRec(AddRec, L, AccessTy, /*Ptr=*/nullptr, PSE);
413}
414
416 const Loop *L) {
417 // If address is an SCEVAddExpr, we require that all operands must be either
418 // be invariant or a (possibly sign-extend) affine AddRec.
419 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
420 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
421 return SE.isLoopInvariant(Op, L) ||
422 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
423 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
424 });
425 }
426
427 // Otherwise, check if address is loop invariant or an affine add recurrence.
428 return SE.isLoopInvariant(Addr, L) ||
430}
431
432unsigned vputils::getOpcode(const VPValue *V) {
436 VPWidenLoadEVLRecipe>([](auto *I) { return I->getOpcode(); })
439 // For recipes that do not directly map to LLVM IR instructions,
440 // assign opcodes after the last VPInstruction opcode (which is also
441 // after the last IR Instruction opcode), based on the VPRecipeID.
442 return VPInstruction::OpsEnd + 1 + I->getVPRecipeID();
443 })
444 .Default([](auto *) { return 0; });
445}
446
447std::optional<std::pair<bool, unsigned>>
450 return std::make_pair(true, IID);
451 if (unsigned Opcode = vputils::getOpcode(V))
452 return std::make_pair(false, Opcode);
453 return {};
454}
455
456/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
457/// uniform, the result will also be uniform.
458static bool preservesUniformity(unsigned Opcode) {
459 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
460 return true;
461 switch (Opcode) {
462 case Instruction::Freeze:
463 case Instruction::GetElementPtr:
464 case Instruction::ICmp:
465 case Instruction::FCmp:
466 case Instruction::Select:
471 return true;
472 default:
473 return false;
474 }
475}
476
478 // TODO: Handle more opcodes and recipes.
480 return false;
481 unsigned Opcode = getOpcode(V);
482 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
483}
484
486 // Live-in, symbolic and canonical-IV region values are single-scalar.
487 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
488 return RV == RV->getDefiningRegion()->getCanonicalIV();
490 return true;
491
492 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
493 const VPRegionBlock *RegionOfR = Rep->getRegion();
494 // Don't consider recipes in replicate regions as uniform yet; their first
495 // lane cannot be accessed when executing the replicate region for other
496 // lanes.
497 if (RegionOfR && RegionOfR->isReplicator())
498 return false;
499 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
500 all_of(Rep->operands(), isSingleScalar));
501 }
504 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
505 return preservesUniformity(WidenR->getOpcode()) &&
506 all_of(WidenR->operands(), isSingleScalar);
507 }
508 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
509 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
510 (preservesUniformity(VPI->getOpcode()) &&
511 all_of(VPI->operands(), isSingleScalar));
512 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
513 return !RR->isPartialReduction();
515 VPV))
516 return true;
517 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
518 return Expr->isVectorToScalar();
519
520 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
521 return isa<VPExpandSCEVRecipe>(VPV);
522}
523
525 const VPValue *V,
526 function_ref<void(VPUser::const_operand_range)> AddToWorklist) {
527 // Live-ins, symbolic and canonical-IV region values are uniform.
528 if (auto *RV = dyn_cast<VPRegionValue>(V))
529 return RV == RV->getDefiningRegion()->getCanonicalIV();
531 return true;
532
533 const VPRecipeBase *R = V->getDefiningRecipe();
534 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
535 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
536 if (VPBB &&
537 (VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
538 if (match(R,
541 return false;
542 AddToWorklist(R->operands());
543 return true;
544 }
545
547 .Case([](const VPDerivedIVRecipe *) { return true; })
548 .Case([&](const VPReplicateRecipe *R) {
549 // Be conservative about side-effects, except for the
550 // known-side-effecting assumes and stores, which we know will be
551 // uniform. Each alloca creates a distinct allocation, so allocas are
552 // never uniform.
553 if (!R->isSingleScalar() || R->getOpcode() == Instruction::Alloca ||
554 (R->mayHaveSideEffects() &&
555 !isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())))
556 return false;
557 AddToWorklist(R->operands());
558 return true;
559 })
560 .Case([&](const VPWidenRecipe *R) {
561 if (!preservesUniformity(R->getOpcode()))
562 return false;
563 AddToWorklist(R->operands());
564 return true;
565 })
566 .Case([](const VPPhi *) {
567 // Bail out on VPPhi, as we can end up in infinite cycles.
568 return false;
569 })
570 .Case([&](const VPInstruction *VPI) {
571 if (!VPI->isSingleScalar() && !VPI->isVectorToScalar() &&
573 return false;
574 AddToWorklist(VPI->operands());
575 return true;
576 })
577 .Case([&](const VPWidenCastRecipe *R) {
578 // A cast is uniform according to its operand.
579 AddToWorklist(R->operands());
580 return true;
581 })
582 .Default([](const VPRecipeBase *) {
583 // A value is considered non-uniform unless proven otherwise.
584 return false;
585 });
586}
587
590 Worklist.insert(V);
591
592 auto AddToWorklist = [&Worklist](VPUser::const_operand_range Operands) {
593 Worklist.insert_range(Operands);
594 };
595
596 // All dependency checks are conjunctive, so each value needs checking once.
597 for (unsigned I = 0; I != Worklist.size(); ++I) {
598 if (!isUniformAcrossVFsAndUFsImpl(Worklist[I], AddToWorklist))
599 return false;
600 }
601 return true;
602}
603
605 if (auto *RepR = dyn_cast<VPReplicateRecipe>(R))
606 return RepR->doesGeneratePerAllLanes();
607 if (auto *VPI = dyn_cast<VPInstruction>(R))
608 return VPI->doesGeneratePerAllLanes();
609 if (auto *SIVSteps = dyn_cast<VPScalarIVStepsRecipe>(R))
610 return SIVSteps->doesGeneratePerAllLanes();
611 return false;
612}
613
615 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
616 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
617 return VPBlockUtils::isHeader(VPB, VPDT);
618 });
619 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
620}
621
623 if (!R)
624 return 1;
625 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
626 return RR->getVFScaleFactor();
627 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
628 return RR->getVFScaleFactor();
629 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
630 return ER->getVFScaleFactor();
631 assert(
634 "getting scaling factor of reduction-start-vector not implemented yet");
635 return 1;
636}
637
638bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
639 // Assumes don't alias anything or throw; as long as they're guaranteed to
640 // execute, they're safe to hoist. They should however not be sunk, as it
641 // would destroy information.
643 return Sinking;
644 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
645 return true;
646 // Allocas cannot be hoisted.
647 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
648 return RepR && RepR->getOpcode() == Instruction::Alloca;
649}
650
653 VPBasicBlock *LastBB) {
654 assert(FirstBB->getParent() == LastBB->getParent() &&
655 "FirstBB and LastBB from different regions");
656#ifndef NDEBUG
657 bool InSingleSuccChain = false;
658 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
659 InSingleSuccChain |= (Succ == LastBB);
660 assert(InSingleSuccChain &&
661 "LastBB unreachable from FirstBB in single-successor chain");
662#endif
663 auto Blocks = to_vector(
665 auto *LastIt = find(Blocks, LastBB);
666 assert(LastIt != Blocks.end() &&
667 "LastBB unreachable from FirstBB in depth-first traversal");
668 Blocks.erase(std::next(LastIt), Blocks.end());
669 return Blocks;
670}
671
673 for (VPRecipeBase &R : *Plan.getVectorPreheader())
675 return cast<VPInstruction>(&R);
676 return nullptr;
677}
678
680vputils::getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB) {
682 for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks())
683 for (VPBlockBase *Pred : ExitVPBB->getPredecessors())
684 if (Pred != MiddleVPBB)
685 Exits.emplace_back(cast<VPBasicBlock>(Pred), ExitVPBB);
686 return Exits;
687}
688
691 Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp,
692 Type *ResultTy, VPValue *StartV, VPValue *Step, DebugLoc DL,
693 VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags) {
694 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
695 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
696 VPValue *CanonicalIV = LoopRegion->getCanonicalIV();
697 VPValue *BaseIV =
698 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
699
700 // Truncate BaseIV and Step to ResultTy.
701 if (ResultTy->isIntegerTy()) {
702 [[maybe_unused]] Type *BaseIVTy = BaseIV->getScalarType();
703 assert(BaseIVTy->isIntegerTy() && "Integral BaseIV type expected");
704 assert(BaseIVTy->getPrimitiveSizeInBits() >=
705 ResultTy->getPrimitiveSizeInBits() &&
706 "BaseIV's type must be at least as large as ResultTy");
707 BaseIV = Builder.createScalarZExtOrTrunc(BaseIV, ResultTy, DL);
708 [[maybe_unused]] Type *StepTy = Step->getScalarType();
709 assert(StepTy->isIntegerTy() && "Integral Step type expected");
710 assert(StepTy->getPrimitiveSizeInBits() >=
711 ResultTy->getPrimitiveSizeInBits() &&
712 "Step's type must be at least as large as ResultTy");
713 auto *VecPreheader =
715 VPBuilder::InsertPointGuard Guard(Builder);
716 Builder.setInsertPoint(VecPreheader);
717 Step = Builder.createScalarZExtOrTrunc(Step, ResultTy, DL);
718 }
719 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
720 &Plan.getVF(), DL);
721}
722
723VPValue *
725 VPlan &Plan, VPBuilder &Builder) {
726 VPValue *StepV = PtrIV->getStepValue();
727 VPIRValue *StartV = Plan.getZero(StepV->getScalarType());
729 Plan, InductionDescriptor::IK_IntInduction, Instruction::Add, nullptr,
730 StartV->getScalarType(), StartV, StepV, PtrIV->getDebugLoc(), Builder);
731
732 return Builder.createPtrAdd(PtrIV->getStartValue(), Steps,
733 PtrIV->getDebugLoc(), "next.gep");
734}
735
737 const VPDominatorTree &VPDT) {
738 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
739 if (!VPBB)
740 return false;
741
742 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
743 // VPBB as its entry, i.e., free of predecessors.
744 if (auto *R = VPBB->getParent())
745 return !R->isReplicator() && !VPBB->hasPredecessors();
746
747 // A header dominates its second predecessor (the latch), with the other
748 // predecessor being the preheader
749 return VPB->getPredecessors().size() == 2 &&
750 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
751}
752
754 const VPDominatorTree &VPDT) {
755 // A latch has a header as its last successor, with its other successors
756 // leaving the loop. A preheader OTOH has a header as its first (and only)
757 // successor.
758 return VPB->getNumSuccessors() >= 2 &&
760}
761
762std::pair<VPBasicBlock *, VPBasicBlock *>
765 Plan.getEntry()->getNumSuccessors() == 1
766 ? Plan.getEntry()->getSingleSuccessor()
767 : Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
768 assert(Header->getNumPredecessors() == 2 &&
769 "Header must have exactly 2 predecessors");
770 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
771 return {Header, Latch};
772}
773
777
779 const VPPhi *PhiR) {
780 if (ID.getKind() == InductionDescriptor::IK_FpInduction)
781 return ID.getInductionBinOp()->getFastMathFlags();
782
783 // The flags only bound the induction values if the increment directly
784 // updates PhiR.
785 VPValue *Inc = PhiR->getOperand(1);
786 if (match(Inc, m_c_Add(m_Specific(PhiR), m_VPValue())))
787 return cast<VPInstruction>(Inc)->getNoWrapFlagsOrNone();
788
789 if (match(Inc, m_Sub(m_Specific(PhiR), m_VPValue()))) {
790 // The step of a sub induction is negated, so NUW cannot be preserved. NSW
791 // can, if the step is not the signed minimum.
792 std::optional<APInt> Step = ID.getConstStepValue();
793 bool NSW = cast<VPInstruction>(Inc)->getNoWrapFlagsOrNone().HasNSW &&
794 Step && !Step->isMinSignedValue();
795 return VPIRFlags::WrapFlagsTy(/*NUW*/ false, NSW);
796 }
797
798 return VPIRFlags::WrapFlagsTy(false, false);
799}
800
801std::optional<MemoryLocation>
803 auto *M = dyn_cast<VPIRMetadata>(&R);
804 if (!M)
805 return std::nullopt;
807 // Populate noalias metadata from VPIRMetadata.
808 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
809 Loc.AATags.NoAlias = NoAliasMD;
810 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
811 Loc.AATags.Scope = AliasScopeMD;
812 return Loc;
813}
814
816 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
817 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
818 assert(CanIV && "Expected loop region to have a canonical IV");
819
820 VPSymbolicValue &VFxUF = Plan.getVFxUF();
821
822 // Check if \p Step matches the expected increment step, accounting for
823 // materialization of VFxUF and UF.
824 auto IsIncrementStep = [&](VPValue *Step) -> bool {
825 if (!VFxUF.isMaterialized())
826 return Step == &VFxUF;
827
828 VPSymbolicValue &UF = Plan.getUF();
829 if (!UF.isMaterialized())
830 return Step == &UF ||
831 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
832
833 // Alias masking: step is number of active lanes of a dependence mask.
834 if (match(Step, m_ZExtOrTruncOrSelf(
836 return true;
837
838 unsigned ConcreteUF = Plan.getConcreteUF();
839 // Fixed VF: step is just the concrete UF.
840 if (match(Step, m_SpecificInt(ConcreteUF)))
841 return true;
842
843 // Scalable VF: step involves VScale.
844 if (ConcreteUF == 1)
845 return match(Step, m_VScale());
846 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
847 return true;
848 // mul(VScale, ConcreteUF) may have been simplified to
849 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
850 return isPowerOf2_32(ConcreteUF) &&
851 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
852 };
853
854 VPInstruction *Increment = nullptr;
855 for (VPUser *U : CanIV->users()) {
856 VPValue *Step;
857 if (isa<VPInstruction>(U) &&
858 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
859 IsIncrementStep(Step)) {
860 assert(!Increment && "There must be a unique increment");
862 }
863 }
864
865 assert((!VFxUF.isMaterialized() || Increment) &&
866 "After materializing VFxUF, an increment must exist");
867 assert((!Increment ||
868 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
869 "NUW flag in region and increment must match");
870 return Increment;
871}
872
873/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
874/// inserted for predicated reductions or tail folding.
876 VPValue *BackedgeVal = PhiR->getBackedgeValue();
877 if (auto *Res =
879 return Res;
880
881 // Look through selects inserted for tail folding or predicated reductions.
883 BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
884 if (!SelR)
885 return nullptr;
887}
888
891 SmallVector<const VPValue *> WorkList = {V};
892
893 while (!WorkList.empty()) {
894 const VPValue *Cur = WorkList.pop_back_val();
895 if (!Seen.insert(Cur).second)
896 continue;
897
898 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
899 // Skip blends that use V only through a compare by checking if any incoming
900 // value was already visited.
901 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
902 [&](unsigned I) {
903 return Seen.contains(Blend->getIncomingValue(I));
904 }))
905 continue;
906
907 for (VPUser *U : Cur->users()) {
908 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
909 if (InterleaveR->getAddr() == Cur)
910 return true;
911 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
912 // store (operand 1).
915 m_Specific(Cur)))))
916 return true;
918 if (MemR->getAddr() == Cur && MemR->isConsecutive())
919 return true;
920 }
921 }
922
923 // The legacy cost model only supports scalarization loads/stores with phi
924 // addresses, if the phi is directly used as load/store address. Don't
925 // traverse further for Blends and first-order recurrence splices.
926 if (Blend ||
927 match(Cur,
929 continue;
930
931 // Only traverse further through users that also define a value (and can
932 // thus have their own users walked). Skip when Cur is only used as mask ,
933 // as well as loads: a loaded value does not depend on the load's operand.
934 for (VPUser *U : Cur->users()) {
935 auto *VPI = dyn_cast<VPInstruction>(U);
936 if (VPI && VPI->getMask() == Cur &&
937 none_of(VPI->operandsWithoutMask(), equal_to(Cur)))
938 continue;
940 continue;
941 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
942 WorkList.push_back(SDR);
943 }
944 }
945 return false;
946}
947
948/// Try to find a loop-invariant IR value for \p S in the plan's entry block
949/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
950/// if no reusable IR value is found.
951VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
953 return nullptr;
954 VPlan &Plan = Builder.getPlan();
955 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
956 for (Value *V : SE.getSCEVValues(S)) {
957 // Only reuse instructions in the plan's entry block, or, when a
958 // DominatorTree is available, any instruction that dominates it.
959 // Instructions in sibling branches may not dominate the entry block.
960 auto *I = dyn_cast<Instruction>(V);
961 if (!I)
962 return Plan.getOrAddLiveIn(V);
963 if (!SE.DT.dominates(I->getParent(), PH))
964 continue;
965 Loop *IL = SE.LI.getLoopFor(I->getParent());
966 if (IL && !IL->contains(PH))
967 continue;
968 SmallVector<Instruction *> DropPoisonGeneratingInsts;
969 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
970 continue;
971 for (Instruction *DropI : DropPoisonGeneratingInsts)
973 return Plan.getOrAddLiveIn(V);
974 }
975 return nullptr;
976}
977
978VPValue *VPSCEVExpander::expandAsPtrAdd(const SCEVNAryExpr *S) {
979 VPValue *Base = expand(SE.getPointerBase(S));
980 VPValue *Offset = expand(SE.removePointerBase(S));
981 GEPNoWrapFlags GEPFlags = S->hasNoUnsignedWrap()
983 : GEPNoWrapFlags::none();
984 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
985}
986
987#ifndef NDEBUG
988/// Returns true if \p V dominates the insert point of \p Builder.
989static bool dominatesInsertPoint(const VPValue *V, const VPBuilder &Builder) {
990 const VPRecipeBase *R = V->getDefiningRecipe();
991 if (!R)
992 return true;
993 VPDominatorTree VPDT(Builder.getPlan());
994 if (VPRecipeBase *InsertPt = Builder.getRecipeAtInsertPoint())
995 return VPDT.properlyDominates(R, InsertPt);
996 return VPDT.dominates(R->getParent(), Builder.getInsertBlock());
997}
998#endif
999
1002 if (VPValue *V = InsertedExpressions.lookup(Key)) {
1003 assert(dominatesInsertPoint(V, Builder) &&
1004 "reused expansion must dominate the insert point");
1005 return V;
1006 }
1007 VPValue *V = expandImpl(S);
1008 InsertedExpressions[Key] = V;
1009 return V;
1010}
1011
1012VPValue *VPSCEVExpander::expandImpl(const SCEV *S) {
1013 if (VPValue *V = tryToReuseIRValue(S))
1014 return V;
1015
1016 if (HoistOutOf && !SafeUDivMode && SE.isLoopInvariant(S, HoistOutOf) &&
1018 return vputils::getOrCreateVPValueForSCEVExpr(Builder.getPlan(), S,
1019 /*ExpandInIR=*/true);
1020
1021 switch (S->getSCEVType()) {
1022 case scConstant:
1023 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
1024 case scUnknown:
1025 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
1026 case scVScale:
1027 return Builder.createVScale(S->getType(), DL);
1028 case scAddExpr: {
1029 auto *AddE = cast<SCEVAddExpr>(S);
1030 VPIRFlags::WrapFlagsTy WrapFlags(AddE->hasNoUnsignedWrap(),
1031 AddE->hasNoSignedWrap());
1032
1033 // Expand pointer SCEVAddExpr as a ptradd of the pointer base and the
1034 // integer offset, matching SCEVExpander.
1035 if (S->getType()->isPointerTy())
1036 return expandAsPtrAdd(AddE);
1037
1038 // Non-constant-negative add operands are expanded negated and subtracted
1039 // from the running result below, instead of being negated and added.
1040 auto UseSubtract = [](const SCEV *Op) {
1041 return Op->isNonConstantNegative();
1042 };
1043 // Iterate in reverse so that constants are emitted last, and move the
1044 // subtracted operands last, matching SCEVExpander's LoopCompare, so that
1045 // they don't start the running result.
1046 SmallVector<const SCEV *, 2> SCEVOps(reverse(AddE->operands()));
1047 stable_sort(SCEVOps, [&](const SCEV *L, const SCEV *R) {
1048 return !UseSubtract(L) && UseSubtract(R);
1049 });
1051 for (const SCEV *Op : SCEVOps) {
1052 // The first operand starts the result, so it is never subtracted.
1053 bool Negate = !Ops.empty() && UseSubtract(Op);
1054 Ops.push_back(expand(Negate ? SE.getNegativeSCEV(Op) : Op));
1055 }
1056 VPValue *Result = Ops.front();
1057 for (auto [Op, OpV] : drop_begin(zip_equal(SCEVOps, Ops))) {
1058 if (UseSubtract(Op)) {
1059 // Result + (-Op) == Result - Op, which saves the multiply for the
1060 // negation. NSW only transfers if negating Op cannot overflow, see
1061 // ScalarEvolution::getMinusSCEV.
1062 bool HasNSW =
1063 WrapFlags.HasNSW && !SE.getSignedRangeMin(Op).isMinSignedValue();
1064 Result = Builder.createOverflowingOp(Instruction::Sub, {Result, OpV},
1065 {/*HasNUW=*/false, HasNSW}, DL);
1066 continue;
1067 }
1068 Result = Builder.createOverflowingOp(Instruction::Add, {Result, OpV},
1069 WrapFlags, DL);
1070 }
1071 return Result;
1072 }
1073 case scMulExpr: {
1074 auto *MulE = cast<SCEVMulExpr>(S);
1075 VPIRFlags::WrapFlagsTy WrapFlags(MulE->hasNoUnsignedWrap(),
1076 MulE->hasNoSignedWrap());
1078 for (const SCEV *Op : reverse(MulE->operands()))
1079 Ops.push_back(expand(Op));
1080 VPValue *Result = Ops.front();
1081 for (VPValue *OpV : drop_begin(Ops)) {
1082 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, OpV},
1083 WrapFlags, DL);
1084 }
1085 return Result;
1086 }
1087 case scUDivExpr: {
1088 auto *UDiv = cast<SCEVUDivExpr>(S);
1089 VPValue *LHS = expand(UDiv->getLHS());
1090 const SCEV *RHSExpr = UDiv->getRHS();
1091 VPValue *RHS = expand(RHSExpr);
1092 if (SafeUDivMode) {
1093 // Make sure the UDiv's divisor is guaranteed to not be zero/poison, to
1094 // avoid UB.
1095 Type *Ty = UDiv->getType();
1096 bool GuaranteedNotPoison =
1098 if (!GuaranteedNotPoison)
1099 RHS = Builder.createFreeze(RHS, DL);
1100 if (!SE.isKnownNonZero(RHSExpr) || !GuaranteedNotPoison)
1101 RHS = Builder.createScalarIntrinsic(
1102 Intrinsic::umax, {RHS, Builder.getPlan().getConstantInt(Ty, 1)}, Ty,
1103 DL);
1104 }
1105 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
1106 VPIRFlags::getDefaultFlags(Instruction::UDiv),
1107 DL);
1108 }
1109 case scTruncate:
1110 case scZeroExtend:
1111 case scSignExtend:
1112 case scPtrToAddr: {
1113 auto *Cast = cast<SCEVCastExpr>(S);
1114 VPValue *Op = expand(Cast->getOperand());
1115 Instruction::CastOps Opcode;
1116 switch (S->getSCEVType()) {
1117 case scTruncate:
1118 Opcode = Instruction::Trunc;
1119 break;
1120 case scZeroExtend:
1121 Opcode = Instruction::ZExt;
1122 break;
1123 case scSignExtend:
1124 Opcode = Instruction::SExt;
1125 break;
1126 case scPtrToAddr:
1127 Opcode = Instruction::PtrToAddr;
1128 break;
1129 default:
1130 llvm_unreachable("Unhandled cast SCEV");
1131 }
1132
1133 // For ptrtoaddr of an IR value, reuse an existing cast dominating the
1134 // entry if there is one. Otherwise leave it to SCEVExpander, which places
1135 // the cast right after the IR value's definition, so all users can share
1136 // it.
1137 if (Opcode == Instruction::PtrToAddr) {
1138 VPlan &Plan = Builder.getPlan();
1139 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1140 if (auto *IRV = dyn_cast<VPIRValue>(Op)) {
1142 IRV->getValue(), S->getType(), PH->getDataLayout(),
1143 [&](const CastInst *CI) {
1144 return SE.DT.dominates(CI->getParent(), PH);
1145 }))
1146 return Plan.getOrAddLiveIn(CI);
1148 }
1149 }
1150
1151 std::optional<VPIRFlags> Flags;
1152 if (Opcode == Instruction::ZExt)
1153 Flags =
1154 VPIRFlags::NonNegFlagsTy(SE.isKnownNonNegative(Cast->getOperand()));
1155
1156 return Builder.createScalarCast(Opcode, Op, S->getType(), DL, Flags);
1157 }
1158 case scUMaxExpr:
1159 case scSMaxExpr:
1160 case scUMinExpr:
1161 case scSMinExpr:
1162 case scSequentialUMinExpr: {
1163 auto *MinMax = cast<SCEVNAryExpr>(S);
1164 Intrinsic::ID IntrinsicID;
1165 switch (S->getSCEVType()) {
1166 case scUMaxExpr:
1167 IntrinsicID = Intrinsic::umax;
1168 break;
1169 case scSMaxExpr:
1170 IntrinsicID = Intrinsic::smax;
1171 break;
1172 case scUMinExpr:
1174 IntrinsicID = Intrinsic::umin;
1175 break;
1176 case scSMinExpr:
1177 IntrinsicID = Intrinsic::smin;
1178 break;
1179 default:
1180 llvm_unreachable("Unexpected min/max SCEV type");
1181 }
1182 // Chain operands in reverse order matching SCEVExpander's expansion of
1183 // min/max expressions. In SafeUDivMode freeze expansion results of operands
1184 // other than the first for sequential UMins, to avoid short-circuiting
1185 // divide-by-0/poison.
1186 bool IsSequential = S->getSCEVType() == scSequentialUMinExpr;
1187 Type *ResultTy = MinMax->getType();
1188 bool PrevSafeMode = SafeUDivMode;
1190 for (const SCEV *SCEVOp : reverse(MinMax->operands())) {
1191 bool MayShortCircuit =
1192 IsSequential && Ops.size() != MinMax->getNumOperands() - 1;
1193 SafeUDivMode = MayShortCircuit || PrevSafeMode;
1194 VPValue *OpV = expand(SCEVOp);
1195 SafeUDivMode = PrevSafeMode;
1196 if (MayShortCircuit)
1197 OpV = Builder.createFreeze(OpV, DL);
1198 Ops.push_back(OpV);
1199 }
1200 VPValue *Result = Ops.front();
1201 for (VPValue *Op : drop_begin(Ops)) {
1202 if (!ResultTy->isPointerTy()) {
1203 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
1204 ResultTy, DL);
1205 continue;
1206 }
1207 // The min/max intrinsics don't support pointer operands, so expand
1208 // pointer-typed min/max as cmp + select, matching SCEVExpander.
1209 VPValue *Cmp = Builder.createICmp(
1210 MinMaxIntrinsic::getPredicate(IntrinsicID), Result, Op, DL);
1211 Result = Builder.createSelect(Cmp, Result, Op, DL);
1212 Function &F = *Builder.getPlan().getIRFunction();
1213 if (MDNode *MD =
1215 cast<VPInstruction>(Result)->setMetadata(LLVMContext::MD_prof, MD);
1216 }
1217 return Result;
1218 }
1219 case scAddRecExpr: {
1220 auto *AR = cast<SCEVAddRecExpr>(S);
1221 VPlan &Plan = Builder.getPlan();
1222 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1223 assert(SE.DT.dominates(AR->getLoop()->getHeader(), PH) &&
1224 "can only expand AddRecs for loops outside VPlan's scope");
1225
1226 Type *Ty = AR->getType();
1227 if (auto [LCSSAPhi, Diff] = SCEVExpander::findReusableLCSSAPhi(SE, AR, PH);
1228 LCSSAPhi) {
1229 VPValue *DiffV = expand(Diff);
1230 VPValue *BaseV = Plan.getOrAddLiveIn(LCSSAPhi);
1231 if (LCSSAPhi->getType()->isPointerTy()) {
1232 if (Ty->isPointerTy())
1233 return Builder.createPtrAdd(BaseV, DiffV, DL);
1234 BaseV = Builder.createScalarCast(Instruction::PtrToAddr, BaseV, Ty, DL);
1235 }
1236 return Builder.createAdd(BaseV, DiffV, DL);
1237 }
1238
1239 // Mirror SCEVExpander::visitAddRecExpr, but only expand the canonical IV
1240 // {0,+,1} and non-affine AddRecs to IR (which will be created outside the
1241 // scope of VPlan). The AddRec is then scaled and offset using
1242 // VPInstructions.
1243 const Loop *L = AR->getLoop();
1244 auto m_scev_CanonicalIV = // NOLINT
1246 if (!AR->isAffine() || match(AR, m_scev_CanonicalIV))
1248
1249 const SCEV *Step = AR->getStepRecurrence(SE);
1250 // {0,+,F} --> {0,+,1} * F
1251 if (AR->getStart()->isZero()) {
1252 const SCEV *CanIV =
1253 SE.getAddRecExpr(SE.getZero(Ty), SE.getOne(Ty), L, SCEV::FlagNone);
1254 return Builder.createOverflowingOp(
1255 Instruction::Mul, {expand(CanIV), expand(Step)},
1256 {SE.willNotOverflow(Instruction::Mul, /*Signed=*/false, CanIV, Step),
1257 SE.willNotOverflow(Instruction::Mul, /*Signed=*/true, CanIV, Step)},
1258 DL);
1259 }
1260
1261 // {X,+,F} --> X + {0,+,F}
1262 if (Ty->isPointerTy())
1263 return expandAsPtrAdd(AR);
1264 VPValue *Start = expand(AR->getStart());
1265 VPValue *Rest = expand(SE.getAddRecExpr(SE.getZero(Ty), Step, L,
1266 AR->getNoWrapFlags(SCEV::FlagNW)));
1267 return Builder.createAdd(Start, Rest, DL, "",
1268 {AR->hasNoUnsignedWrap(), false});
1269 }
1270 case scCouldNotCompute:
1271 llvm_unreachable("Attempt to expand a SCEVCouldNotCompute");
1272 }
1273 llvm_unreachable("Unknown SCEV kind!");
1274}
1275
1277 // Do remove conditional assume instructions as their conditions may be
1278 // flattened.
1279 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1280 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1282 if (IsConditionalAssume)
1283 return true;
1284
1285 if (R.mayHaveSideEffects())
1286 return false;
1287
1288 // Forbid removing trip-count expressions.
1289 if (isa<VPExpandSCEVRecipe>(R) &&
1290 R.getVPSingleValue() == R.getParent()->getPlan()->getTripCount())
1291 return false;
1292
1293 // Recipe is dead if no user keeps the recipe alive.
1294 return all_of(R.definedValues(), [](VPValue *V) { return V->user_empty(); });
1295}
1296
1298 SmallVector<VPValue *> WorkList;
1300 WorkList.push_back(V);
1301
1302 while (!WorkList.empty()) {
1303 VPValue *Cur = WorkList.pop_back_val();
1304 if (!Seen.insert(Cur).second)
1305 continue;
1306 VPRecipeBase *R = Cur->getDefiningRecipe();
1307 if (!R)
1308 continue;
1309 if (!isDeadRecipe(*R))
1310 continue;
1311 append_range(WorkList, R->operands());
1312 R->eraseFromParent();
1313 }
1314}
1315
1318 for (unsigned I = 0; I != Users.size(); ++I) {
1320 for (VPValue *V : Cur->definedValues())
1321 Users.insert_range(V->users());
1322 }
1323 return Users.takeVector();
1324}
1325
1326/// Returns \p Num / \p Denom as a BranchProbability, clamped so a ratio that is
1327/// neither zero nor one does not round to zero or one. BlockFrequencyInfo also
1328/// keeps a zero-weight edge distinguishable from an unreachable one.
1330 uint64_t Denom) {
1332 if (Num == 0 || Num == Denom)
1333 return P;
1334 return BranchProbability::getRaw(std::clamp(
1335 P.getNumerator(), 1u, BranchProbability::getDenominator() - 1));
1336}
1337
1343
1344/// Returns the probability of each successor edge of \p VPBB, computed via
1345/// BranchProbabilityInfo::getEdgeProbabilitiesFromWeights from the branch
1346/// weights recorded on its terminator, or std::nullopt if not available.
1347static std::optional<SmallVector<BranchProbability>>
1349 // With a single successor the edge is always taken and needs no weights.
1350 if (VPBB->getSingleSuccessor())
1352
1353 SmallVector<uint32_t> Weights;
1355 if (!Term || !extractBranchWeights(Term->getBranchWeights(), Weights) ||
1356 Weights.size() != VPBB->getNumSuccessors())
1357 return std::nullopt;
1359}
1360
1363 using BFIBase = BlockFrequencyInfoImplBase;
1364 assert(!Blocks.empty() && "expected at least the header block");
1365 // Distribute the header's frequency using BFI. Nodes for blocks are numbered
1366 // in reverse post-order. Edges leaving Blocks, i.e. a plain CFG's edges to
1367 // the middle block or to an exit block, exit to a node outside the loop.
1368 BFIBase BFI;
1369 BFIBase::BlockNode Header(0), Outside(Blocks.size());
1370 BFIBase::LoopData &Loop = BFI.Loops.emplace_back(nullptr, Header);
1372 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1373 Nodes[VPBB] = BFIBase::BlockNode(Idx);
1374 BFI.Working.emplace_back(BFIBase::BlockNode(Idx)).Loop = &Loop;
1375 }
1376 BFI.Working.emplace_back(Outside);
1377 BFI.Working[Header.Index].getMass() = BFIBase::BlockMass::getFull();
1378
1379 // Keep track nodes reached via an edge without branch weighs or with
1380 // estimated ones
1381 SmallVector<bool> IsUnknown(Blocks.size()), IsEstimated(Blocks.size());
1382 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1383 BFIBase::BlockNode Node(Idx);
1384 auto Probs = getSuccessorProbabilities(VPBB);
1385 auto *Term = dyn_cast_if_present<VPInstruction>(VPBB->getTerminator());
1386 bool TermIsEstimated = Term && Term->hasEstimatedBranchWeights();
1387 BFIBase::Distribution Dist;
1388 for (auto [SuccIdx, Succ] : enumerate(VPBB->getSuccessors())) {
1389 BFIBase::BlockNode SuccNode = Nodes.lookup_or(Succ, Outside);
1390 if (SuccNode != Header && SuccNode != Outside) {
1391 IsUnknown[SuccNode.Index] |= IsUnknown[Idx] || !Probs;
1392 IsEstimated[SuccNode.Index] |= IsEstimated[Idx] || TermIsEstimated;
1393 }
1394 if (Probs)
1395 BFI.addToDist(Dist, &Loop, Node, SuccNode,
1396 getWeightFromBranchProb((*Probs)[SuccIdx]));
1397 }
1398 if (Probs)
1399 BFI.distributeMass(Node, &Loop, Dist);
1400 }
1401
1402 // Round frequencies up to at least 1, so all edges are reached with a
1403 // non-zero frequency, to distinguish rarely executed blocks from unreachable
1404 // ones. blocks distinguishable from unreachable ones.
1406 Frequencies;
1407 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1408 std::optional<VPExecutionFrequency> &Freq = Frequencies[VPBB];
1409 if (IsUnknown[Idx])
1410 continue;
1411 uint64_t Mass = BFI.Working[Idx].getMass().getMass();
1412 Freq.emplace(BlockFrequency(std::max<uint64_t>(Mass, 1)), IsEstimated[Idx]);
1413 }
1414 return Frequencies;
1415}
1416
1419 const DataLayout &DL) {
1420 auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
1421 if (!OpcodeOrIID)
1422 return nullptr;
1423
1425 for (VPValue *Op : Operands) {
1426 VPValue *Candidate = Op;
1427 match(Op, m_Broadcast(m_VPValue(Candidate)));
1428 if (!match(Candidate, m_LiveIn()))
1429 return nullptr;
1430 Value *V = Candidate->getUnderlyingValue();
1431 if (!V)
1432 return nullptr;
1433 Ops.push_back(V);
1434 }
1435
1436 VPlan &Plan = *R.getParent()->getPlan();
1437 auto FoldToIRValue = [&]() -> Value * {
1438 InstSimplifyFolder Folder(DL);
1439 if (OpcodeOrIID->first) {
1440 // VPInstructions store the called intrinsic as last operand.
1441 if (isa<VPInstruction>(R))
1442 Ops.pop_back();
1443
1444 auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(&R);
1445 return Folder.FoldIntrinsic(OpcodeOrIID->second, Ops, R.getScalarType(),
1446 RFlags ? RFlags->getFastMathFlagsOrNone()
1447 : FastMathFlags());
1448 }
1449 unsigned Opcode = OpcodeOrIID->second;
1450 if (Instruction::isBinaryOp(Opcode))
1451 return Folder.FoldBinOp(static_cast<Instruction::BinaryOps>(Opcode),
1452 Ops[0], Ops[1]);
1453 if (Instruction::isCast(Opcode))
1454 return Folder.FoldCast(static_cast<Instruction::CastOps>(Opcode), Ops[0],
1455 R.getVPSingleValue()->getScalarType());
1456 switch (Opcode) {
1457 case VPInstruction::Not:
1458 return Folder.FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
1460 case Instruction::Select:
1461 return Folder.FoldSelect(Ops[0], Ops[1], Ops[2]);
1462 case Instruction::ICmp:
1463 case Instruction::FCmp:
1464 return Folder.FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
1465 Ops[1]);
1466 case Instruction::GetElementPtr: {
1467 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
1468 auto *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
1469 return Folder.FoldGEP(DL, GEP->getSourceElementType(), Ops[0],
1470 drop_begin(Ops), RFlags.getGEPNoWrapFlags());
1471 }
1474 return Folder.FoldGEP(DL, IntegerType::getInt8Ty(Plan.getContext()),
1475 Ops[0], Ops[1],
1476 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
1477 // An extract of a live-in is an extract of a broadcast, so return the
1478 // broadcasted element.
1479 case Instruction::ExtractElement:
1480 assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
1481 return Ops[0];
1484 uint64_t Multiplier = 1;
1485 if (Opcode == VPInstruction::WideActiveLaneMask) {
1486 // Optimizing WideALM can only happen after the Plan is unrolled.
1487 if (!Plan.isUnrolled())
1488 return nullptr;
1489 Multiplier = cast<ConstantInt>(Ops[2])->getZExtValue();
1490 Ops.pop_back();
1491 }
1492
1493 // We rely on the fact that different VPlans are created for the
1494 // fixed-vector and scalable-vector cases.
1495 ElementCount MaxVF =
1497 Multiplier;
1498
1499 Type *I1Ty = IntegerType::getInt1Ty(Plan.getContext());
1500 if (auto *C = dyn_cast_if_present<Constant>(Folder.FoldIntrinsic(
1501 Intrinsic::get_active_lane_mask, Ops,
1502 VectorType::get(I1Ty, MaxVF), {}, Plan.getIRFunction()))) {
1503 // We cannot handle vector constants that are not all-true or all-false,
1504 // because they would not be collapsable to a scalar constant, that
1505 // would be necessary for live-in simplification.
1506 if (C->isOneValue())
1507 return ConstantInt::getTrue(I1Ty);
1508 if (C->isNullValue())
1509 return ConstantInt::getFalse(I1Ty);
1510 }
1511 }
1512 }
1513 return nullptr;
1514 };
1515
1516 if (Value *V = FoldToIRValue())
1517 return Plan.getOrAddLiveIn(V);
1518 return nullptr;
1519}
1520
1522 VPlan &Plan, function_ref<VPValue *(VPValue *Op)> MatchPerm,
1525 vp_depth_first_deep(Plan.getEntry()))) {
1526 for (VPSingleDefRecipe &Def :
1528 if (!isElementwise(&Def))
1529 continue;
1530
1531 // At least one of the ops must be a permutation.
1532 if (none_of(Def.operands(), MatchPerm))
1533 continue;
1534
1535 // All operands must be a single-use permutation or a live in (splat).
1536 if (!all_of(Def.operands(), [&MatchPerm](VPValue *Op) {
1537 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1538 }))
1539 continue;
1540
1541 // Remove the inner permutations.
1542 for (unsigned I = 0, E = Def.getNumOperands(); I != E; ++I)
1543 if (VPValue *X = MatchPerm(Def.getOperand(I)))
1544 Def.setOperand(I, X);
1545
1546 VPSingleDefRecipe *Res = BuildPerm(&Def);
1547 Res->insertAfter(&Def);
1548 Def.replaceUsesWithIf(Res, not_equal_to(Res));
1549 }
1550 }
1551}
1552
1553// Implements the algorithm described in "Simple and Efficient Construction of
1554// Static Single Assignment Form" by Braun et al.
1557 assert(!Defs.empty() && "Defs shouldn't be empty");
1558 assert(
1560 "VPBB isn't reachable from entry");
1561 if (VPValue *Def = Defs.lookup(VPBB))
1562 return Def;
1563 // If the entry block is reached and there's still no def, then Defs is
1564 // missing a definition that covers this path.
1565 assert(VPBB->getNumPredecessors() && "Not all paths have def");
1566
1567 if (VPBlockBase *Pred = VPBB->getSinglePredecessor())
1568 return reconstructSSA(cast<VPBasicBlock>(Pred), Defs);
1569
1570 // Multiple predecessors, create a join.
1571 Type *Ty = Defs.begin()->second->getScalarType();
1572 VPPhi *Phi = VPBuilder(VPBB->getFirstNonPhi())
1573 .createScalarPhi({}, DebugLoc::getUnknown(), "", {}, Ty);
1574 Defs[VPBB] = Phi;
1575 for (auto *Pred : VPBB->predecessors())
1576 Phi->addIncoming(reconstructSSA(cast<VPBasicBlock>(Pred), Defs));
1577
1578 // Fold away trivial phis.
1579 // TODO: Remove phi users which have become trivial too.
1580 if (all_equal(Phi->incoming_values())) {
1581 VPValue *Common = Phi->getIncomingValue(0);
1582 Phi->replaceAllUsesWith(Common);
1583 for (auto &[_, V] : Defs)
1584 if (V == Phi)
1585 V = Common;
1586 Defs[VPBB] = Common;
1587 Phi->eraseFromParent();
1588 return Common;
1589 }
1590
1591 return Phi;
1592}
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:665
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 bool dominatesInsertPoint(const VPValue *V, const VPBuilder &Builder)
Returns true if V dominates the insert point of Builder.
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 isUniformAcrossVFsAndUFsImpl(const VPValue *V, function_ref< void(VPUser::const_operand_range)> AddToWorklist)
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 ...
Value * RHS
Value * LHS
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)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
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.
ICmpInst::Predicate getPredicate() const
Returns the comparison predicate underlying the intrinsic.
PointerIntPair - This class implements a pair of a pointer and small integer.
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 isGuaranteedNotToCauseUB(const SCEV *Op)
Returns true if Op is guaranteed not to cause immediate UB.
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
void insert_range(Range &&R)
Definition SetVector.h:182
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:4506
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
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:96
VPRegionBlock * getParent()
Definition VPlan.h:194
iterator_range< VPBlockBase ** > predecessors()
Definition VPlan.h:227
size_t getNumSuccessors() const
Definition VPlan.h:244
size_t getNumPredecessors() const
Definition VPlan.h:245
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:229
VPlan * getPlan()
Definition VPlan.h:198
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:240
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:183
VPBlockBase * getSingleHierarchicalPredecessor()
Definition VPlan.h:270
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:234
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:218
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:440
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:4236
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
LLVM_ABI_FOR_TEST bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B) const
Recipe to expand a SCEV expression.
Definition VPlan.h:4060
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2518
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition VPlan.h:2507
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4624
Class to record and manage LLVM IR flags.
Definition VPlan.h:682
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:1321
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1422
unsigned getOpcode() const
Definition VPlan.h:1513
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.
VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when control converges back from ...
Definition VPlan.h:3743
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:403
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:547
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:2878
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4696
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4772
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4860
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4816
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:3428
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:4297
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:605
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
iterator_range< const_operand_iterator > const_operand_range
Definition VPlanValue.h:466
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
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2387
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1887
A recipe for handling GEP instructions.
Definition VPlan.h:2245
VPValue * getStepValue()
Returns the step value of the induction.
Definition VPlan.h:2585
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2631
A recipe for widened phis.
Definition VPlan.h:2765
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1820
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4883
LLVMContext & getContext() const
Definition VPlan.h:5080
VPBasicBlock * getEntry()
Definition VPlan.h:4975
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
Definition VPlan.h:5113
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5078
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:5041
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:5156
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5182
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
Definition VPlan.h:5147
Function * getIRFunction() const
Definition VPlan.h:5088
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1065
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5134
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4980
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:5075
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:5031
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5071
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.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
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.
RecipeTy * findSingleUser(VPValue *V, const MatchT &P)
Return the sole user of V matching pattern P, casting it to RecipeTy, or nullptr.
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)
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...
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.
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr, bool ExpandInIR=false)
Get or create a VPValue that corresponds to the expansion of Expr.
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:67
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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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,...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
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:3898
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3843