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"
22#include "llvm/IR/Dominators.h"
24
25using namespace llvm;
26using namespace llvm::VPlanPatternMatch;
27using namespace llvm::SCEVPatternMatch;
28
30 return all_of(Def->users(),
31 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
32}
33
35 return all_of(Def->users(),
36 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
37}
38
40 return all_of(Def->users(),
41 [Def](const VPUser *U) { return U->usesScalars(Def); });
42}
43
45 if (auto *E = dyn_cast<SCEVConstant>(Expr))
46 return Plan.getOrAddLiveIn(E->getValue());
47 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
48 // value. Otherwise the value may be defined in a loop and using it directly
49 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
50 // form.
51 auto *U = dyn_cast<SCEVUnknown>(Expr);
52 if (U && !isa<Instruction>(U->getValue()))
53 return Plan.getOrAddLiveIn(U->getValue());
54 auto *Expanded = new VPExpandSCEVRecipe(Expr);
55 VPBasicBlock *EntryVPBB = Plan.getEntry();
56 auto Iter = EntryVPBB->getFirstNonPhi();
57 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
58 ++Iter;
59 EntryVPBB->insert(Expanded, Iter);
60 return Expanded;
61}
62
63/// Returns true if \p V being poison is guaranteed to trigger UB because it
64/// propagates to the address of a memory recipe.
65static bool poisonGuaranteesUB(const VPValue *V) {
68
69 auto PropagatesPoisonFromRecipeOp = [](const VPRecipeBase *R) {
71 return false;
72 unsigned Opcode = vputils::getOpcode(R->getVPSingleValue());
73 return Instruction::isCast(Opcode) || Opcode == Instruction::GetElementPtr;
74 };
75
76 Worklist.push_back(V);
77
78 while (!Worklist.empty()) {
79 const VPValue *Current = Worklist.pop_back_val();
80 if (!Visited.insert(Current).second)
81 continue;
82
83 for (VPUser *U : Current->users()) {
84 // Check if Current is used as an address operand for load/store.
85 auto *R = cast<VPRecipeBase>(U);
86 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(R)) {
87 if (MemR->getAddr() == Current)
88 return true;
89 continue;
90 }
91 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
92 unsigned Opcode = Rep->getOpcode();
93 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
94 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
95 return true;
96 }
97
98 // Check if poison propagates through this recipe to any of its users.
99 for (const VPValue *Op : R->operands()) {
100 if (Op == Current && PropagatesPoisonFromRecipeOp(R)) {
101 Worklist.push_back(R->getVPSingleValue());
102 break;
103 }
104 }
105 }
106 }
107
108 return false;
109}
110
112 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
113 // casts to find a root GEP VPInstruction.
114 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
115 unsigned Opcode = PtrVPI->getOpcode();
116 if (Opcode == Instruction::GetElementPtr) {
117 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
118 return PtrVPI->getGEPNoWrapFlags();
119 Ptr = PtrVPI->getOperand(0);
120 continue;
121 }
122 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
123 break;
124 Ptr = PtrVPI->getOperand(0);
125 }
126 return GEPNoWrapFlags::none();
127}
128
131 const Loop *L) {
132 ScalarEvolution &SE = *PSE.getSE();
133 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
134 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
135 "RegionValue must be canonical IV");
136 if (!L)
137 return SE.getCouldNotCompute();
138 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
140 }
141
143 Value *LiveIn = V->getUnderlyingValue();
144 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
145 return SE.getSCEV(LiveIn);
146 return SE.getCouldNotCompute();
147 }
148
149 // Helper to create SCEVs for binary and unary operations.
150 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
151 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
152 -> const SCEV * {
154 for (VPValue *Op : Ops) {
155 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
157 return SE.getCouldNotCompute();
158 SCEVOps.push_back(S);
159 }
160 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
161 };
162
163 VPValue *LHSVal, *RHSVal;
164 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
165 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
166 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
167 });
168 if (match(V, m_BinaryOr(m_VPValue(LHSVal), m_VPValue(RHSVal))))
169 if (cast<VPRecipeWithIRFlags>(V->getDefiningRecipe())->isDisjoint())
170 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
171 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
172 });
173 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
174 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
175 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
176 });
177 if (match(V, m_Not(m_VPValue(LHSVal)))) {
178 // not X = xor X, -1 = -1 - X
179 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
180 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
181 });
182 }
183 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
184 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
185 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
186 });
187 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
188 // amount >= the bit width produces poison; do not rewrite it, as
189 // getPowerOfTwo requires the power to be in range.
190 uint64_t ShiftAmt;
191 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
192 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
193 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
194 return SE.getMulExpr(Ops[0],
195 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
196 });
197 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
198 Type *Ty = V->getScalarType();
199 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
200 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
201 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
202 });
203 }
204 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
205 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
206 return SE.getUDivExpr(Ops[0], Ops[1]);
207 });
208 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
209 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
210 return SE.getURemExpr(Ops[0], Ops[1]);
211 });
212 // A SDiv with non-negative operands is equivalent to an UDiv.
213 if (match(V, m_SDiv(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
214 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
215 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
216 return SE.getCouldNotCompute();
217 return SE.getUDivExpr(Ops[0], Ops[1]);
218 });
219 }
220 // A SRem with non-negative operands is equivalent to an URem.
221 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
222 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
223 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
224 return SE.getCouldNotCompute();
225 return SE.getURemExpr(Ops[0], Ops[1]);
226 });
227 }
228 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
229 const APInt *Mask;
230 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
231 (*Mask + 1).isPowerOf2())
232 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
233 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
234 });
235 // SCEV models ptrtoaddr, but not ptrtoint, mirroring createSCEV.
236 if (match(V, m_PtrToAddr(m_VPValue(LHSVal))))
237 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
238 return SE.getPtrToAddrExpr(Ops[0]);
239 });
240 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
241 Type *DestTy = V->getScalarType();
242 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
243 return SE.getTruncateExpr(Ops[0], DestTy);
244 });
245 }
246 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
247 Type *DestTy = V->getScalarType();
248 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
249 return SE.getZeroExtendExpr(Ops[0], DestTy);
250 });
251 }
252 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
253 Type *DestTy = V->getScalarType();
254
255 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
256 // onto the operands before computing the subtraction.
257 VPValue *SubLHS, *SubRHS;
258 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
259 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
260 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
261 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
262 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
264 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
265 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
266 }
267
268 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
269 return SE.getSignExtendExpr(Ops[0], DestTy);
270 });
271 }
272 if (match(V,
274 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
275 return SE.getUMaxExpr(Ops[0], Ops[1]);
276 });
277 if (match(V,
279 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
280 return SE.getSMaxExpr(Ops[0], Ops[1]);
281 });
282 if (match(V,
284 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
285 return SE.getUMinExpr(Ops[0], Ops[1]);
286 });
287 if (match(V,
289 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
290 return SE.getSMinExpr(Ops[0], Ops[1]);
291 });
293 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
294 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
295 // not proof that the input is never INT_MIN, nor that poison reaches
296 // UB. Do not translate it to SCEV's global IsNSW flag.
297 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
298 });
299
301 Type *SourceElementType;
302 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
303 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
304 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
305 });
306 }
307
308 // TODO: Support constructing SCEVs for more recipes as needed.
309 const VPRecipeBase *DefR = V->getDefiningRecipe();
310 const SCEV *Expr =
312 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
313 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
314 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
315 if (!L || isa<SCEVCouldNotCompute>(Step))
316 return SE.getCouldNotCompute();
317 const SCEV *Start =
318 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
319 const SCEV *AddRec =
320 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
321 if (R->getTruncInst())
322 return SE.getTruncateExpr(AddRec, R->getScalarType());
323 return AddRec;
324 })
325 .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
326 const SCEV *Start =
327 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
328 if (!L || isa<SCEVCouldNotCompute>(Start))
329 return SE.getCouldNotCompute();
330 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
331 if (isa<SCEVCouldNotCompute>(Step))
332 return SE.getCouldNotCompute();
333 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
334 })
335 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
336 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
337 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
338 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
339 if (any_of(ArrayRef({Start, IV, Scale}),
341 return SE.getCouldNotCompute();
342
343 return SE.getAddExpr(
344 SE.getTruncateOrSignExtend(Start, IV->getType()),
345 SE.getMulExpr(
346 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
347 })
348 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
349 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
350 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
352 return SE.getCouldNotCompute();
353 return SE.getTruncateOrSignExtend(IV, Step->getType());
354 })
355 .Default(
356 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
357
358 return PSE.getPredicatedSCEV(Expr);
359}
360
362 const Loop *L) {
363 // If address is an SCEVAddExpr, we require that all operands must be either
364 // be invariant or a (possibly sign-extend) affine AddRec.
365 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
366 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
367 return SE.isLoopInvariant(Op, L) ||
368 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
369 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
370 });
371 }
372
373 // Otherwise, check if address is loop invariant or an affine add recurrence.
374 return SE.isLoopInvariant(Addr, L) ||
376}
377
378unsigned vputils::getOpcode(const VPValue *V) {
382 [](auto *I) { return I->getOpcode(); })
383 .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe, VPScalarIVStepsRecipe>(
384 [](auto *I) {
385 // For recipes that do not directly map to LLVM IR instructions,
386 // assign opcodes after the last VPInstruction opcode (which is also
387 // after the last IR Instruction opcode), based on the VPRecipeID.
388 return VPInstruction::OpsEnd + 1 + I->getVPRecipeID();
389 })
390 .Default([](auto *) { return 0; });
391}
392
393std::optional<std::pair<bool, unsigned>>
396 return std::make_pair(true, IID);
397 if (unsigned Opcode = vputils::getOpcode(V))
398 return std::make_pair(false, Opcode);
399 return {};
400}
401
402/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
403/// uniform, the result will also be uniform.
404static bool preservesUniformity(unsigned Opcode) {
405 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
406 return true;
407 switch (Opcode) {
408 case Instruction::Freeze:
409 case Instruction::GetElementPtr:
410 case Instruction::ICmp:
411 case Instruction::FCmp:
412 case Instruction::Select:
417 return true;
418 default:
419 return false;
420 }
421}
422
424 // TODO: Handle more opcodes and recipes.
426 return false;
427 unsigned Opcode = getOpcode(V);
428 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
429}
430
432 // Live-in, symbolic and canonical-IV region values are single-scalar.
433 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
434 return RV == RV->getDefiningRegion()->getCanonicalIV();
436 return true;
437
438 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
439 const VPRegionBlock *RegionOfR = Rep->getRegion();
440 // Don't consider recipes in replicate regions as uniform yet; their first
441 // lane cannot be accessed when executing the replicate region for other
442 // lanes.
443 if (RegionOfR && RegionOfR->isReplicator())
444 return false;
445 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
446 all_of(Rep->operands(), isSingleScalar));
447 }
450 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
451 return preservesUniformity(WidenR->getOpcode()) &&
452 all_of(WidenR->operands(), isSingleScalar);
453 }
454 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
455 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
456 (preservesUniformity(VPI->getOpcode()) &&
457 all_of(VPI->operands(), isSingleScalar));
458 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
459 return !RR->isPartialReduction();
461 VPV))
462 return true;
463 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
464 return Expr->isVectorToScalar();
465
466 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
467 return isa<VPExpandSCEVRecipe>(VPV);
468}
469
471 // Live-ins, symbolic and canonical-IV region values are uniform.
472 if (auto *RV = dyn_cast<VPRegionValue>(V))
473 return RV == RV->getDefiningRegion()->getCanonicalIV();
475 return true;
476
477 const VPRecipeBase *R = V->getDefiningRecipe();
478 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
479 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
480 if (VPBB &&
481 (VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
482 if (match(R,
485 return false;
486 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
487 }
488
490 .Case([](const VPDerivedIVRecipe *R) { return true; })
491 .Case([](const VPReplicateRecipe *R) {
492 // Be conservative about side-effects, except for the
493 // known-side-effecting assumes and stores, which we know will be
494 // uniform.
495 return R->isSingleScalar() &&
496 (!R->mayHaveSideEffects() ||
497 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
498 all_of(R->operands(), isUniformAcrossVFsAndUFs);
499 })
500 .Case([](const VPWidenRecipe *R) {
501 return preservesUniformity(R->getOpcode()) &&
502 all_of(R->operands(), isUniformAcrossVFsAndUFs);
503 })
504 .Case([](const VPPhi *) {
505 // Bail out on VPPhi, as we can end up in infinite cycles.
506 return false;
507 })
508 .Case([](const VPInstruction *VPI) {
509 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
512 })
513 .Case([](const VPWidenCastRecipe *R) {
514 // A cast is uniform according to its operand.
515 return isUniformAcrossVFsAndUFs(R->getOperand(0));
516 })
517 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
518 // unless proven otherwise.
519 return false;
520 });
521}
522
524 if (auto *RepR = dyn_cast<VPReplicateRecipe>(R))
525 return RepR->doesGeneratePerAllLanes();
526 if (auto *VPI = dyn_cast<VPInstruction>(R))
527 return VPI->doesGeneratePerAllLanes();
528 if (auto *SIVSteps = dyn_cast<VPScalarIVStepsRecipe>(R))
529 return SIVSteps->doesGeneratePerAllLanes();
530 return false;
531}
532
534 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
535 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
536 return VPBlockUtils::isHeader(VPB, VPDT);
537 });
538 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
539}
540
542 if (!R)
543 return 1;
544 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
545 return RR->getVFScaleFactor();
546 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
547 return RR->getVFScaleFactor();
548 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
549 return ER->getVFScaleFactor();
550 assert(
553 "getting scaling factor of reduction-start-vector not implemented yet");
554 return 1;
555}
556
557bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
558 // Assumes don't alias anything or throw; as long as they're guaranteed to
559 // execute, they're safe to hoist. They should however not be sunk, as it
560 // would destroy information.
562 return Sinking;
563 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
564 return true;
565 // Allocas cannot be hoisted.
566 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
567 return RepR && RepR->getOpcode() == Instruction::Alloca;
568}
569
572 VPBasicBlock *LastBB) {
573 assert(FirstBB->getParent() == LastBB->getParent() &&
574 "FirstBB and LastBB from different regions");
575#ifndef NDEBUG
576 bool InSingleSuccChain = false;
577 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
578 InSingleSuccChain |= (Succ == LastBB);
579 assert(InSingleSuccChain &&
580 "LastBB unreachable from FirstBB in single-successor chain");
581#endif
582 auto Blocks = to_vector(
584 auto *LastIt = find(Blocks, LastBB);
585 assert(LastIt != Blocks.end() &&
586 "LastBB unreachable from FirstBB in depth-first traversal");
587 Blocks.erase(std::next(LastIt), Blocks.end());
588 return Blocks;
589}
590
592 for (VPRecipeBase &R : *Plan.getVectorPreheader())
594 return cast<VPInstruction>(&R);
595 return nullptr;
596}
597
599vputils::getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB) {
601 for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks())
602 for (VPBlockBase *Pred : ExitVPBB->getPredecessors())
603 if (Pred != MiddleVPBB)
604 Exits.emplace_back(cast<VPBasicBlock>(Pred), ExitVPBB);
605 return Exits;
606}
607
610 Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp,
611 Instruction *TruncI, VPValue *StartV, VPValue *Step, DebugLoc DL,
612 VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags) {
613 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
614 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
615 VPValue *CanonicalIV = LoopRegion->getCanonicalIV();
616 VPSingleDefRecipe *BaseIV =
617 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
618
619 // Truncate base induction if needed.
620 Type *ResultTy = BaseIV->getScalarType();
621 if (TruncI) {
622 Type *TruncTy = TruncI->getType();
623 assert(ResultTy->getScalarSizeInBits() > TruncTy->getScalarSizeInBits() &&
624 "Not truncating.");
625 assert(ResultTy->isIntegerTy() && "Truncation requires an integer type");
626 BaseIV = Builder.createScalarCast(Instruction::Trunc, BaseIV, TruncTy, DL);
627 ResultTy = TruncTy;
628 }
629
630 // Truncate step if needed.
631 Type *StepTy = Step->getScalarType();
632 if (ResultTy != StepTy) {
633 assert(StepTy->getScalarSizeInBits() > ResultTy->getScalarSizeInBits() &&
634 "Not truncating.");
635 assert(StepTy->isIntegerTy() && "Truncation requires an integer type");
636 auto *VecPreheader =
638 VPBuilder::InsertPointGuard Guard(Builder);
639 Builder.setInsertPoint(VecPreheader);
640 Step = Builder.createScalarCast(Instruction::Trunc, Step, ResultTy, DL);
641 }
642 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
643 &Plan.getVF(), DL);
644}
645
646VPValue *
648 VPlan &Plan, VPBuilder &Builder) {
649 const InductionDescriptor &ID = PtrIV->getInductionDescriptor();
650 VPIRValue *StartV = Plan.getZero(ID.getStep()->getType());
651 VPValue *StepV = PtrIV->getOperand(1);
653 Plan, InductionDescriptor::IK_IntInduction, Instruction::Add, nullptr,
654 nullptr, StartV, StepV, PtrIV->getDebugLoc(), Builder);
655
656 return Builder.createPtrAdd(PtrIV->getStartValue(), Steps,
657 PtrIV->getDebugLoc(), "next.gep");
658}
659
661 const VPDominatorTree &VPDT) {
662 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
663 if (!VPBB)
664 return false;
665
666 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
667 // VPBB as its entry, i.e., free of predecessors.
668 if (auto *R = VPBB->getParent())
669 return !R->isReplicator() && !VPBB->hasPredecessors();
670
671 // A header dominates its second predecessor (the latch), with the other
672 // predecessor being the preheader
673 return VPB->getPredecessors().size() == 2 &&
674 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
675}
676
678 const VPDominatorTree &VPDT) {
679 // A latch has a header as its last successor, with its other successors
680 // leaving the loop. A preheader OTOH has a header as its first (and only)
681 // successor.
682 return VPB->getNumSuccessors() >= 2 &&
684}
685
686std::pair<VPBasicBlock *, VPBasicBlock *>
689 Plan.getEntry()->getNumSuccessors() == 1
690 ? Plan.getEntry()->getSingleSuccessor()
691 : Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
692 assert(Header->getNumPredecessors() == 2 &&
693 "Header must have exactly 2 predecessors");
694 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
695 return {Header, Latch};
696}
697
701
702std::optional<MemoryLocation>
704 auto *M = dyn_cast<VPIRMetadata>(&R);
705 if (!M)
706 return std::nullopt;
708 // Populate noalias metadata from VPIRMetadata.
709 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
710 Loc.AATags.NoAlias = NoAliasMD;
711 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
712 Loc.AATags.Scope = AliasScopeMD;
713 return Loc;
714}
715
717 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
718 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
719 assert(CanIV && "Expected loop region to have a canonical IV");
720
721 VPSymbolicValue &VFxUF = Plan.getVFxUF();
722
723 // Check if \p Step matches the expected increment step, accounting for
724 // materialization of VFxUF and UF.
725 auto IsIncrementStep = [&](VPValue *Step) -> bool {
726 if (!VFxUF.isMaterialized())
727 return Step == &VFxUF;
728
729 VPSymbolicValue &UF = Plan.getUF();
730 if (!UF.isMaterialized())
731 return Step == &UF ||
732 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
733
734 // Alias masking: step is number of active lanes of a dependence mask.
735 if (match(Step, m_ZExtOrTruncOrSelf(
737 return true;
738
739 unsigned ConcreteUF = Plan.getConcreteUF();
740 // Fixed VF: step is just the concrete UF.
741 if (match(Step, m_SpecificInt(ConcreteUF)))
742 return true;
743
744 // Scalable VF: step involves VScale.
745 if (ConcreteUF == 1)
746 return match(Step, m_VScale());
747 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
748 return true;
749 // mul(VScale, ConcreteUF) may have been simplified to
750 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
751 return isPowerOf2_32(ConcreteUF) &&
752 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
753 };
754
755 VPInstruction *Increment = nullptr;
756 for (VPUser *U : CanIV->users()) {
757 VPValue *Step;
758 if (isa<VPInstruction>(U) &&
759 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
760 IsIncrementStep(Step)) {
761 assert(!Increment && "There must be a unique increment");
763 }
764 }
765
766 assert((!VFxUF.isMaterialized() || Increment) &&
767 "After materializing VFxUF, an increment must exist");
768 assert((!Increment ||
769 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
770 "NUW flag in region and increment must match");
771 return Increment;
772}
773
774/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
775/// inserted for predicated reductions or tail folding.
777 VPValue *BackedgeVal = PhiR->getBackedgeValue();
778 if (auto *Res =
780 return Res;
781
782 // Look through selects inserted for tail folding or predicated reductions.
783 VPRecipeBase *SelR =
784 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
785 if (!SelR)
786 return nullptr;
789}
790
793 SmallVector<const VPValue *> WorkList = {V};
794
795 while (!WorkList.empty()) {
796 const VPValue *Cur = WorkList.pop_back_val();
797 if (!Seen.insert(Cur).second)
798 continue;
799
800 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
801 // Skip blends that use V only through a compare by checking if any incoming
802 // value was already visited.
803 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
804 [&](unsigned I) {
805 return Seen.contains(Blend->getIncomingValue(I));
806 }))
807 continue;
808
809 for (VPUser *U : Cur->users()) {
810 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
811 if (InterleaveR->getAddr() == Cur)
812 return true;
813 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
814 // store (operand 1).
817 m_Specific(Cur)))))
818 return true;
820 if (MemR->getAddr() == Cur && MemR->isConsecutive())
821 return true;
822 }
823 }
824
825 // The legacy cost model only supports scalarization loads/stores with phi
826 // addresses, if the phi is directly used as load/store address. Don't
827 // traverse further for Blends.
828 if (Blend)
829 continue;
830
831 // Only traverse further through users that also define a value (and can
832 // thus have their own users walked). Skip when Cur is only used as mask ,
833 // as well as loads: a loaded value does not depend on the load's operand.
834 for (VPUser *U : Cur->users()) {
835 auto *VPI = dyn_cast<VPInstruction>(U);
836 if (VPI && VPI->getMask() == Cur &&
837 none_of(VPI->operandsWithoutMask(), equal_to(Cur)))
838 continue;
840 continue;
841 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
842 WorkList.push_back(SDR);
843 }
844 }
845 return false;
846}
847
848/// Try to find a loop-invariant IR value for \p S in the plan's entry block
849/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
850/// if no reusable IR value is found.
851VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
853 return nullptr;
854 VPlan &Plan = Builder.getPlan();
855 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
856 for (Value *V : SE.getSCEVValues(S)) {
857 // Only reuse instructions in the plan's entry block, or, when a
858 // DominatorTree is available, any instruction that dominates it.
859 // Instructions in sibling branches may not dominate the entry block.
860 auto *I = dyn_cast<Instruction>(V);
861 if (!I)
862 return Plan.getOrAddLiveIn(V);
863 if (!SE.DT.dominates(I->getParent(), PH))
864 continue;
865 SmallVector<Instruction *> DropPoisonGeneratingInsts;
866 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
867 continue;
868 for (Instruction *DropI : DropPoisonGeneratingInsts)
870 return Plan.getOrAddLiveIn(V);
871 }
872 return nullptr;
873}
874
876 if (VPValue *V = tryToReuseIRValue(S))
877 return V;
878
879 switch (S->getSCEVType()) {
880 case scConstant:
881 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
882 case scUnknown:
883 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
884 case scVScale:
885 return Builder.createVScale(S->getType(), DL);
886 case scAddExpr: {
887 auto *AddE = cast<SCEVAddExpr>(S);
888 VPIRFlags::WrapFlagsTy WrapFlags(AddE->hasNoUnsignedWrap(),
889 AddE->hasNoSignedWrap());
890
891 // Expand pointer SCEVAddExpr as a ptradd of the pointer base and the
892 // integer offset, matching SCEVExpander.
893 if (S->getType()->isPointerTy()) {
894 VPValue *Base = expand(SE.getPointerBase(S));
895 VPValue *Offset = expand(SE.removePointerBase(S));
896 GEPNoWrapFlags GEPFlags = WrapFlags.HasNUW
899 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
900 }
901
902 // Non-constant-negative add operands are expanded negated and subtracted
903 // from the running result below, instead of being negated and added.
904 auto UseSubtract = [](const SCEV *Op) {
905 return Op->isNonConstantNegative();
906 };
907 // Iterate in reverse so that constants are emitted last, and move the
908 // subtracted operands last, matching SCEVExpander's LoopCompare, so that
909 // they don't start the running result.
910 SmallVector<const SCEV *, 2> SCEVOps(reverse(AddE->operands()));
911 stable_sort(SCEVOps, [&](const SCEV *L, const SCEV *R) {
912 return !UseSubtract(L) && UseSubtract(R);
913 });
915 for (const SCEV *Op : SCEVOps) {
916 // The first operand starts the result, so it is never subtracted.
917 bool Negate = !Ops.empty() && UseSubtract(Op);
918 Ops.push_back(expand(Negate ? SE.getNegativeSCEV(Op) : Op));
919 }
920 VPValue *Result = Ops.front();
921 for (auto [Op, OpV] : drop_begin(zip_equal(SCEVOps, Ops))) {
922 if (UseSubtract(Op)) {
923 // Result + (-Op) == Result - Op, which saves the multiply for the
924 // negation. NSW only transfers if negating Op cannot overflow, see
925 // ScalarEvolution::getMinusSCEV.
926 bool HasNSW =
927 WrapFlags.HasNSW && !SE.getSignedRangeMin(Op).isMinSignedValue();
928 Result = Builder.createOverflowingOp(Instruction::Sub, {Result, OpV},
929 {/*HasNUW=*/false, HasNSW}, DL);
930 continue;
931 }
932 Result = Builder.createOverflowingOp(Instruction::Add, {Result, OpV},
933 WrapFlags, DL);
934 }
935 return Result;
936 }
937 case scMulExpr: {
938 auto *MulE = cast<SCEVMulExpr>(S);
939 VPIRFlags::WrapFlagsTy WrapFlags(MulE->hasNoUnsignedWrap(),
940 MulE->hasNoSignedWrap());
942 for (const SCEV *Op : reverse(MulE->operands()))
943 Ops.push_back(expand(Op));
944 VPValue *Result = Ops.front();
945 for (VPValue *OpV : drop_begin(Ops)) {
946 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, OpV},
947 WrapFlags, DL);
948 }
949 return Result;
950 }
951 case scUDivExpr: {
952 auto *UDiv = cast<SCEVUDivExpr>(S);
953 VPValue *LHS = expand(UDiv->getLHS());
954 const SCEV *RHSExpr = UDiv->getRHS();
955 VPValue *RHS = expand(RHSExpr);
956 if (SafeUDivMode) {
957 // Make sure the UDiv's divisor is guaranteed to not be zero/poison, to
958 // avoid UB.
959 Type *Ty = UDiv->getType();
960 bool GuaranteedNotPoison =
962 if (!GuaranteedNotPoison)
963 RHS = Builder.createScalarFreeze(RHS, DL);
964 if (!SE.isKnownNonZero(RHSExpr) || !GuaranteedNotPoison)
965 RHS = Builder.createScalarIntrinsic(
966 Intrinsic::umax, {RHS, Builder.getPlan().getConstantInt(Ty, 1)}, Ty,
967 DL);
968 }
969 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
970 VPIRFlags::getDefaultFlags(Instruction::UDiv),
971 DL);
972 }
973 case scTruncate:
974 case scZeroExtend:
975 case scSignExtend:
976 case scPtrToAddr: {
977 auto *Cast = cast<SCEVCastExpr>(S);
978 VPValue *Op = expand(Cast->getOperand());
980 switch (S->getSCEVType()) {
981 case scTruncate:
982 Opcode = Instruction::Trunc;
983 break;
984 case scZeroExtend:
985 Opcode = Instruction::ZExt;
986 break;
987 case scSignExtend:
988 Opcode = Instruction::SExt;
989 break;
990 case scPtrToAddr:
991 Opcode = Instruction::PtrToAddr;
992 break;
993 default:
994 llvm_unreachable("Unhandled cast SCEV");
995 }
996
997 // When expanding ptrtoaddr, first check if there's an existing ptrtoint we
998 // can reuse.
999 if (Opcode == Instruction::PtrToAddr) {
1000 VPlan &Plan = Builder.getPlan();
1001 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1002 if (auto *IRV = dyn_cast<VPIRValue>(Op)) {
1004 IRV->getValue(), S->getType(), PH->getDataLayout(),
1005 [&](const CastInst *CI) {
1006 return SE.DT.dominates(CI->getParent(), PH);
1007 }))
1008 return Plan.getOrAddLiveIn(CI);
1009 }
1010 }
1011
1012 return Builder.createScalarCast(Opcode, Op, S->getType(), DL);
1013 }
1014 case scUMaxExpr:
1015 case scSMaxExpr:
1016 case scUMinExpr:
1017 case scSMinExpr:
1018 case scSequentialUMinExpr: {
1019 auto *MinMax = cast<SCEVNAryExpr>(S);
1020 Intrinsic::ID IntrinsicID;
1021 switch (S->getSCEVType()) {
1022 case scUMaxExpr:
1023 IntrinsicID = Intrinsic::umax;
1024 break;
1025 case scSMaxExpr:
1026 IntrinsicID = Intrinsic::smax;
1027 break;
1028 case scUMinExpr:
1030 IntrinsicID = Intrinsic::umin;
1031 break;
1032 case scSMinExpr:
1033 IntrinsicID = Intrinsic::smin;
1034 break;
1035 default:
1036 llvm_unreachable("Unexpected min/max SCEV type");
1037 }
1038 // Chain operands in reverse order matching SCEVExpander's expansion of
1039 // min/max expressions. In SafeUDivMode freeze expansion results of operands
1040 // other than the first for sequential UMins, to avoid short-circuiting
1041 // divide-by-0/poison.
1042 bool IsSequential = S->getSCEVType() == scSequentialUMinExpr;
1043 Type *ResultTy = MinMax->getType();
1044 bool PrevSafeMode = SafeUDivMode;
1046 for (const SCEV *SCEVOp : reverse(MinMax->operands())) {
1047 bool MayShortCircuit =
1048 IsSequential && Ops.size() != MinMax->getNumOperands() - 1;
1049 SafeUDivMode = MayShortCircuit || PrevSafeMode;
1050 VPValue *OpV = expand(SCEVOp);
1051 SafeUDivMode = PrevSafeMode;
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 case scAddRecExpr: {
1063 auto *AR = cast<SCEVAddRecExpr>(S);
1064 VPlan &Plan = Builder.getPlan();
1065 [[maybe_unused]] BasicBlock *PH =
1066 cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1067 assert(SE.DT.dominates(AR->getLoop()->getHeader(), PH) &&
1068 "can only expand AddRecs for loops outside VPlan's scope");
1069
1070 // Try to expand AR by re-using an existing canonical IV in the Plan's
1071 // entry. A canonical IV must be affine and integer typed.
1072 if (!AR->isAffine() || !AR->getType()->isIntegerTy())
1074 auto FoundCanIV =
1075 find_if(Plan.getEntry()->phis(), [&](const VPRecipeBase &R) {
1076 if (!SE.isSCEVable(cast<VPIRPhi>(R).getIRPhi().getType()))
1077 return false;
1078 const SCEV *Candidate = SE.getSCEV(&cast<VPIRPhi>(R).getIRPhi());
1079 return match(Candidate,
1080 m_scev_AffineAddRec(m_scev_Zero(), m_scev_One(),
1081 m_SpecificLoop(AR->getLoop()))) &&
1082 Candidate->getType() == AR->getType();
1083 });
1084 if (FoundCanIV == Plan.getEntry()->phis().end())
1086
1087 // {Start, +, Step} --> Start + IV * Step, since the AddRec is affine.
1088 // Compute Offset = IV * Step.
1089 VPValue *Start = expand(AR->getStart());
1090 Value *CanonicalIV = &cast<VPIRPhi>(FoundCanIV)->getIRPhi();
1092 SE.getMulExpr(SE.getUnknown(CanonicalIV), AR->getStepRecurrence(SE)));
1093
1094 // Compute Start + Offset with nuw from the AddRec.
1095 return Builder.createAdd(Start, Offset, DL, "",
1096 {AR->hasNoUnsignedWrap(), false});
1097 }
1098 case scCouldNotCompute:
1099 llvm_unreachable("Attempt to expand a SCEVCouldNotCompute");
1100 }
1101 llvm_unreachable("Unknown SCEV kind!");
1102}
1103
1105 // Do remove conditional assume instructions as their conditions may be
1106 // flattened.
1107 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1108 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1110 if (IsConditionalAssume)
1111 return true;
1112
1113 if (R.mayHaveSideEffects())
1114 return false;
1115
1116 // Forbid removing trip-count expressions.
1117 if (isa<VPExpandSCEVRecipe>(R) &&
1118 R.getVPSingleValue() == R.getParent()->getPlan()->getTripCount())
1119 return false;
1120
1121 // Recipe is dead if no user keeps the recipe alive.
1122 return all_of(R.definedValues(), [](VPValue *V) { return V->user_empty(); });
1123}
1124
1126 SmallVector<VPValue *> WorkList;
1128 WorkList.push_back(V);
1129
1130 while (!WorkList.empty()) {
1131 VPValue *Cur = WorkList.pop_back_val();
1132 if (!Seen.insert(Cur).second)
1133 continue;
1134 VPRecipeBase *R = Cur->getDefiningRecipe();
1135 if (!R)
1136 continue;
1137 if (!isDeadRecipe(*R))
1138 continue;
1139 append_range(WorkList, R->operands());
1140 R->eraseFromParent();
1141 }
1142}
1143
1146 for (unsigned I = 0; I != Users.size(); ++I) {
1148 for (VPValue *V : Cur->definedValues())
1149 Users.insert_range(V->users());
1150 }
1151 return Users.takeVector();
1152}
1153
1156 const DataLayout &DL) {
1157 auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
1158 if (!OpcodeOrIID)
1159 return nullptr;
1160
1162 for (VPValue *Op : Operands) {
1163 VPValue *Candidate = Op;
1164 match(Op, m_Broadcast(m_VPValue(Candidate)));
1165 if (!match(Candidate, m_LiveIn()))
1166 return nullptr;
1167 Value *V = Candidate->getUnderlyingValue();
1168 if (!V)
1169 return nullptr;
1170 Ops.push_back(V);
1171 }
1172
1173 VPlan &Plan = *R.getParent()->getPlan();
1174 auto FoldToIRValue = [&]() -> Value * {
1175 InstSimplifyFolder Folder(DL);
1176 if (OpcodeOrIID->first) {
1177 // VPInstructions store the called intrinsic as last operand.
1178 if (isa<VPInstruction>(R))
1179 Ops.pop_back();
1180
1181 auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(&R);
1182 return Folder.FoldIntrinsic(OpcodeOrIID->second, Ops, R.getScalarType(),
1183 RFlags ? RFlags->getFastMathFlagsOrNone()
1184 : FastMathFlags());
1185 }
1186 unsigned Opcode = OpcodeOrIID->second;
1187 if (Instruction::isBinaryOp(Opcode))
1188 return Folder.FoldBinOp(static_cast<Instruction::BinaryOps>(Opcode),
1189 Ops[0], Ops[1]);
1190 if (Instruction::isCast(Opcode))
1191 return Folder.FoldCast(static_cast<Instruction::CastOps>(Opcode), Ops[0],
1192 R.getVPSingleValue()->getScalarType());
1193 switch (Opcode) {
1194 case VPInstruction::Not:
1195 return Folder.FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
1197 case Instruction::Select:
1198 return Folder.FoldSelect(Ops[0], Ops[1], Ops[2]);
1199 case Instruction::ICmp:
1200 case Instruction::FCmp:
1201 return Folder.FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
1202 Ops[1]);
1203 case Instruction::GetElementPtr: {
1204 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
1205 auto *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
1206 return Folder.FoldGEP(GEP->getSourceElementType(), Ops[0],
1207 drop_begin(Ops), RFlags.getGEPNoWrapFlags());
1208 }
1211 return Folder.FoldGEP(IntegerType::getInt8Ty(Plan.getContext()), Ops[0],
1212 Ops[1],
1213 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
1214 // An extract of a live-in is an extract of a broadcast, so return the
1215 // broadcasted element.
1216 case Instruction::ExtractElement:
1217 assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
1218 return Ops[0];
1219 }
1220 return nullptr;
1221 };
1222
1223 if (Value *V = FoldToIRValue())
1224 return Plan.getOrAddLiveIn(V);
1225 return nullptr;
1226}
1227
1229 VPlan &Plan, function_ref<VPValue *(VPValue *Op)> MatchPerm,
1232 vp_depth_first_deep(Plan.getEntry()))) {
1233 for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
1234 auto *Def = dyn_cast<VPSingleDefRecipe>(&R);
1235 if (!Def || !isElementwise(Def))
1236 continue;
1237
1238 // At least one of the ops must be a permutation.
1239 if (none_of(Def->operands(), MatchPerm))
1240 continue;
1241
1242 // All operands must be a single-use permutation or a live in (splat).
1243 if (!all_of(Def->operands(), [&MatchPerm](VPValue *Op) {
1244 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1245 }))
1246 continue;
1247
1248 // Remove the inner permutations.
1249 for (unsigned I = 0, E = Def->getNumOperands(); I != E; ++I)
1250 if (VPValue *X = MatchPerm(Def->getOperand(I)))
1251 Def->setOperand(I, X);
1252
1253 VPSingleDefRecipe *Res = BuildPerm(Def);
1254 Res->insertAfter(Def);
1255 Def->replaceUsesWithIf(
1256 Res, [&Res](VPUser &U, unsigned _) { return &U != Res; });
1257 }
1258 }
1259}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
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 * getPtrToAddrExpr(const SCEV *Op)
LLVM_ABI const SCEV * getSMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI bool canReuseInstruction(const SCEV *S, Instruction *I, SmallVectorImpl< Instruction * > &DropPoisonGeneratingInsts)
Check whether it is poison-safe to represent the expression S using the instruction I.
LLVM_ABI const SCEV * getGEPExpr(GEPOperator *GEP, ArrayRef< SCEVUse > IndexExprs)
Returns an expression for a GEP.
LLVM_ABI const SCEV * getUMinExpr(SCEVUse LHS, SCEVUse RHS, bool Sequential=false)
LLVM_ABI const SCEV * getTruncateOrSignExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
A vector that has set insertion semantics.
Definition SetVector.h:57
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:4400
iterator end()
Definition VPlan.h:4437
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4488
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:4466
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:387
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:4194
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:4026
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:4553
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:4625
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4701
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4789
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4745
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:3405
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:4255
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
VPValue * 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:4812
LLVMContext & getContext() const
Definition VPlan.h:5022
VPBasicBlock * getEntry()
Definition VPlan.h:4908
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5020
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:4974
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:5094
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5120
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1086
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5072
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4913
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:5017
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4964
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5013
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.
IteratorT end() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
CastOperator_match< OpTy, Instruction::PtrToAddr > m_PtrToAddr(const OpTy &Op)
Matches PtrToAddr.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_VScale()
Matches a call to llvm.vscale().
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
auto m_ZExtOrTruncOrSelf(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_commutative_match< Instruction::And, Op0_t, Op1_t > m_c_BinaryAnd(const Op0_t &Op0, const Op1_t &Op1)
Match a binary AND operation.
AllRecipe_match< Instruction::Or, Op0_t, Op1_t > m_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
Match a binary OR operation.
AllRecipe_match< Opcode, Op0_t, Op1_t > m_Binary(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_match< Opcode, Op0_t > m_Unary(const Op0_t &Op0)
auto m_GetElementPtr(const Op0_t &Op0, const Op1_t &Op1)
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExtractVectorForPart, Op0_t, Op1_t > m_ExtractVectorForPart(const Op0_t &Op0, const Op1_t &Op1)
VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
VPInstruction_match< VPInstruction::Broadcast, Op0_t > m_Broadcast(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
void pullOutPermutationsImpl(VPlan &Plan, function_ref< VPValue *(VPValue *Op)> Perm, function_ref< VPSingleDefRecipe *(VPSingleDefRecipe *X)> Build)
Template-independent implementation for pullOutPermutations.
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, 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...
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:577
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:326
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