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/SetVector.h"
16#include "llvm/ADT/TypeSwitch.h"
21#include "llvm/IR/Dominators.h"
23
24using namespace llvm;
25using namespace llvm::VPlanPatternMatch;
26using namespace llvm::SCEVPatternMatch;
27
29 return all_of(Def->users(),
30 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
31}
32
34 return all_of(Def->users(),
35 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
36}
37
39 return all_of(Def->users(),
40 [Def](const VPUser *U) { return U->usesScalars(Def); });
41}
42
44 if (auto *E = dyn_cast<SCEVConstant>(Expr))
45 return Plan.getOrAddLiveIn(E->getValue());
46 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
47 // value. Otherwise the value may be defined in a loop and using it directly
48 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
49 // form.
50 auto *U = dyn_cast<SCEVUnknown>(Expr);
51 if (U && !isa<Instruction>(U->getValue()))
52 return Plan.getOrAddLiveIn(U->getValue());
53 auto *Expanded = new VPExpandSCEVRecipe(Expr);
54 VPBasicBlock *EntryVPBB = Plan.getEntry();
55 auto Iter = EntryVPBB->getFirstNonPhi();
56 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
57 ++Iter;
58 EntryVPBB->insert(Expanded, Iter);
59 return Expanded;
60}
61
62/// Returns true if \p V being poison is guaranteed to trigger UB because it
63/// propagates to the address of a memory recipe.
64static bool poisonGuaranteesUB(const VPValue *V) {
67
68 auto PropagatesPoisonFromRecipeOp = [](const VPRecipeBase *R) {
70 return false;
71 unsigned Opcode = vputils::getOpcode(R->getVPSingleValue());
72 return Instruction::isCast(Opcode) || Opcode == Instruction::GetElementPtr;
73 };
74
75 Worklist.push_back(V);
76
77 while (!Worklist.empty()) {
78 const VPValue *Current = Worklist.pop_back_val();
79 if (!Visited.insert(Current).second)
80 continue;
81
82 for (VPUser *U : Current->users()) {
83 // Check if Current is used as an address operand for load/store.
84 auto *R = cast<VPRecipeBase>(U);
85 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(R)) {
86 if (MemR->getAddr() == Current)
87 return true;
88 continue;
89 }
90 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
91 unsigned Opcode = Rep->getOpcode();
92 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
93 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
94 return true;
95 }
96
97 // Check if poison propagates through this recipe to any of its users.
98 for (const VPValue *Op : R->operands()) {
99 if (Op == Current && PropagatesPoisonFromRecipeOp(R)) {
100 Worklist.push_back(R->getVPSingleValue());
101 break;
102 }
103 }
104 }
105 }
106
107 return false;
108}
109
111 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
112 // casts to find a root GEP VPInstruction.
113 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
114 unsigned Opcode = PtrVPI->getOpcode();
115 if (Opcode == Instruction::GetElementPtr) {
116 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
117 return PtrVPI->getGEPNoWrapFlags();
118 Ptr = PtrVPI->getOperand(0);
119 continue;
120 }
121 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
122 break;
123 Ptr = PtrVPI->getOperand(0);
124 }
125 return GEPNoWrapFlags::none();
126}
127
130 const Loop *L) {
131 ScalarEvolution &SE = *PSE.getSE();
132 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
133 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
134 "RegionValue must be canonical IV");
135 if (!L)
136 return SE.getCouldNotCompute();
137 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
139 }
140
142 Value *LiveIn = V->getUnderlyingValue();
143 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
144 return SE.getSCEV(LiveIn);
145 return SE.getCouldNotCompute();
146 }
147
148 // Helper to create SCEVs for binary and unary operations.
149 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
150 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
151 -> const SCEV * {
153 for (VPValue *Op : Ops) {
154 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
156 return SE.getCouldNotCompute();
157 SCEVOps.push_back(S);
158 }
159 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
160 };
161
162 VPValue *LHSVal, *RHSVal;
163 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
164 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
165 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
166 });
167 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
168 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
169 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
170 });
171 if (match(V, m_Not(m_VPValue(LHSVal)))) {
172 // not X = xor X, -1 = -1 - X
173 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
174 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
175 });
176 }
177 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
178 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
179 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
180 });
181 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
182 // amount >= the bit width produces poison; do not rewrite it, as
183 // getPowerOfTwo requires the power to be in range.
184 uint64_t ShiftAmt;
185 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
186 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
187 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
188 return SE.getMulExpr(Ops[0],
189 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
190 });
191 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
192 Type *Ty = V->getScalarType();
193 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
194 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
195 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
196 });
197 }
198 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
199 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
200 return SE.getUDivExpr(Ops[0], Ops[1]);
201 });
202 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
203 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
204 return SE.getURemExpr(Ops[0], Ops[1]);
205 });
206 // A SRem with non-negative operands is equivalent to an URem.
207 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
208 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
209 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
210 return SE.getCouldNotCompute();
211 return SE.getURemExpr(Ops[0], Ops[1]);
212 });
213 }
214 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
215 const APInt *Mask;
216 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
217 (*Mask + 1).isPowerOf2())
218 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
219 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
220 });
221 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
222 Type *DestTy = V->getScalarType();
223 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
224 return SE.getTruncateExpr(Ops[0], DestTy);
225 });
226 }
227 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
228 Type *DestTy = V->getScalarType();
229 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
230 return SE.getZeroExtendExpr(Ops[0], DestTy);
231 });
232 }
233 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
234 Type *DestTy = V->getScalarType();
235
236 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
237 // onto the operands before computing the subtraction.
238 VPValue *SubLHS, *SubRHS;
239 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
240 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
241 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
242 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
243 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
245 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
246 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
247 }
248
249 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
250 return SE.getSignExtendExpr(Ops[0], DestTy);
251 });
252 }
253 if (match(V,
255 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
256 return SE.getUMaxExpr(Ops[0], Ops[1]);
257 });
258 if (match(V,
260 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
261 return SE.getSMaxExpr(Ops[0], Ops[1]);
262 });
263 if (match(V,
265 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
266 return SE.getUMinExpr(Ops[0], Ops[1]);
267 });
268 if (match(V,
270 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
271 return SE.getSMinExpr(Ops[0], Ops[1]);
272 });
274 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
275 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
276 // not proof that the input is never INT_MIN, nor that poison reaches
277 // UB. Do not translate it to SCEV's global IsNSW flag.
278 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
279 });
280
282 Type *SourceElementType;
283 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
284 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
285 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
286 });
287 }
288
289 // TODO: Support constructing SCEVs for more recipes as needed.
290 const VPRecipeBase *DefR = V->getDefiningRecipe();
291 const SCEV *Expr =
293 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
294 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
295 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
296 if (!L || isa<SCEVCouldNotCompute>(Step))
297 return SE.getCouldNotCompute();
298 const SCEV *Start =
299 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
300 const SCEV *AddRec =
301 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
302 if (R->getTruncInst())
303 return SE.getTruncateExpr(AddRec, R->getScalarType());
304 return AddRec;
305 })
306 .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
307 const SCEV *Start =
308 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
309 if (!L || isa<SCEVCouldNotCompute>(Start))
310 return SE.getCouldNotCompute();
311 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
312 if (isa<SCEVCouldNotCompute>(Step))
313 return SE.getCouldNotCompute();
314 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
315 })
316 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
317 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
318 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
319 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
320 if (any_of(ArrayRef({Start, IV, Scale}),
322 return SE.getCouldNotCompute();
323
324 return SE.getAddExpr(
325 SE.getTruncateOrSignExtend(Start, IV->getType()),
326 SE.getMulExpr(
327 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
328 })
329 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
330 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
331 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
333 return SE.getCouldNotCompute();
334 return SE.getTruncateOrSignExtend(IV, Step->getType());
335 })
336 .Default(
337 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
338
339 return PSE.getPredicatedSCEV(Expr);
340}
341
343 const Loop *L) {
344 // If address is an SCEVAddExpr, we require that all operands must be either
345 // be invariant or a (possibly sign-extend) affine AddRec.
346 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
347 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
348 return SE.isLoopInvariant(Op, L) ||
349 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
350 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
351 });
352 }
353
354 // Otherwise, check if address is loop invariant or an affine add recurrence.
355 return SE.isLoopInvariant(Addr, L) ||
357}
358
359unsigned vputils::getOpcode(const VPValue *V) {
363 [](auto *I) { return I->getOpcode(); })
364 .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe, VPScalarIVStepsRecipe>(
365 [](auto *I) {
366 // For recipes that do not directly map to LLVM IR instructions,
367 // assign opcodes after the last VPInstruction opcode (which is also
368 // after the last IR Instruction opcode), based on the VPRecipeID.
369 return VPInstruction::OpsEnd + 1 + I->getVPRecipeID();
370 })
371 .Default([](auto *) { return 0; });
372}
373
374std::optional<std::pair<bool, unsigned>>
377 return std::make_pair(true, IID);
378 if (unsigned Opcode = vputils::getOpcode(V))
379 return std::make_pair(false, Opcode);
380 return {};
381}
382
383/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
384/// uniform, the result will also be uniform.
385static bool preservesUniformity(unsigned Opcode) {
386 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
387 return true;
388 switch (Opcode) {
389 case Instruction::Freeze:
390 case Instruction::GetElementPtr:
391 case Instruction::ICmp:
392 case Instruction::FCmp:
393 case Instruction::Select:
398 return true;
399 default:
400 return false;
401 }
402}
403
405 // TODO: Handle more opcodes and recipes.
407 return false;
408 unsigned Opcode = getOpcode(V);
409 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
410}
411
413 // Live-in, symbolic and canonical-IV region values are single-scalar.
414 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
415 return RV == RV->getDefiningRegion()->getCanonicalIV();
417 return true;
418
419 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
420 const VPRegionBlock *RegionOfR = Rep->getRegion();
421 // Don't consider recipes in replicate regions as uniform yet; their first
422 // lane cannot be accessed when executing the replicate region for other
423 // lanes.
424 if (RegionOfR && RegionOfR->isReplicator())
425 return false;
426 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
427 all_of(Rep->operands(), isSingleScalar));
428 }
431 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
432 return preservesUniformity(WidenR->getOpcode()) &&
433 all_of(WidenR->operands(), isSingleScalar);
434 }
435 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
436 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
437 (preservesUniformity(VPI->getOpcode()) &&
438 all_of(VPI->operands(), isSingleScalar));
439 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
440 return !RR->isPartialReduction();
442 VPV))
443 return true;
444 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
445 return Expr->isVectorToScalar();
446
447 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
448 return isa<VPExpandSCEVRecipe>(VPV);
449}
450
452 // Live-ins, symbolic and canonical-IV region values are uniform.
453 if (auto *RV = dyn_cast<VPRegionValue>(V))
454 return RV == RV->getDefiningRegion()->getCanonicalIV();
456 return true;
457
458 const VPRecipeBase *R = V->getDefiningRecipe();
459 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
460 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
461 if (VPBB &&
462 (VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
463 if (match(R,
466 return false;
467 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
468 }
469
471 .Case([](const VPDerivedIVRecipe *R) { return true; })
472 .Case([](const VPReplicateRecipe *R) {
473 // Be conservative about side-effects, except for the
474 // known-side-effecting assumes and stores, which we know will be
475 // uniform.
476 return R->isSingleScalar() &&
477 (!R->mayHaveSideEffects() ||
478 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
479 all_of(R->operands(), isUniformAcrossVFsAndUFs);
480 })
481 .Case([](const VPWidenRecipe *R) {
482 return preservesUniformity(R->getOpcode()) &&
483 all_of(R->operands(), isUniformAcrossVFsAndUFs);
484 })
485 .Case([](const VPPhi *) {
486 // Bail out on VPPhi, as we can end up in infinite cycles.
487 return false;
488 })
489 .Case([](const VPInstruction *VPI) {
490 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
493 })
494 .Case([](const VPWidenCastRecipe *R) {
495 // A cast is uniform according to its operand.
496 return isUniformAcrossVFsAndUFs(R->getOperand(0));
497 })
498 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
499 // unless proven otherwise.
500 return false;
501 });
502}
503
505 if (auto *RepR = dyn_cast<VPReplicateRecipe>(R))
506 return RepR->doesGeneratePerAllLanes();
507 if (auto *VPI = dyn_cast<VPInstruction>(R))
508 return VPI->doesGeneratePerAllLanes();
509 if (auto *SIVSteps = dyn_cast<VPScalarIVStepsRecipe>(R))
510 return SIVSteps->doesGeneratePerAllLanes();
511 return false;
512}
513
515 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
516 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
517 return VPBlockUtils::isHeader(VPB, VPDT);
518 });
519 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
520}
521
523 if (!R)
524 return 1;
525 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
526 return RR->getVFScaleFactor();
527 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
528 return RR->getVFScaleFactor();
529 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
530 return ER->getVFScaleFactor();
531 assert(
534 "getting scaling factor of reduction-start-vector not implemented yet");
535 return 1;
536}
537
538bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
539 // Assumes don't alias anything or throw; as long as they're guaranteed to
540 // execute, they're safe to hoist. They should however not be sunk, as it
541 // would destroy information.
543 return Sinking;
544 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
545 return true;
546 // Allocas cannot be hoisted.
547 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
548 return RepR && RepR->getOpcode() == Instruction::Alloca;
549}
550
553 VPBasicBlock *LastBB) {
554 assert(FirstBB->getParent() == LastBB->getParent() &&
555 "FirstBB and LastBB from different regions");
556#ifndef NDEBUG
557 bool InSingleSuccChain = false;
558 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
559 InSingleSuccChain |= (Succ == LastBB);
560 assert(InSingleSuccChain &&
561 "LastBB unreachable from FirstBB in single-successor chain");
562#endif
563 auto Blocks = to_vector(
565 auto *LastIt = find(Blocks, LastBB);
566 assert(LastIt != Blocks.end() &&
567 "LastBB unreachable from FirstBB in depth-first traversal");
568 Blocks.erase(std::next(LastIt), Blocks.end());
569 return Blocks;
570}
571
573 for (VPRecipeBase &R : *Plan.getVectorPreheader())
575 return cast<VPInstruction>(&R);
576 return nullptr;
577}
578
580vputils::getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB) {
582 for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks())
583 for (VPBlockBase *Pred : ExitVPBB->getPredecessors())
584 if (Pred != MiddleVPBB)
585 Exits.emplace_back(cast<VPBasicBlock>(Pred), ExitVPBB);
586 return Exits;
587}
588
591 Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp,
592 Instruction *TruncI, VPIRValue *StartV, VPValue *Step, DebugLoc DL,
593 VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags) {
594 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
595 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
596 VPValue *CanonicalIV = LoopRegion->getCanonicalIV();
597 VPSingleDefRecipe *BaseIV =
598 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
599
600 // Truncate base induction if needed.
601 Type *ResultTy = BaseIV->getScalarType();
602 if (TruncI) {
603 Type *TruncTy = TruncI->getType();
604 assert(ResultTy->getScalarSizeInBits() > TruncTy->getScalarSizeInBits() &&
605 "Not truncating.");
606 assert(ResultTy->isIntegerTy() && "Truncation requires an integer type");
607 BaseIV = Builder.createScalarCast(Instruction::Trunc, BaseIV, TruncTy, DL);
608 ResultTy = TruncTy;
609 }
610
611 // Truncate step if needed.
612 Type *StepTy = Step->getScalarType();
613 if (ResultTy != StepTy) {
614 assert(StepTy->getScalarSizeInBits() > ResultTy->getScalarSizeInBits() &&
615 "Not truncating.");
616 assert(StepTy->isIntegerTy() && "Truncation requires an integer type");
617 auto *VecPreheader =
619 VPBuilder::InsertPointGuard Guard(Builder);
620 Builder.setInsertPoint(VecPreheader);
621 Step = Builder.createScalarCast(Instruction::Trunc, Step, ResultTy, DL);
622 }
623 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
624 &Plan.getVF(), DL);
625}
626
627VPValue *
629 VPlan &Plan, VPBuilder &Builder) {
630 const InductionDescriptor &ID = PtrIV->getInductionDescriptor();
631 VPIRValue *StartV = Plan.getZero(ID.getStep()->getType());
632 VPValue *StepV = PtrIV->getOperand(1);
634 Plan, InductionDescriptor::IK_IntInduction, Instruction::Add, nullptr,
635 nullptr, StartV, StepV, PtrIV->getDebugLoc(), Builder);
636
637 return Builder.createPtrAdd(PtrIV->getStartValue(), Steps,
638 PtrIV->getDebugLoc(), "next.gep");
639}
640
642 const VPDominatorTree &VPDT) {
643 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
644 if (!VPBB)
645 return false;
646
647 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
648 // VPBB as its entry, i.e., free of predecessors.
649 if (auto *R = VPBB->getParent())
650 return !R->isReplicator() && !VPBB->hasPredecessors();
651
652 // A header dominates its second predecessor (the latch), with the other
653 // predecessor being the preheader
654 return VPB->getPredecessors().size() == 2 &&
655 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
656}
657
659 const VPDominatorTree &VPDT) {
660 // A latch has a header as its last successor, with its other successors
661 // leaving the loop. A preheader OTOH has a header as its first (and only)
662 // successor.
663 return VPB->getNumSuccessors() >= 2 &&
665}
666
667std::pair<VPBasicBlock *, VPBasicBlock *>
670 Plan.getEntry()->getNumSuccessors() == 1
671 ? Plan.getEntry()->getSingleSuccessor()
672 : Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
673 assert(Header->getNumPredecessors() == 2 &&
674 "Header must have exactly 2 predecessors");
675 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
676 return {Header, Latch};
677}
678
682
683std::optional<MemoryLocation>
685 auto *M = dyn_cast<VPIRMetadata>(&R);
686 if (!M)
687 return std::nullopt;
689 // Populate noalias metadata from VPIRMetadata.
690 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
691 Loc.AATags.NoAlias = NoAliasMD;
692 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
693 Loc.AATags.Scope = AliasScopeMD;
694 return Loc;
695}
696
698 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
699 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
700 assert(CanIV && "Expected loop region to have a canonical IV");
701
702 VPSymbolicValue &VFxUF = Plan.getVFxUF();
703
704 // Check if \p Step matches the expected increment step, accounting for
705 // materialization of VFxUF and UF.
706 auto IsIncrementStep = [&](VPValue *Step) -> bool {
707 if (!VFxUF.isMaterialized())
708 return Step == &VFxUF;
709
710 VPSymbolicValue &UF = Plan.getUF();
711 if (!UF.isMaterialized())
712 return Step == &UF ||
713 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
714
715 // Alias masking: step is number of active lanes of a dependence mask.
716 if (match(Step, m_ZExtOrTruncOrSelf(
718 return true;
719
720 unsigned ConcreteUF = Plan.getConcreteUF();
721 // Fixed VF: step is just the concrete UF.
722 if (match(Step, m_SpecificInt(ConcreteUF)))
723 return true;
724
725 // Scalable VF: step involves VScale.
726 if (ConcreteUF == 1)
727 return match(Step, m_VScale());
728 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
729 return true;
730 // mul(VScale, ConcreteUF) may have been simplified to
731 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
732 return isPowerOf2_32(ConcreteUF) &&
733 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
734 };
735
736 VPInstruction *Increment = nullptr;
737 for (VPUser *U : CanIV->users()) {
738 VPValue *Step;
739 if (isa<VPInstruction>(U) &&
740 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
741 IsIncrementStep(Step)) {
742 assert(!Increment && "There must be a unique increment");
744 }
745 }
746
747 assert((!VFxUF.isMaterialized() || Increment) &&
748 "After materializing VFxUF, an increment must exist");
749 assert((!Increment ||
750 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
751 "NUW flag in region and increment must match");
752 return Increment;
753}
754
755/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
756/// inserted for predicated reductions or tail folding.
758 VPValue *BackedgeVal = PhiR->getBackedgeValue();
759 if (auto *Res =
761 return Res;
762
763 // Look through selects inserted for tail folding or predicated reductions.
764 VPRecipeBase *SelR =
765 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
766 if (!SelR)
767 return nullptr;
770}
771
774 SmallVector<const VPValue *> WorkList = {V};
775
776 while (!WorkList.empty()) {
777 const VPValue *Cur = WorkList.pop_back_val();
778 if (!Seen.insert(Cur).second)
779 continue;
780
781 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
782 // Skip blends that use V only through a compare by checking if any incoming
783 // value was already visited.
784 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
785 [&](unsigned I) {
786 return Seen.contains(Blend->getIncomingValue(I));
787 }))
788 continue;
789
790 for (VPUser *U : Cur->users()) {
791 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
792 if (InterleaveR->getAddr() == Cur)
793 return true;
794 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
795 // store (operand 1).
798 m_Specific(Cur)))))
799 return true;
801 if (MemR->getAddr() == Cur && MemR->isConsecutive())
802 return true;
803 }
804 }
805
806 // The legacy cost model only supports scalarization loads/stores with phi
807 // addresses, if the phi is directly used as load/store address. Don't
808 // traverse further for Blends.
809 if (Blend)
810 continue;
811
812 // Only traverse further through users that also define a value (and can
813 // thus have their own users walked). Skip when Cur is only used as mask ,
814 // as well as loads: a loaded value does not depend on the load's operand.
815 for (VPUser *U : Cur->users()) {
816 auto *VPI = dyn_cast<VPInstruction>(U);
817 if (VPI && VPI->getMask() == Cur &&
818 none_of(VPI->operandsWithoutMask(), equal_to(Cur)))
819 continue;
821 continue;
822 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
823 WorkList.push_back(SDR);
824 }
825 }
826 return false;
827}
828
829/// Try to find a loop-invariant IR value for \p S in the plan's entry block
830/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
831/// if no reusable IR value is found.
832VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
834 return nullptr;
835 VPlan &Plan = Builder.getPlan();
836 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
837 for (Value *V : SE.getSCEVValues(S)) {
838 // Only reuse instructions in the plan's entry block, or, when a
839 // DominatorTree is available, any instruction that dominates it.
840 // Instructions in sibling branches may not dominate the entry block.
841 auto *I = dyn_cast<Instruction>(V);
842 if (!I)
843 return Plan.getOrAddLiveIn(V);
844 if (!SE.DT.dominates(I->getParent(), PH))
845 continue;
846 SmallVector<Instruction *> DropPoisonGeneratingInsts;
847 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
848 continue;
849 for (Instruction *DropI : DropPoisonGeneratingInsts)
851 return Plan.getOrAddLiveIn(V);
852 }
853 return nullptr;
854}
855
857 if (VPValue *V = tryToReuseIRValue(S))
858 return V;
859
860 switch (S->getSCEVType()) {
861 case scConstant:
862 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
863 case scUnknown:
864 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
865 case scVScale:
866 return Builder.createVScale(S->getType(), DL);
867 case scAddExpr: {
868 auto *AddE = cast<SCEVAddExpr>(S);
869 VPIRFlags::WrapFlagsTy WrapFlags(AddE->hasNoUnsignedWrap(),
870 AddE->hasNoSignedWrap());
871
872 // Expanded poiner SCEVAddExpr as a ptradd of the pointer base and the
873 // integer offset, matching SCEVExpander.
874 if (S->getType()->isPointerTy()) {
875 VPValue *Base = tryToExpand(SE.getPointerBase(S));
876 if (!Base)
877 return nullptr;
878 VPValue *Offset = tryToExpand(SE.removePointerBase(S));
879 if (!Offset)
880 return nullptr;
881 GEPNoWrapFlags GEPFlags = WrapFlags.HasNUW
884 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
885 }
886
887 // Non-constant-negative add operands are expanded negated and subtracted
888 // from the running result below, instead of being negated and added.
889 auto UseSubtract = [](const SCEV *Op) {
890 return Op->isNonConstantNegative();
891 };
892 // Iterate in reverse so that constants are emitted last, and move the
893 // subtracted operands last, matching SCEVExpander's LoopCompare, so that
894 // they don't start the running result.
895 SmallVector<const SCEV *, 2> SCEVOps(reverse(AddE->operands()));
896 stable_sort(SCEVOps, [&](const SCEV *L, const SCEV *R) {
897 return !UseSubtract(L) && UseSubtract(R);
898 });
900 for (const SCEV *Op : SCEVOps) {
901 // The first operand starts the result, so it is never subtracted.
902 bool Negate = !Ops.empty() && UseSubtract(Op);
903 VPValue *OpV = tryToExpand(Negate ? SE.getNegativeSCEV(Op) : Op);
904 if (!OpV)
905 return nullptr;
906 Ops.push_back(OpV);
907 }
908 VPValue *Result = Ops.front();
909 for (auto [Op, OpV] : drop_begin(zip_equal(SCEVOps, Ops))) {
910 if (UseSubtract(Op)) {
911 // Result + (-Op) == Result - Op, which saves the multiply for the
912 // negation. NSW only transfers if negating Op cannot overflow, see
913 // ScalarEvolution::getMinusSCEV.
914 bool HasNSW =
915 WrapFlags.HasNSW && !SE.getSignedRangeMin(Op).isMinSignedValue();
916 Result = Builder.createOverflowingOp(Instruction::Sub, {Result, OpV},
917 {/*HasNUW=*/false, HasNSW}, DL);
918 continue;
919 }
920 Result = Builder.createOverflowingOp(Instruction::Add, {Result, OpV},
921 WrapFlags, DL);
922 }
923 return Result;
924 }
925 case scMulExpr: {
926 auto *MulE = cast<SCEVMulExpr>(S);
927 VPIRFlags::WrapFlagsTy WrapFlags(MulE->hasNoUnsignedWrap(),
928 MulE->hasNoSignedWrap());
930 for (const SCEV *Op : reverse(MulE->operands())) {
931 VPValue *OpV = tryToExpand(Op);
932 if (!OpV)
933 return nullptr;
934 Ops.push_back(OpV);
935 }
936 VPValue *Result = Ops.front();
937 for (VPValue *OpV : drop_begin(Ops)) {
938 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, OpV},
939 WrapFlags, DL);
940 }
941 return Result;
942 }
943 case scUDivExpr: {
944 auto *UDiv = cast<SCEVUDivExpr>(S);
945 VPValue *LHS = tryToExpand(UDiv->getLHS());
946 if (!LHS)
947 return nullptr;
948 const SCEV *RHSExpr = UDiv->getRHS();
949 VPValue *RHS = tryToExpand(RHSExpr);
950 if (!RHS)
951 return nullptr;
952 if (SafeUDivMode) {
953 // Make sure the UDiv's divisor is guaranteed to not be zero/poison, to
954 // avoid UB.
955 Type *Ty = UDiv->getType();
956 bool GuaranteedNotPoison =
958 if (!GuaranteedNotPoison)
959 RHS = Builder.createScalarFreeze(RHS, DL);
960 if (!SE.isKnownNonZero(RHSExpr) || !GuaranteedNotPoison)
961 RHS = Builder.createScalarIntrinsic(
962 Intrinsic::umax, {RHS, Builder.getPlan().getConstantInt(Ty, 1)}, Ty,
963 DL);
964 }
965 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
966 VPIRFlags::getDefaultFlags(Instruction::UDiv),
967 DL);
968 }
969 case scTruncate:
970 case scZeroExtend:
971 case scSignExtend:
972 case scPtrToAddr: {
973 auto *Cast = cast<SCEVCastExpr>(S);
974 VPValue *Op = tryToExpand(Cast->getOperand());
975 if (!Op)
976 return nullptr;
978 switch (S->getSCEVType()) {
979 case scTruncate:
980 Opcode = Instruction::Trunc;
981 break;
982 case scZeroExtend:
983 Opcode = Instruction::ZExt;
984 break;
985 case scSignExtend:
986 Opcode = Instruction::SExt;
987 break;
988 case scPtrToAddr:
989 Opcode = Instruction::PtrToAddr;
990 break;
991 default:
992 llvm_unreachable("Unhandled cast SCEV");
993 }
994
995 // When expanding ptrtoaddr, first check if there's an existing ptrtoint we
996 // can reuse.
997 if (Opcode == Instruction::PtrToAddr) {
998 VPlan &Plan = Builder.getPlan();
999 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1000 if (auto *IRV = dyn_cast<VPIRValue>(Op)) {
1002 IRV->getValue(), S->getType(), PH->getDataLayout(),
1003 [&](const CastInst *CI) {
1004 return SE.DT.dominates(CI->getParent(), PH);
1005 }))
1006 return Plan.getOrAddLiveIn(CI);
1007 }
1008 }
1009
1010 return Builder.createScalarCast(Opcode, Op, S->getType(), DL);
1011 }
1012 case scUMaxExpr:
1013 case scSMaxExpr:
1014 case scUMinExpr:
1015 case scSMinExpr:
1016 case scSequentialUMinExpr: {
1017 auto *MinMax = cast<SCEVNAryExpr>(S);
1018 Intrinsic::ID IntrinsicID;
1019 switch (S->getSCEVType()) {
1020 case scUMaxExpr:
1021 IntrinsicID = Intrinsic::umax;
1022 break;
1023 case scSMaxExpr:
1024 IntrinsicID = Intrinsic::smax;
1025 break;
1026 case scUMinExpr:
1028 IntrinsicID = Intrinsic::umin;
1029 break;
1030 case scSMinExpr:
1031 IntrinsicID = Intrinsic::smin;
1032 break;
1033 default:
1034 llvm_unreachable("Unexpected min/max SCEV type");
1035 }
1036 // Chain operands in reverse order matching SCEVExpander's expansion of
1037 // min/max expressions. In SafeUDivMode freeze expansion results of operands
1038 // other than the first for sequential UMins, to avoid short-circuiting
1039 // divide-by-0/poison.
1040 bool IsSequential = S->getSCEVType() == scSequentialUMinExpr;
1041 Type *ResultTy = MinMax->getType();
1042 bool PrevSafeMode = SafeUDivMode;
1044 for (const SCEV *SCEVOp : reverse(MinMax->operands())) {
1045 bool MayShortCircuit =
1046 IsSequential && Ops.size() != MinMax->getNumOperands() - 1;
1047 SafeUDivMode = MayShortCircuit || PrevSafeMode;
1048 VPValue *OpV = tryToExpand(SCEVOp);
1049 SafeUDivMode = PrevSafeMode;
1050 if (!OpV)
1051 return nullptr;
1052 if (MayShortCircuit)
1053 OpV = Builder.createScalarFreeze(OpV, DL);
1054 Ops.push_back(OpV);
1055 }
1056 VPValue *Result = Ops.front();
1057 for (VPValue *Op : drop_begin(Ops))
1058 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
1059 ResultTy, DL);
1060 return Result;
1061 }
1062 default:
1063 return nullptr;
1064 }
1065}
1066
1068 // Do remove conditional assume instructions as their conditions may be
1069 // flattened.
1070 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1071 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1073 if (IsConditionalAssume)
1074 return true;
1075
1076 if (R.mayHaveSideEffects())
1077 return false;
1078
1079 // Forbid removing trip-count expressions.
1080 if (isa<VPExpandSCEVRecipe>(R) &&
1081 R.getVPSingleValue() == R.getParent()->getPlan()->getTripCount())
1082 return false;
1083
1084 // Recipe is dead if no user keeps the recipe alive.
1085 return all_of(R.definedValues(), [](VPValue *V) { return V->user_empty(); });
1086}
1087
1089 SmallVector<VPValue *> WorkList;
1091 WorkList.push_back(V);
1092
1093 while (!WorkList.empty()) {
1094 VPValue *Cur = WorkList.pop_back_val();
1095 if (!Seen.insert(Cur).second)
1096 continue;
1097 VPRecipeBase *R = Cur->getDefiningRecipe();
1098 if (!R)
1099 continue;
1100 if (!isDeadRecipe(*R))
1101 continue;
1102 append_range(WorkList, R->operands());
1103 R->eraseFromParent();
1104 }
1105}
1106
1109 for (unsigned I = 0; I != Users.size(); ++I) {
1111 for (VPValue *V : Cur->definedValues())
1112 Users.insert_range(V->users());
1113 }
1114 return Users.takeVector();
1115}
1116
1119 const DataLayout &DL) {
1120 auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
1121 if (!OpcodeOrIID)
1122 return nullptr;
1123
1125 for (VPValue *Op : Operands) {
1126 VPValue *Candidate = Op;
1127 match(Op, m_Broadcast(m_VPValue(Candidate)));
1128 if (!match(Candidate, m_LiveIn()))
1129 return nullptr;
1130 Value *V = Candidate->getUnderlyingValue();
1131 if (!V)
1132 return nullptr;
1133 Ops.push_back(V);
1134 }
1135
1136 VPlan &Plan = *R.getParent()->getPlan();
1137 auto FoldToIRValue = [&]() -> Value * {
1138 InstSimplifyFolder Folder(DL);
1139 if (OpcodeOrIID->first) {
1140 // VPInstructions store the called intrinsic as last operand.
1141 if (isa<VPInstruction>(R))
1142 Ops.pop_back();
1143
1144 auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(&R);
1145 return Folder.FoldIntrinsic(OpcodeOrIID->second, Ops, R.getScalarType(),
1146 RFlags ? RFlags->getFastMathFlagsOrNone()
1147 : FastMathFlags());
1148 }
1149 unsigned Opcode = OpcodeOrIID->second;
1150 if (Instruction::isBinaryOp(Opcode))
1151 return Folder.FoldBinOp(static_cast<Instruction::BinaryOps>(Opcode),
1152 Ops[0], Ops[1]);
1153 if (Instruction::isCast(Opcode))
1154 return Folder.FoldCast(static_cast<Instruction::CastOps>(Opcode), Ops[0],
1155 R.getVPSingleValue()->getScalarType());
1156 switch (Opcode) {
1157 case VPInstruction::Not:
1158 return Folder.FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
1160 case Instruction::Select:
1161 return Folder.FoldSelect(Ops[0], Ops[1], Ops[2]);
1162 case Instruction::ICmp:
1163 case Instruction::FCmp:
1164 return Folder.FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
1165 Ops[1]);
1166 case Instruction::GetElementPtr: {
1167 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
1168 auto *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
1169 return Folder.FoldGEP(GEP->getSourceElementType(), Ops[0],
1170 drop_begin(Ops), RFlags.getGEPNoWrapFlags());
1171 }
1174 return Folder.FoldGEP(IntegerType::getInt8Ty(Plan.getContext()), Ops[0],
1175 Ops[1],
1176 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
1177 // An extract of a live-in is an extract of a broadcast, so return the
1178 // broadcasted element.
1179 case Instruction::ExtractElement:
1180 assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
1181 return Ops[0];
1182 }
1183 return nullptr;
1184 };
1185
1186 if (Value *V = FoldToIRValue())
1187 return Plan.getOrAddLiveIn(V);
1188 return nullptr;
1189}
1190
1192 VPlan &Plan, function_ref<VPValue *(VPValue *Op)> MatchPerm,
1195 vp_depth_first_deep(Plan.getEntry()))) {
1196 for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
1197 auto *Def = dyn_cast<VPSingleDefRecipe>(&R);
1198 if (!Def || !isElementwise(Def))
1199 continue;
1200
1201 // At least one of the ops must be a permutation.
1202 if (none_of(Def->operands(), MatchPerm))
1203 continue;
1204
1205 // All operands must be a single-use permutation or a live in (splat).
1206 if (!all_of(Def->operands(), [&MatchPerm](VPValue *Op) {
1207 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1208 }))
1209 continue;
1210
1211 // Remove the inner permutations.
1212 for (unsigned I = 0, E = Def->getNumOperands(); I != E; ++I)
1213 if (VPValue *X = MatchPerm(Def->getOperand(I)))
1214 Def->setOperand(I, X);
1215
1216 VPSingleDefRecipe *Res = BuildPerm(Def);
1217 Res->insertAfter(Def);
1218 Def->replaceUsesWithIf(
1219 Res, [&Res](VPUser &U, unsigned _) { return &U != Res; });
1220 }
1221 }
1222}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
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 I(x, y, z)
Definition MD5.cpp:57
This file provides utility analysis objects describing memory locations.
SI Fold Operands
This file implements a set that has insertion order iteration characteristics.
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 preservesUniformity(unsigned Opcode)
Returns true if Opcode preserves uniformity, i.e., if all operands are uniform, the result will also ...
static bool poisonGuaranteesUB(const VPValue *V)
Returns true if V being poison is guaranteed to trigger UB because it propagates to the address of a ...
static const uint32_t IV[8]
Definition blake3_impl.h:83
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:512
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
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_IntInduction
Integer induction variable. Step = C.
InstSimplifyFolder - Use InstructionSimplify to fold operations to existing values.
bool isCast() const
bool isBinaryOp() const
bool isUnaryOp() const
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1069
Representation for a specific memory location.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEV * getPredicatedSCEV(const SCEV *Expr)
Returns the rewritten SCEV for Expr in the context of the current SCEV predicate.
static LLVM_ABI void dropPoisonGeneratingAnnotationsAndReinfer(ScalarEvolution &SE, Instruction *I)
Drop poison-generating flags from I, then try re-infer via SCEV.
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 ...
This class represents an analyzed expression in the program.
static constexpr auto FlagAnyWrap
static constexpr auto FlagNSW
Type * getType() const
Return the LLVM type of this SCEV expression.
SCEVTypes getSCEVType() const
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 uint64_t getTypeSizeInBits(Type *Ty) const
Return the size in bits of the specified type, for which isSCEVable must return true.
LLVM_ABI const SCEV * getConstant(ConstantInt *V)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
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 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 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 const SCEV * getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, 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 * getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI const SCEV * getSMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI bool canReuseInstruction(const SCEV *S, Instruction *I, SmallVectorImpl< Instruction * > &DropPoisonGeneratingInsts)
Check whether it is poison-safe to represent the expression S using the instruction I.
LLVM_ABI const SCEV * getGEPExpr(GEPOperator *GEP, ArrayRef< SCEVUse > IndexExprs)
Returns an expression for a GEP.
LLVM_ABI const SCEV * getUMinExpr(SCEVUse LHS, SCEVUse RHS, bool Sequential=false)
LLVM_ABI const SCEV * getTruncateOrSignExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
A vector that has set insertion semantics.
Definition SetVector.h:57
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.
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:282
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:307
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:232
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4396
iterator end()
Definition VPlan.h:4433
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:266
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4462
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:93
VPRegionBlock * getParent()
Definition VPlan.h:191
size_t getNumSuccessors() const
Definition VPlan.h:242
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:227
VPlan * getPlan()
Definition VPlan.cpp:211
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:216
VPBlockBase * getSingleHierarchicalPredecessor()
Definition VPlan.h:278
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:232
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:216
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:388
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.
RAII object that stores the current insertion point and restores it when the object is destroyed.
VPlan-based builder utility analogous to IRBuilder.
ArrayRef< VPRecipeValue * > definedValues()
Returns an ArrayRef of the values defined by the VPDef.
Definition VPlanValue.h:573
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4190
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:4022
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2498
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4549
static 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:1235
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1332
unsigned getOpcode() const
Definition VPlan.h:1429
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:410
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:560
void insertAfter(VPRecipeBase *InsertPos)
Insert an unlinked Recipe into a basic block immediately after the specified Recipe.
Type * getScalarType() const
Returns the scalar type of this VPRecipeValue.
Definition VPlanValue.h:354
A recipe for handling reduction phis.
Definition VPlan.h:2870
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4621
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4697
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4785
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4741
VPValues are defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:252
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3404
VPValue * tryToExpand(const SCEV *S)
Try to expand S into recipes and live-ins using the builder.
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4251
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:618
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:217
bool isMaterialized() const
Returns true if this value has been materialized.
Definition VPlanValue.h:235
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:401
operand_range operands()
Definition VPlanValue.h:474
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:442
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:149
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:130
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:1894
A recipe for handling GEP instructions.
Definition VPlan.h:2221
VPIRValue * getStartValue() const
Returns the start value of the induction.
Definition VPlan.h:2573
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition VPlan.h:2596
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2625
A recipe for widened phis.
Definition VPlan.h:2757
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1828
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4808
LLVMContext & getContext() const
Definition VPlan.h:5018
VPBasicBlock * getEntry()
Definition VPlan.h:4904
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5016
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:4970
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:5090
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5116
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1080
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5068
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4909
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:5013
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4960
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5009
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_VScale()
Matches a call to llvm.vscale().
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
auto m_ZExtOrTruncOrSelf(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_commutative_match< Instruction::And, Op0_t, Op1_t > m_c_BinaryAnd(const Op0_t &Op0, const Op1_t &Op1)
Match a binary AND operation.
AllRecipe_match< Opcode, Op0_t, Op1_t > m_Binary(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_match< Opcode, Op0_t > m_Unary(const Op0_t &Op0)
auto m_GetElementPtr(const Op0_t &Op0, const Op1_t &Op1)
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
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.
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...
VPBasicBlock * getFirstLoopHeader(VPlan &Plan, VPDominatorTree &VPDT)
Returns the header block of the first, top-level loop, or null if none exist.
bool isAddressSCEVForCost(const SCEV *Addr, ScalarEvolution &SE, const Loop *L)
Returns true if Addr is an address SCEV that can be passed to TTI::getAddressComputationCost,...
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used.
Intrinsic::ID getIntrinsicID(const Ty *R)
Return the intrinsic ID underlying a call.
Definition VPlanUtils.h:85
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.
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.
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.
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.
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...
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.
VPScalarIVStepsRecipe * createScalarIVSteps(VPlan &Plan, InductionDescriptor::InductionKind Kind, Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, Instruction *TruncI, VPIRValue *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...
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
@ Offset
Definition DWP.cpp:578
void stable_sort(R &&Range)
Definition STLExtras.h:2116
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
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:840
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr from_range_t from_range
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
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:633
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:2173
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:332
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1753
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
@ Default
The result value is uniform if and only if all operands are uniform.
Definition Uniformity.h:20
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:279