LLVM 24.0.0git
VPlanVerifier.cpp
Go to the documentation of this file.
1//===-- VPlanVerifier.cpp -------------------------------------------------===//
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/// \file
10/// This file defines the class VPlanVerifier, which contains utility functions
11/// to check the consistency and invariants of a VPlan.
12///
13//===----------------------------------------------------------------------===//
14
15#include "VPlanVerifier.h"
16#include "VPlan.h"
17#include "VPlanCFG.h"
18#include "VPlanDominatorTree.h"
19#include "VPlanHelpers.h"
20#include "VPlanPatternMatch.h"
21#include "VPlanUtils.h"
23
24#define DEBUG_TYPE "loop-vectorize"
25
26using namespace llvm;
27using namespace VPlanPatternMatch;
28
29namespace {
30class VPlanVerifier {
31 const VPDominatorTree &VPDT;
32
34
35 // Verify that phi-like recipes are at the beginning of \p VPBB, with no
36 // other recipes in between. Also check that only header blocks contain
37 // VPHeaderPHIRecipes.
38 bool verifyPhiRecipes(const VPBasicBlock *VPBB);
39
40 /// Verify that \p LastActiveLane's operand is guaranteed to be a prefix-mask.
41 bool verifyLastActiveLaneRecipe(const VPInstruction &LastActiveLane) const;
42
43 bool verifyVPBasicBlock(const VPBasicBlock *VPBB);
44
45 bool verifyBlock(const VPBlockBase *VPB);
46
47 /// Helper function that verifies the CFG invariants of the VPBlockBases
48 /// within
49 /// \p Region. Checks in this function are generic for VPBlockBases. They are
50 /// not specific for VPBasicBlocks or VPRegionBlocks.
51 bool verifyBlocksInRegion(const VPRegionBlock *Region);
52
53 /// Verify the CFG invariants of VPRegionBlock \p Region and its nested
54 /// VPBlockBases. Do not recurse inside nested VPRegionBlocks.
55 bool verifyRegion(const VPRegionBlock *Region);
56
57 /// Verify the CFG invariants of VPRegionBlock \p Region and its nested
58 /// VPBlockBases. Recurse inside nested VPRegionBlocks.
59 bool verifyRegionRec(const VPRegionBlock *Region);
60
61public:
62 VPlanVerifier(VPDominatorTree &VPDT) : VPDT(VPDT) {}
63
64 bool verify(const VPlan &Plan);
65};
66} // namespace
67
68bool VPlanVerifier::verifyPhiRecipes(const VPBasicBlock *VPBB) {
69 auto RecipeI = VPBB->begin();
70 auto End = VPBB->end();
71 unsigned NumActiveLaneMaskPhiRecipes = 0;
72 bool IsHeaderVPBB = VPBlockUtils::isHeader(VPBB, VPDT);
73 while (RecipeI != End && RecipeI->isPhi()) {
75 NumActiveLaneMaskPhiRecipes++;
76
77 if (IsHeaderVPBB &&
79 errs() << "Found non-header PHI recipe in header VPBB";
80#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
81 errs() << ": ";
82 RecipeI->dump();
83#endif
84 return false;
85 }
86
87 if (!IsHeaderVPBB && isa<VPHeaderPHIRecipe>(*RecipeI)) {
88 errs() << "Found header PHI recipe in non-header VPBB";
89#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
90 errs() << ": ";
91 RecipeI->dump();
92#endif
93 return false;
94 }
95
96 // In region form, VPCurrentIterationPHIRecipe must be the first header phi
97 // recipe. In a plain CFG VPlan, it must either be the first or second.
100 ? RecipeI->getIterator() != VPBB->begin()
101 : RecipeI->getIterator() != VPBB->begin() &&
102 RecipeI->getIterator() != std::next(VPBB->begin()))) {
103 errs() << "CurrentIteration PHI is not the first/second recipe\n";
104 return false;
105 }
106
107 // Check if the recipe operands match the number of predecessors.
108 // TODO Extend to other phi-like recipes.
109 if (auto *PhiIRI = dyn_cast<VPIRPhi>(&*RecipeI)) {
110 if (PhiIRI->getNumOperands() != VPBB->getNumPredecessors()) {
111 errs() << "Phi-like recipe with different number of operands and "
112 "predecessors.\n";
113 // TODO: Print broken recipe. At the moment printing an ill-formed
114 // phi-like recipe may crash.
115 return false;
116 }
117 }
118
119 RecipeI++;
120 }
121
122 if (!VPBB->getPlan()->isUnrolled() && NumActiveLaneMaskPhiRecipes > 1) {
123 errs() << "There should be no more than one VPActiveLaneMaskPHIRecipe";
124 return false;
125 }
126
127 while (RecipeI != End) {
128 if (RecipeI->isPhi() && !isa<VPBlendRecipe>(&*RecipeI)) {
129 errs() << "Found phi-like recipe after non-phi recipe";
130
131#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
132 errs() << ": ";
133 RecipeI->dump();
134 errs() << "after\n";
135 std::prev(RecipeI)->dump();
136#endif
137 return false;
138 }
139 RecipeI++;
140 }
141 return true;
142}
143
144static bool isKnownMonotonic(VPValue *V) {
145 VPValue *X, *Y;
146 if (match(V, m_Add(m_VPValue(X), m_VPValue(Y))))
147 return cast<VPRecipeWithIRFlags>(V)->hasNoUnsignedWrap() &&
149 if (match(V, m_StepVector()))
150 return true;
151 // Only handle a subset of IVs until we can guarantee there's no overflow.
152 if (auto *WidenIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(V))
153 return WidenIV->isCanonical() || WidenIV->hasNoUnsignedWrap();
154 if (auto *Steps = dyn_cast<VPScalarIVStepsRecipe>(V))
155 return match(Steps->getOperand(0),
159 match(Steps->getStepValue(), m_One());
161 return true;
163}
164
165bool VPlanVerifier::verifyLastActiveLaneRecipe(
166 const VPInstruction &LastActiveLane) const {
167 assert(LastActiveLane.getOpcode() == VPInstruction::LastActiveLane &&
168 "must be called with VPInstruction::LastActiveLane");
169
170 if (LastActiveLane.getNumOperands() < 1) {
171 errs() << "LastActiveLane must have at least one operand\n";
172 return false;
173 }
174
175 // All operands must be prefix-mask. This means an icmp ult/ule LHS, RHS where
176 // the LHS is monotonically increasing and RHS is uniform across VFs and UF.
177 for (VPValue *Op : LastActiveLane.operands()) {
178 VPValue *Mask = Op;
179 VPValue *HeaderMask;
180
181 // Look through any `and`s with the incoming alias mask or a
182 // loop_dependence_war_mask, which are always prefix masks.
183 // TODO: Verify the full loop.dependence.mask chain.
184 if (match(Op,
186 m_VPValue(HeaderMask),
190 m_VPValue()),
193 Mask = HeaderMask;
194
195 // The header mask is a prefix mask. Before being materialized it is the
196 // loop region's abstract header mask; afterwards it is an active lane mask
197 // (an intrinsic or a phi), or the icmp checked below.
198 if (match(Mask, m_HeaderMask()) || isa<VPActiveLaneMaskPHIRecipe>(Mask) ||
200 continue;
201
202 CmpPredicate Pred;
203 VPValue *LHS, *RHS;
204 if (match(Mask, m_ICmp(Pred, m_VPValue(LHS), m_VPValue(RHS))) &&
205 (Pred == CmpInst::ICMP_ULE || Pred == CmpInst::ICMP_ULT) &&
208 match(RHS, m_EVL(m_VPValue()))))
209 continue;
210
211 errs() << "LastActiveLane operand ";
212#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
213 VPSlotTracker Tracker(LastActiveLane.getParent()->getPlan());
214 Op->printAsOperand(errs(), Tracker);
215#endif
216 errs() << " must be prefix mask (a header mask or an "
217 "EVL-derived mask currently)\n";
218 return false;
219 }
220
221 return true;
222}
223
224bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
225 if (!verifyPhiRecipes(VPBB))
226 return false;
227
228 // Verify that defs in VPBB dominate all their uses.
229 DenseMap<const VPRecipeBase *, unsigned> RecipeNumbering;
230 unsigned Cnt = 0;
231 for (const VPRecipeBase &R : *VPBB)
232 RecipeNumbering[&R] = Cnt++;
233
234 for (const VPRecipeBase &R : *VPBB) {
235 if (isa<VPIRInstruction>(&R) && !isa<VPIRBasicBlock>(VPBB)) {
236 errs() << "VPIRInstructions ";
237#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
238 R.dump();
239 errs() << " ";
240#endif
241 errs() << "not in a VPIRBasicBlock!\n";
242 return false;
243 }
244 for (const VPValue *V : R.definedValues()) {
245 // Verify that each defined value has a scalar type.
246 if (!V->getScalarType()) {
247 errs() << "VPValue without scalar type!\n";
248 return false;
249 }
250
251 // MaskedCond may be used from blocks it don't dominate; the block will be
252 // linearized and it will dominate its users after linearization.
254 continue;
255
256 for (const VPUser *U : V->users()) {
257 auto *UI = cast<VPRecipeBase>(U);
258 if (isa<VPIRPhi>(UI) &&
259 UI->getNumOperands() != UI->getParent()->getNumPredecessors()) {
260 errs() << "Phi-like recipe with different number of operands and "
261 "predecessors.\n";
262 return false;
263 }
264
265 if (auto *Phi = dyn_cast<VPPhiAccessors>(UI)) {
266 for (const auto &[IncomingVPV, IncomingVPBB] :
267 Phi->incoming_values_and_blocks()) {
268 if (IncomingVPV != V)
269 continue;
270
271 if (VPDT.dominates(VPBB, IncomingVPBB))
272 continue;
273
274 errs() << "Incoming def does not dominate incoming block!\n";
275#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
276 VPSlotTracker Tracker(VPBB->getPlan());
277 IncomingVPV->getDefiningRecipe()->print(errs(), " ", Tracker);
278 errs() << "\n does not dominate " << IncomingVPBB->getName()
279 << " for\n";
280 UI->print(errs(), " ", Tracker);
281#endif
282 return false;
283 }
284 continue;
285 }
286 // TODO: Also verify VPPredInstPHIRecipe.
288 continue;
289
290 // If the user is in the same block, check it comes after R in the
291 // block.
292 if (UI->getParent() == VPBB) {
293 if (RecipeNumbering[UI] >= RecipeNumbering[&R])
294 continue;
295 } else {
296 if (VPDT.dominates(VPBB, UI->getParent()))
297 continue;
298 }
299
300 // Recipes in blocks with a MaskedCond may be used in exit blocks; the
301 // block will be linearized and its recipes will dominate their users
302 // after linearization.
303 bool BlockHasMaskedCond = any_of(*VPBB, [](const VPRecipeBase &R) {
305 });
306 if (BlockHasMaskedCond &&
307 any_of(VPBB->getPlan()->getExitBlocks(), [UI](VPIRBasicBlock *EB) {
308 return is_contained(EB->getPredecessors(), UI->getParent());
309 })) {
310 continue;
311 }
312
313 errs() << "Use before def!\n";
314#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
315 VPSlotTracker Tracker(VPBB->getPlan());
316 UI->print(errs(), " ", Tracker);
317 errs() << "\n before\n";
318 R.print(errs(), " ", Tracker);
319 errs() << "\n";
320#endif
321 return false;
322 }
323 }
324 if (const auto *VPI = dyn_cast<VPInstruction>(&R)) {
325 switch (VPI->getOpcode()) {
327 if (!verifyLastActiveLaneRecipe(*VPI))
328 return false;
329 break;
330 default:
331 break;
332 }
333 }
334 if (const auto *DIV = dyn_cast<VPDerivedIVRecipe>(&R)) {
335 if (!DIV->getStartValue()->isDefinedOutsideLoopRegions()) {
336 errs() << "VPDerivedIVRecipe must have start value defined outside "
337 "loop regions\n";
338 return false;
339 }
340 }
341 if (const auto *ScalarIVSteps = dyn_cast<VPScalarIVStepsRecipe>(&R)) {
342 unsigned NumOps = ScalarIVSteps->getNumOperands();
343 if (NumOps != 3 && NumOps != 4) {
344 errs() << "VPScalarIVStepsRecipe must have 3 or 4 operands\n";
345 return false;
346 }
347 }
348 }
349
350 auto *IRBB = dyn_cast<VPIRBasicBlock>(VPBB);
351 if (!IRBB)
352 return true;
353
354 if (!WrappedIRBBs.insert(IRBB->getIRBasicBlock()).second) {
355 errs() << "Same IR basic block used by multiple wrapper blocks!\n";
356 return false;
357 }
358
359 return true;
360}
361
362bool VPlanVerifier::verifyBlock(const VPBlockBase *VPB) {
363 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
364 // Check block's condition bit.
365 if (VPBB && !isa<VPIRBasicBlock>(VPB)) {
366 // For plain CFG VPlans, verify header and latch block structure.
367 if (!VPBB->getParent()) {
368 if (VPBlockUtils::isHeader(VPBB, VPDT)) {
369 if (VPB->getNumPredecessors() != 2) {
370 errs()
371 << "Header block in plain CFG VPlan must have 2 predecessors!\n";
372 return false;
373 }
374 // Predecessor 0 is preheader, predecessor 1 is latch.
375 if (!VPBlockUtils::isLatch(VPB->getPredecessors()[1], VPDT)) {
376 errs() << "Header's second predecessor must be the latch!\n";
377 return false;
378 }
379 }
380
381 if (VPBlockUtils::isLatch(VPBB, VPDT)) {
382 if (!match(VPBB->getTerminator(), m_Branch())) {
383 errs() << "Latch block must have a branch terminator!\n";
384 return false;
385 }
386 // Successor 0 is middle block, successor 1 is header.
387 if (VPBlockUtils::isHeader(VPB->getSuccessors()[0], VPDT)) {
388 errs() << "Latch's first successor must not be the header (must be "
389 "middle block)!\n";
390 return false;
391 }
392 }
393 } else if (VPB->getNumSuccessors() > 1 ||
394 (VPBB->isExiting() && !VPBB->getParent()->isReplicator())) {
395 if (!VPBB->getTerminator()) {
396 errs() << "Block has multiple successors but doesn't "
397 "have a proper branch recipe!\n";
398 return false;
399 }
400 } else if (VPBB->getTerminator()) {
401 errs() << "Unexpected branch recipe!\n";
402 return false;
403 }
404 }
405
406 // Check block's successors.
407 const auto &Successors = VPB->getSuccessors();
408 for (const VPBlockBase *Succ : Successors) {
409 // There must be a bi-directional link between block and successor.
410 const auto &SuccPreds = Succ->getPredecessors();
411 if (!is_contained(SuccPreds, VPB)) {
412 errs() << "Missing predecessor link.\n";
413 return false;
414 }
415 }
416
417 // Check block's predecessors.
418 const auto &Predecessors = VPB->getPredecessors();
419
420 for (const VPBlockBase *Pred : Predecessors) {
421 // Block and predecessor must be inside the same region.
422 if (Pred->getParent() != VPB->getParent()) {
423 errs() << "Predecessor is not in the same region.\n";
424 return false;
425 }
426
427 // There must be a bi-directional link between block and predecessor.
428 const auto &PredSuccs = Pred->getSuccessors();
429 if (!is_contained(PredSuccs, VPB)) {
430 errs() << "Missing successor link.\n";
431 return false;
432 }
433 }
434 return !VPBB || verifyVPBasicBlock(VPBB);
435}
436
437bool VPlanVerifier::verifyBlocksInRegion(const VPRegionBlock *Region) {
438 for (const VPBlockBase *VPB : vp_depth_first_shallow(Region->getEntry())) {
439 // Check block's parent.
440 if (VPB->getParent() != Region) {
441 errs() << "VPBlockBase has wrong parent\n";
442 return false;
443 }
444
445 if (!verifyBlock(VPB))
446 return false;
447 }
448 return true;
449}
450
451bool VPlanVerifier::verifyRegion(const VPRegionBlock *Region) {
452 const VPBlockBase *Entry = Region->getEntry();
453 const VPBlockBase *Exiting = Region->getExiting();
454
455 // Entry and Exiting shouldn't have any predecessor/successor, respectively.
456 if (Entry->hasPredecessors()) {
457 errs() << "region entry block has predecessors\n";
458 return false;
459 }
460 if (Exiting->getNumSuccessors() != 0) {
461 errs() << "region exiting block has successors\n";
462 return false;
463 }
464
465 return verifyBlocksInRegion(Region);
466}
467
468bool VPlanVerifier::verifyRegionRec(const VPRegionBlock *Region) {
469 // Recurse inside nested regions and check all blocks inside the region.
470 return verifyRegion(Region) &&
472 [this](const VPBlockBase *VPB) {
473 const auto *SubRegion = dyn_cast<VPRegionBlock>(VPB);
474 return !SubRegion || verifyRegionRec(SubRegion);
475 });
476}
477
478bool VPlanVerifier::verify(const VPlan &Plan) {
480 [this](const VPBlockBase *VPB) { return !verifyBlock(VPB); }))
481 return false;
482
483 // Check that the plan has a single loop region reachable from entry, and it
484 // matches the one returned by getVectorLoopRegion.
485 const VPRegionBlock *TopRegion = Plan.getVectorLoopRegion();
488 [TopRegion](const VPRegionBlock *R) {
489 return !R->isReplicator() && R != TopRegion;
490 })) {
491 errs() << "VPlan must have a single top-level loop region, reachable from "
492 "the entry by following the last successor of each block\n";
493 return false;
494 }
495
496 // TODO: Verify all blocks using vp_depth_first_deep iterators.
497 if (!TopRegion)
498 return true;
499
500 if (!verifyRegionRec(TopRegion))
501 return false;
502
503 if (TopRegion->getParent()) {
504 errs() << "VPlan Top Region should have no parent.\n";
505 return false;
506 }
507
508 const VPBasicBlock *Entry = dyn_cast<VPBasicBlock>(TopRegion->getEntry());
509 if (!Entry) {
510 errs() << "VPlan entry block is not a VPBasicBlock\n";
511 return false;
512 }
513
514 const VPBasicBlock *Exiting = dyn_cast<VPBasicBlock>(TopRegion->getExiting());
515 if (!Exiting) {
516 errs() << "VPlan exiting block is not a VPBasicBlock\n";
517 return false;
518 }
519
520 if (Exiting->empty()) {
521 errs() << "VPlan vector loop exiting block must end with BranchOnCount, "
522 "BranchOnCond, or BranchOnTwoConds VPInstruction but is empty\n";
523 return false;
524 }
525
526 auto *LastInst = dyn_cast<VPInstruction>(std::prev(Exiting->end()));
527 if (!match(LastInst, m_Branch())) {
528 errs() << "VPlan vector loop exit must end with BranchOnCount, "
529 "BranchOnCond, or BranchOnTwoConds VPInstruction\n";
530 return false;
531 }
532
533 return true;
534}
535
537 // The entry must be the root of the plan's top-level CFG: the dominator tree
538 // constructed below and the verifier's block walks all start there.
539 if (Plan.getEntry()->hasPredecessors()) {
540 errs() << "VPlan entry block has predecessors\n";
541 return false;
542 }
543
544 VPDominatorTree VPDT(const_cast<VPlan &>(Plan));
545 VPlanVerifier Verifier(VPDT);
546 return Verifier.verify(Plan);
547}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
ppc ctr loops verify
verify safepoint Safepoint IR Verifier
This file defines the SmallPtrSet class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
This file contains the declarations of different VPlan-related auxiliary helpers.
static bool isKnownMonotonic(VPValue *V)
This file declares the class VPlanVerifier, which contains utility functions to check the consistency...
This file contains the declarations of the Vectorization Plan base classes:
Value * RHS
Value * LHS
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
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.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4389
iterator end()
Definition VPlan.h:4426
iterator begin()
Recipe iterator methods.
Definition VPlan.h:4424
bool empty() const
Definition VPlan.h:4435
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:94
VPRegionBlock * getParent()
Definition VPlan.h:192
size_t getNumSuccessors() const
Definition VPlan.h:243
bool hasPredecessors() const
Returns true if this block has any predecessors.
Definition VPlan.h:223
size_t getNumPredecessors() const
Definition VPlan.h:244
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:228
VPlan * getPlan()
Definition VPlan.cpp:211
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:217
static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
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:384
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1234
unsigned getOpcode() const
Definition VPlan.h:1429
VPBasicBlock * getParent()
Definition VPlan.h:483
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4614
const VPBlockBase * getEntry() const
Definition VPlan.h:4658
const VPBlockBase * getExiting() const
Definition VPlan.h:4670
operand_range operands()
Definition VPlanValue.h:474
unsigned getNumOperands() const
Definition VPlanValue.h:441
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4801
VPBasicBlock * getEntry()
Definition VPlan.h:4897
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
Definition VPlan.h:5067
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1080
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Entry
Definition COFF.h:862
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
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)
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
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.
VPInstruction_match< VPInstruction::StepVector > m_StepVector()
canonical_iv_match m_CanonicalIV()
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
header_mask_match m_HeaderMask()
VPInstruction_match< VPInstruction::ExplicitVectorLength, Op0_t > m_EVL(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
auto m_DerivedIV(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
bool isUniformAcrossVFsAndUFs(const VPValue *V)
Checks if V is uniform across all VF lanes and UF parts.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< df_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_depth_first_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order.
Definition VPlanCFG.h:250
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
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
LLVM_ABI_FOR_TEST bool verifyVPlanIsValid(const VPlan &Plan)
Verify invariants for general VPlans.