LLVM 24.0.0git
SLPUtils.cpp
Go to the documentation of this file.
1//===- SLPUtils.cpp - SLP Vectorizer free utility helpers -----------------===//
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 "SLPUtils.h"
10#include "SLPMemoryUtils.h"
11
12#include "llvm/ADT/APInt.h"
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/Sequence.h"
21#include "llvm/IR/Constants.h"
22#include "llvm/IR/DataLayout.h"
23#include "llvm/IR/DebugInfo.h"
24#include "llvm/IR/DebugLoc.h"
26#include "llvm/IR/IRBuilder.h"
35
36#include <algorithm>
37#include <numeric>
38#include <optional>
39#include <string>
40#include <type_traits>
41
42using namespace llvm;
43using namespace llvm::PatternMatch;
44
45namespace llvm::slpvectorizer {
46
50
51bool isBinOpIdentityConstant(const Value *V, unsigned Opcode) {
52 const auto *CI = dyn_cast<ConstantInt>(V);
53 return CI && ConstantExpr::getBinOpIdentity(Opcode, CI->getType()) == CI;
54}
55
57 const BinaryOperator *BO;
58 return match(V, m_BinOp(BO)) && BO->getType()->isIntOrIntVectorTy() &&
59 !BO->isShift() && !BO->isIntDivRem();
60}
61
64 return nullptr;
65 for (const Value *Op : cast<BinaryOperator>(V)->operands())
66 if (const auto *LI = dyn_cast<LoadInst>(Op))
67 return LI;
68 return nullptr;
69}
70
71unsigned getReassocCombineOpcode(unsigned Opcode) {
72 switch (Opcode) {
73 case Instruction::Sub:
74 return Instruction::Add;
75 case Instruction::FSub:
76 return Instruction::FAdd;
77 default:
78 return Opcode;
79 }
80}
81
83 if (I->getOpcode() == Instruction::Sub)
84 return true;
85 if (I->getOpcode() == Instruction::FSub)
86 return I->hasAllowReassoc();
87 return I->isAssociative();
88}
89
91 auto *I = dyn_cast<Instruction>(V);
92 // Non-instructions are vector-like only if they are undef.
93 if (!I)
94 return isa<UndefValue>(V);
95 switch (I->getOpcode()) {
96 case Instruction::ExtractValue:
97 case Instruction::InsertValue:
98 return true;
99 case Instruction::ExtractElement:
100 return isa<FixedVectorType>(I->getOperand(0)->getType()) &&
101 isConstant(I->getOperand(1));
102 case Instruction::InsertElement:
103 return isa<FixedVectorType>(I->getOperand(0)->getType()) &&
104 isConstant(I->getOperand(2));
105 default:
106 return false;
107 }
108}
109
110unsigned getNumElements(Type *Ty) {
112 "ScalableVectorType is not supported.");
113 if (isVectorizedTy(Ty))
115 return 1;
116}
117
118unsigned getPartNumElems(unsigned Size, unsigned NumParts) {
119 return std::min<unsigned>(Size, bit_ceil(divideCeil(Size, NumParts)));
120}
121
122unsigned getNumElems(unsigned Size, unsigned PartNumElems, unsigned Part) {
123 return std::min<unsigned>(PartNumElems, Size - Part * PartNumElems);
124}
125
126#if !defined(NDEBUG)
127std::string shortBundleName(ArrayRef<Value *> VL, int Idx) {
128 std::string Result;
129 raw_string_ostream OS(Result);
130 if (Idx >= 0)
131 OS << "Idx: " << Idx << ", ";
132 OS << "n=" << VL.size() << " [" << *VL.front() << ", ..]";
133 return Result;
134}
135#endif
136
138 auto *It = find_if(VL, IsaPred<Instruction>);
139 if (It == VL.end())
140 return false;
143 return true;
144
145 BasicBlock *BB = I0->getParent();
146 for (Value *V : make_filter_range(iterator_range(It, VL.end()), [](Value *V) {
147 return !isa<PoisonValue>(V);
148 })) {
149 auto *II = dyn_cast<Instruction>(V);
150 if (!II)
151 return false;
152
153 if (BB != II->getParent())
154 return false;
155 }
156 return true;
157}
158
160 // Constant expressions and globals can't be vectorized like normal integer/FP
161 // constants.
162 return all_of(VL, isConstant);
163}
164
166 Value *FirstNonUndef = nullptr;
167 for (Value *V :
168 make_filter_range(VL, [](Value *V) { return !isa<UndefValue>(V); })) {
169 if (!FirstNonUndef) {
170 FirstNonUndef = V;
171 continue;
172 }
173 if (V != FirstNonUndef)
174 return false;
175 }
176 return FirstNonUndef != nullptr;
177}
178
180 if (LHS == RHS)
181 return RHS;
182 if ((LHS == Intrinsic::fma || LHS == Intrinsic::fmuladd) &&
183 (RHS == Intrinsic::fma || RHS == Intrinsic::fmuladd))
184 return Intrinsic::fma;
186}
187
188bool isCommutative(const Instruction *I, const Value *ValWithUses,
189 bool IsCopyable) {
190 // The trunc X to i1 lanes of a compare have the single operand X.
191 if (auto *Cmp = dyn_cast<CmpInst>(I))
192 return isa<CmpInst>(ValWithUses) && Cmp->isCommutative();
193 if (auto *BO = dyn_cast<BinaryOperator>(I))
194 return BO->isCommutative() ||
195 (BO->getOpcode() == Instruction::Sub && ValWithUses->hasUseList() &&
196 !ValWithUses->hasNUsesOrMore(UsesLimit) &&
197 all_of(
198 ValWithUses->uses(),
199 [&](const Use &U) {
200 // Commutative, if icmp eq/ne sub, 0
201 CmpPredicate Pred;
202 if (match(U.getUser(),
203 m_ICmp(Pred, m_Specific(U.get()), m_Zero())) &&
204 (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE))
205 return true;
206 // Commutative, if abs(sub nsw, true) or abs(sub, false).
207 ConstantInt *Flag;
208 auto *I = dyn_cast<BinaryOperator>(U.get());
209 return match(U.getUser(),
210 m_Intrinsic<Intrinsic::abs>(
211 m_Specific(U.get()), m_ConstantInt(Flag))) &&
212 ((!IsCopyable && I && !I->hasNoSignedWrap()) ||
213 Flag->isOne());
214 })) ||
215 (BO->getOpcode() == Instruction::FSub && ValWithUses->hasUseList() &&
216 !ValWithUses->hasNUsesOrMore(UsesLimit) &&
217 all_of(ValWithUses->uses(), [](const Use &U) {
218 return match(U.getUser(),
219 m_Intrinsic<Intrinsic::fabs>(m_Specific(U.get())));
220 }));
221 return I->isCommutative();
222}
223
224bool isCommutative(const Instruction *I) { return isCommutative(I, I); }
225
226bool isCommutableOperand(const Instruction *I, Value *ValWithUses, unsigned Op,
227 bool IsCopyable) {
228 assert(isCommutative(I, ValWithUses, IsCopyable) &&
229 "The instruction is not commutative.");
230 if (isa<CmpInst>(I))
231 return true;
232 if (auto *BO = dyn_cast<BinaryOperator>(I)) {
233 switch (BO->getOpcode()) {
234 case Instruction::Sub:
235 case Instruction::FSub:
236 return true;
237 default:
238 break;
239 }
240 }
241 return I->isCommutableOperand(Op);
242}
243
246 // IntrinsicInst::isCommutative returns true if swapping the first "two"
247 // arguments to the intrinsic produces the same result.
248 constexpr unsigned IntrinsicNumOperands = 2;
249 return IntrinsicNumOperands;
250 }
251 return I->getNumOperands();
252}
253
254std::optional<unsigned> getElementIndex(const Value *Inst, unsigned Offset) {
255 if (auto Index = getInsertExtractIndex<InsertElementInst>(Inst, Offset))
256 return Index;
258 return Index;
259
260 unsigned Index = Offset;
261
262 const auto *IV = dyn_cast<InsertValueInst>(Inst);
263 if (!IV)
264 return std::nullopt;
265
266 Type *CurrentType = IV->getType();
267 for (unsigned I : IV->indices()) {
268 if (const auto *ST = dyn_cast<StructType>(CurrentType)) {
269 Index *= ST->getNumElements();
270 CurrentType = ST->getElementType(I);
271 } else if (const auto *AT = dyn_cast<ArrayType>(CurrentType)) {
272 Index *= AT->getNumElements();
273 CurrentType = AT->getElementType();
274 } else {
275 return std::nullopt;
276 }
277 Index += I;
278 }
279 return Index;
280}
281
283 auto *It = find_if(VL, IsaPred<Instruction>);
284 if (It == VL.end())
285 return true;
286 Instruction *MainOp = cast<Instruction>(*It);
287 unsigned Opcode = MainOp->getOpcode();
288 bool IsCmpOp = isa<CmpInst>(MainOp);
289 CmpInst::Predicate BasePred = IsCmpOp ? cast<CmpInst>(MainOp)->getPredicate()
291 return all_of(make_range(It, VL.end()), [&](Value *V) {
292 if (auto *CI = dyn_cast<CmpInst>(V))
293 return BasePred == CI->getPredicate();
294 if (auto *I = dyn_cast<Instruction>(V))
295 return I->getOpcode() == Opcode;
296 return isa<PoisonValue>(V);
297 });
298}
299
300std::optional<unsigned> getExtractIndex(const Instruction *E) {
301 unsigned Opcode = E->getOpcode();
302 assert((Opcode == Instruction::ExtractElement ||
303 Opcode == Instruction::ExtractValue) &&
304 "Expected extractelement or extractvalue instruction.");
305 if (Opcode == Instruction::ExtractElement) {
306 auto *CI = dyn_cast<ConstantInt>(E->getOperand(1));
307 if (!CI)
308 return std::nullopt;
309 // Check if the index is out of bound. We can get the source vector from
310 // operand 0.
311 unsigned Idx = CI->getZExtValue();
312 auto *EE = cast<ExtractElementInst>(E);
313 const unsigned VF = getNumElements(EE->getVectorOperandType());
314 if (Idx >= VF)
315 return std::nullopt;
316 return Idx;
317 }
318 auto *EI = cast<ExtractValueInst>(E);
319 if (EI->getNumIndices() != 1)
320 return std::nullopt;
321 return *EI->idx_begin();
322}
323
325 SmallVectorImpl<int> &Mask) {
326 Mask.clear();
327 const unsigned E = Indices.size();
328 Mask.resize(E, PoisonMaskElem);
329 for (unsigned I = 0; I < E; ++I)
330 Mask[Indices[I]] = I;
331}
332
334 assert(!Mask.empty() && "Expected non-empty mask.");
335 SmallVector<Value *> Prev(Scalars.size(),
336 PoisonValue::get(Scalars.front()->getType()));
337 Prev.swap(Scalars);
338 for (unsigned I = 0, E = Prev.size(); I < E; ++I)
339 if (Mask[I] != PoisonMaskElem)
340 Scalars[Mask[I]] = Prev[I];
341}
342
344 assert(!Mask.empty() && Reuses.size() == Mask.size() &&
345 "Expected non-empty mask.");
346 SmallVector<int> Prev(Reuses.begin(), Reuses.end());
347 Prev.swap(Reuses);
348 for (unsigned I = 0, E = Prev.size(); I < E; ++I)
349 if (Mask[I] != PoisonMaskElem)
350 Reuses[Mask[I]] = Prev[I];
351}
352
354 bool BottomOrder) {
355 assert(!Mask.empty() && "Expected non-empty mask.");
356 unsigned Sz = Mask.size();
357 if (BottomOrder) {
358 SmallVector<unsigned> PrevOrder;
359 if (Order.empty()) {
360 PrevOrder.resize(Sz);
361 std::iota(PrevOrder.begin(), PrevOrder.end(), 0);
362 } else {
363 PrevOrder.swap(Order);
364 }
365 Order.assign(Sz, Sz);
366 for (unsigned I = 0; I < Sz; ++I)
367 if (Mask[I] != PoisonMaskElem)
368 Order[I] = PrevOrder[Mask[I]];
369 if (all_of(enumerate(Order), [&](const auto &Data) {
370 return Data.value() == Sz || Data.index() == Data.value();
371 })) {
372 Order.clear();
373 return;
374 }
376 return;
377 }
378 SmallVector<int> MaskOrder;
379 if (Order.empty()) {
380 MaskOrder.resize(Sz);
381 std::iota(MaskOrder.begin(), MaskOrder.end(), 0);
382 } else {
383 inversePermutation(Order, MaskOrder);
384 }
385 reorderReuses(MaskOrder, Mask);
386 if (ShuffleVectorInst::isIdentityMask(MaskOrder, Sz)) {
387 Order.clear();
388 return;
389 }
390 Order.assign(Sz, Sz);
391 for (unsigned I = 0; I < Sz; ++I)
392 if (MaskOrder[I] != PoisonMaskElem)
393 Order[MaskOrder[I]] = I;
395}
396
398 assert(!Order.empty() &&
399 "Order is empty. Please check it before using isReverseOrder.");
400 unsigned Sz = Order.size();
401 return all_of(enumerate(Order), [&](const auto &Pair) {
402 return Pair.value() == Sz || Sz - Pair.index() - 1 == Pair.value();
403 });
404}
405
407 ArrayRef<int> FirstCluster = Mask.slice(0, Sz);
408 if (ShuffleVectorInst::isIdentityMask(FirstCluster, Sz))
409 return false;
410 for (unsigned I = Sz, E = Mask.size(); I < E; I += Sz) {
411 ArrayRef<int> Cluster = Mask.slice(I, Sz);
412 if (Cluster != FirstCluster)
413 return false;
414 }
415 return true;
416}
417
419 ArrayRef<unsigned> SecondaryOrder) {
420 assert((SecondaryOrder.empty() || Order.size() == SecondaryOrder.size()) &&
421 "Expected same size of orders");
422 size_t Sz = Order.size();
423 SmallBitVector UsedIndices(Sz);
424 for (unsigned Idx : seq<unsigned>(0, Sz)) {
425 if (Order[Idx] != Sz)
426 UsedIndices.set(Order[Idx]);
427 }
428 if (SecondaryOrder.empty()) {
429 for (unsigned Idx : seq<unsigned>(0, Sz))
430 if (Order[Idx] == Sz && !UsedIndices.test(Idx))
431 Order[Idx] = Idx;
432 } else {
433 for (unsigned Idx : seq<unsigned>(0, Sz))
434 if (SecondaryOrder[Idx] != Sz && Order[Idx] == Sz &&
435 !UsedIndices.test(SecondaryOrder[Idx]))
436 Order[Idx] = SecondaryOrder[Idx];
437 }
438}
439
441 assert(!VL.empty() && "Expected non-empty list of values.");
442 Type *Ty = VL.consume_front()->getType();
443 return all_of(VL, [&](Value *V) { return V->getType() == Ty; });
444}
445
446template <typename T>
447std::optional<unsigned> getInsertExtractIndex(const Value *Inst,
448 unsigned Offset) {
449 static_assert(std::is_same_v<T, InsertElementInst> ||
450 std::is_same_v<T, ExtractElementInst>,
451 "unsupported T");
452 const auto *IE = dyn_cast<T>(Inst);
453 if (!IE)
454 return std::nullopt;
455 // InsertElement: result is the vector, index is op 2.
456 // ExtractElement: result is scalar, vector is op 0, index is op 1.
457 constexpr bool IsInsert = std::is_same_v<T, InsertElementInst>;
458 Type *VecTy = IsInsert ? IE->getType() : IE->getOperand(0)->getType();
459 const auto *VT = dyn_cast<FixedVectorType>(VecTy);
460 if (!VT)
461 return std::nullopt;
462 const auto *CI = dyn_cast<ConstantInt>(IE->getOperand(IsInsert ? 2 : 1));
463 if (!CI)
464 return std::nullopt;
465 if (CI->getValue().uge(VT->getNumElements()))
466 return std::nullopt;
467 unsigned Index = Offset;
468 Index *= VT->getNumElements();
469 Index += CI->getZExtValue();
470 return Index;
471}
472
473// Only these two specializations are used; instantiate them here so the
474// definition can stay out of the header.
475template std::optional<unsigned>
477template std::optional<unsigned>
479
481 auto *I = dyn_cast<Instruction>(V);
482 if (!I)
483 return true;
484 return all_of(make_isa_range<Instruction>(I->operands()),
485 [I](Instruction *IO) {
486 return isa<PHINode>(IO) || IO->getParent() != I->getParent();
487 }) &&
489}
490
492 auto *I = dyn_cast<Instruction>(V);
493 if (!I)
494 return true;
495 // Limits the number of uses to save compile time.
496 return !I->hasNUsesOrMore(UsesLimit) && all_of(I->users(), [I](User *U) {
497 auto *IU = dyn_cast<Instruction>(U);
498 if (!IU)
499 return true;
500 return IU->getParent() != I->getParent() || isa<PHINode>(IU);
501 }) && !I->mayReadOrWriteMemory();
502}
503
507
512
513void transformScalarShuffleIndiciesToVector(unsigned VecTyNumElements,
514 SmallVectorImpl<int> &Mask) {
515 // The ShuffleBuilder implementation use shufflevector to splat an "element".
516 // But the element have different meaning for SLP (scalar) and REVEC
517 // (vector). We need to expand Mask into masks which shufflevector can use
518 // directly.
519 SmallVector<int> NewMask(Mask.size() * VecTyNumElements);
520 for (unsigned I : seq<unsigned>(Mask.size()))
521 for (auto [J, MaskV] : enumerate(MutableArrayRef(NewMask).slice(
522 I * VecTyNumElements, VecTyNumElements)))
523 MaskV = Mask[I] == PoisonMaskElem ? PoisonMaskElem
524 : Mask[I] * VecTyNumElements + J;
525 Mask.swap(NewMask);
526}
527
529 if (VL.empty())
530 return 0;
532 return 0;
533 auto *SV = cast<ShuffleVectorInst>(VL.front());
534 unsigned SVNumElements =
535 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
536 unsigned ShuffleMaskSize = SV->getShuffleMask().size();
537 if (SVNumElements % ShuffleMaskSize != 0)
538 return 0;
539 unsigned GroupSize = SVNumElements / ShuffleMaskSize;
540 if (GroupSize == 0 || (VL.size() % GroupSize) != 0)
541 return 0;
542 unsigned NumGroup = 0;
543 for (size_t I = 0, E = VL.size(); I != E; I += GroupSize) {
544 auto *SV = cast<ShuffleVectorInst>(VL[I]);
545 Value *Src = SV->getOperand(0);
546 ArrayRef<Value *> Group = VL.slice(I, GroupSize);
547 SmallBitVector ExpectedIndex(GroupSize);
548 if (!all_of(Group, [&](Value *V) {
549 auto *SV = cast<ShuffleVectorInst>(V);
550 // From the same source.
551 if (SV->getOperand(0) != Src)
552 return false;
553 int Index;
554 if (!SV->isExtractSubvectorMask(Index))
555 return false;
556 ExpectedIndex.set(Index / ShuffleMaskSize);
557 return true;
558 }))
559 return 0;
560 if (!ExpectedIndex.all())
561 return 0;
562 ++NumGroup;
563 }
564 assert(NumGroup == (VL.size() / GroupSize) && "Unexpected number of groups");
565 return NumGroup;
566}
567
569 assert(getShufflevectorNumGroups(VL) && "Not supported shufflevector usage.");
570 auto *SV = cast<ShuffleVectorInst>(VL.front());
571 unsigned SVNumElements =
572 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
573 SmallVector<int> Mask;
574 unsigned AccumulateLength = 0;
575 for (Value *V : VL) {
576 auto *SV = cast<ShuffleVectorInst>(V);
577 for (int M : SV->getShuffleMask())
578 Mask.push_back(M == PoisonMaskElem ? PoisonMaskElem
579 : AccumulateLength + M);
580 AccumulateLength += SVNumElements;
581 }
582 return Mask;
583}
584
585/// Checks if the vector of instructions can be represented as a shuffle, like:
586/// %x0 = extractelement <4 x i8> %x, i32 0
587/// %x3 = extractelement <4 x i8> %x, i32 3
588/// %y1 = extractelement <4 x i8> %y, i32 1
589/// %y2 = extractelement <4 x i8> %y, i32 2
590/// %x0x0 = mul i8 %x0, %x0
591/// %x3x3 = mul i8 %x3, %x3
592/// %y1y1 = mul i8 %y1, %y1
593/// %y2y2 = mul i8 %y2, %y2
594/// %ins1 = insertelement <4 x i8> poison, i8 %x0x0, i32 0
595/// %ins2 = insertelement <4 x i8> %ins1, i8 %x3x3, i32 1
596/// %ins3 = insertelement <4 x i8> %ins2, i8 %y1y1, i32 2
597/// %ins4 = insertelement <4 x i8> %ins3, i8 %y2y2, i32 3
598/// ret <4 x i8> %ins4
599/// can be transformed into:
600/// %1 = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 3, i32 5,
601/// i32 6>
602/// %2 = mul <4 x i8> %1, %1
603/// ret <4 x i8> %2
604/// Mask will return the Shuffle Mask equivalent to the extracted elements.
605/// TODO: Can we split off and reuse the shuffle mask detection from
606/// ShuffleVectorInst/getShuffleCost?
607std::optional<TargetTransformInfo::ShuffleKind>
609 AssumptionCache *AC, SLPAnalysisCache &Cache) {
610 const auto *It = find_if(VL, IsaPred<ExtractElementInst>);
611 if (It == VL.end())
612 return std::nullopt;
613 unsigned Size = 0;
614 Value *Vec1 = nullptr;
615 Value *Vec2 = nullptr;
616 // The poison analysis is expensive, it is required only for the undef
617 // vectors.
618 std::optional<bool> HasNonUndefVec;
619 auto IsNonUndefVecPresent = [&]() {
620 if (!HasNonUndefVec)
621 HasNonUndefVec = any_of(make_isa_range<ExtractElementInst>(VL),
622 [&](ExtractElementInst *EE) {
623 Value *Vec = EE->getVectorOperand();
624 if (isa<UndefValue>(Vec))
625 return false;
626 return Cache.isGuaranteedNotToBePoison(Vec, AC);
627 });
628 return *HasNonUndefVec;
629 };
630 enum ShuffleMode { Unknown, Select, Permute };
631 ShuffleMode CommonShuffleMode = Unknown;
632 Mask.assign(VL.size(), PoisonMaskElem);
633 for (unsigned I = 0, E = VL.size(); I < E; ++I) {
634 // Undef, or a copyable lane modeled on an extract main op, can be
635 // represented as an undef element in a vector.
636 if (isa<UndefValue>(VL[I]))
637 continue;
638 auto *EI = dyn_cast<ExtractElementInst>(VL[I]);
639 if (!EI)
640 continue;
641 if (isa<ScalableVectorType>(EI->getVectorOperandType()))
642 return std::nullopt;
643 auto *Vec = EI->getVectorOperand();
644 // We can extractelement from undef or poison vector.
646 continue;
647 // All vector operands must have the same number of vector elements.
648 if (isa<UndefValue>(Vec)) {
649 Mask[I] = I;
650 } else {
651 if (isa<UndefValue>(EI->getIndexOperand()))
652 continue;
653 auto *Idx = dyn_cast<ConstantInt>(EI->getIndexOperand());
654 if (!Idx)
655 return std::nullopt;
656 // Undefined behavior if Idx is negative or out of bounds.
657 if (Idx->getValue().uge(getNumElements(Vec->getType())))
658 continue;
659 unsigned IntIdx = Idx->getValue().getZExtValue();
660 Mask[I] = IntIdx;
661 }
662 // The width is defined only by the lanes that are present in the mask.
663 Size = std::max(Size, getNumElements(Vec->getType()));
664 if (isUndefVector(Vec).all() && IsNonUndefVecPresent())
665 continue;
666 // For correct shuffling we have to have at most 2 different vector operands
667 // in all extractelement instructions.
668 if (!Vec1 || Vec1 == Vec) {
669 Vec1 = Vec;
670 } else if (!Vec2 || Vec2 == Vec) {
671 Vec2 = Vec;
672 } else {
673 return std::nullopt;
674 }
675 }
676 if (Vec2 && Size != std::max(getNumElements(Vec1->getType()),
677 getNumElements(Vec2->getType())))
678 return std::nullopt;
679 for (auto [I, Idx] : enumerate(Mask)) {
680 if (Idx == PoisonMaskElem)
681 continue;
682 auto *Vec = cast<ExtractElementInst>(VL[I])->getVectorOperand();
683 if (Vec == Vec2)
684 Idx += Size;
685 else if (Vec != Vec1)
686 continue;
687 if (CommonShuffleMode == Permute)
688 continue;
689 // If the extract index is not the same as the operation number, it is a
690 // permutation.
691 if (Idx % Size != I) {
692 CommonShuffleMode = Permute;
693 continue;
694 }
695 CommonShuffleMode = Select;
696 }
697 // If we're not crossing lanes in different vectors, consider it as blending.
698 if (CommonShuffleMode == Select && Vec2)
700 // If Vec2 was never used, we have a permutation of a single vector, otherwise
701 // we have permutation of 2 vectors.
704}
705
707 IRBuilderBase &Builder, Value *Vec, Value *V, unsigned Index,
708 function_ref<Value *(Value *, Value *, ArrayRef<int>)> Generator) {
709 if (isa<PoisonValue>(Vec) && isa<PoisonValue>(V))
710 return Vec;
711 const unsigned SubVecVF = getNumElements(V->getType());
712 // Create shuffle, insertvector requires that index is multiple of
713 // the subvector length.
714 const unsigned VecVF = getNumElements(Vec->getType());
715 SmallVector<int> Mask(VecVF, PoisonMaskElem);
716 if (isa<PoisonValue>(Vec)) {
717 auto *Begin = std::next(Mask.begin(), Index);
718 std::iota(Begin, std::next(Begin, SubVecVF), 0);
719 Vec = Builder.CreateShuffleVector(V, Mask);
720 return Vec;
721 }
722 std::iota(Mask.begin(), Mask.end(), 0);
723 std::iota(std::next(Mask.begin(), Index),
724 std::next(Mask.begin(), Index + SubVecVF), VecVF);
725 if (Generator)
726 return Generator(Vec, V, Mask);
727 // 1. Resize V to the size of Vec.
728 SmallVector<int> ResizeMask(VecVF, PoisonMaskElem);
729 std::iota(ResizeMask.begin(), std::next(ResizeMask.begin(), SubVecVF), 0);
730 V = Builder.CreateShuffleVector(V, ResizeMask);
731 // 2. Insert V into Vec.
732 return Builder.CreateShuffleVector(Vec, V, Mask);
733}
734
736 unsigned SubVecVF, unsigned Index) {
737 SmallVector<int> Mask(SubVecVF, PoisonMaskElem);
738 std::iota(Mask.begin(), Mask.end(), Index);
739 return Builder.CreateShuffleVector(Vec, Mask);
740}
741
743 SmallBitVector UseMask(VF, true);
744 for (auto [Idx, Value] : enumerate(Mask)) {
745 if (Value == PoisonMaskElem) {
746 if (MaskArg == UseMask::UndefsAsMask)
747 UseMask.reset(Idx);
748 continue;
749 }
750 if (MaskArg == UseMask::FirstArg && Value < VF)
751 UseMask.reset(Value);
752 else if (MaskArg == UseMask::SecondArg && Value >= VF)
753 UseMask.reset(Value - VF);
754 }
755 return UseMask;
756}
757
758template <bool IsPoisonOnly>
760 SmallBitVector Res(UseMask.empty() ? 1 : UseMask.size(), true);
761 using T = std::conditional_t<IsPoisonOnly, PoisonValue, UndefValue>;
762 if (isa<T>(V))
763 return Res;
764 auto *VecTy = dyn_cast<FixedVectorType>(V->getType());
765 if (!VecTy)
766 return Res.reset();
767 auto *C = dyn_cast<Constant>(V);
768 if (!C) {
769 if (!UseMask.empty()) {
770 const Value *Base = V;
771 while (auto *II = dyn_cast<InsertElementInst>(Base)) {
772 Base = II->getOperand(0);
773 if (isa<T>(II->getOperand(1)))
774 continue;
775 std::optional<unsigned> Idx = getElementIndex(II);
776 if (!Idx) {
777 Res.reset();
778 return Res;
779 }
780 if (*Idx < UseMask.size() && !UseMask.test(*Idx))
781 Res.reset(*Idx);
782 }
783 // TODO: Add analysis for shuffles here too.
784 if (V == Base) {
785 Res.reset();
786 } else {
787 SmallBitVector SubMask(UseMask.size(), false);
788 Res &= isUndefVector<IsPoisonOnly>(Base, SubMask);
789 }
790 } else {
791 Res.reset();
792 }
793 return Res;
794 }
795 for (unsigned I = 0, E = VecTy->getNumElements(); I != E; ++I) {
796 if (Constant *Elem = C->getAggregateElement(I))
797 if (!isa<T>(Elem) &&
798 (UseMask.empty() || (I < UseMask.size() && !UseMask.test(I))))
799 Res.reset(I);
800 }
801 return Res;
802}
803
805 const SmallBitVector &);
807 const SmallBitVector &);
808
811 const TargetTransformInfo *TTI) {
812 if (!UserInst)
813 return false;
814 unsigned Opcode = UserInst->getOpcode();
815 switch (Opcode) {
816 case Instruction::Load: {
817 LoadInst *LI = cast<LoadInst>(UserInst);
818 return (LI->getPointerOperand() == Scalar);
819 }
820 case Instruction::Store: {
821 StoreInst *SI = cast<StoreInst>(UserInst);
822 return (SI->getPointerOperand() == Scalar);
823 }
824 case Instruction::Call: {
825 CallInst *CI = cast<CallInst>(UserInst);
827 return any_of(enumerate(CI->args()), [&](auto &&Arg) {
828 return isVectorIntrinsicWithScalarOpAtArg(ID, Arg.index(), TTI) &&
829 Arg.value().get() == Scalar;
830 });
831 }
832 default:
833 return false;
834 }
835}
836
844
846 if (LoadInst *LI = dyn_cast<LoadInst>(I))
847 return LI->isSimple();
849 return SI->isSimple();
851 return !MI->isVolatile();
852 return true;
853}
854
855bool isSelectedBaseLoad(Type *ScalarTy, ArrayRef<Value *> PointerOps,
856 const DataLayout &DL, Value *&TrueBase,
857 Value *&FalseBase,
858 SmallVectorImpl<Value *> &Conditions) {
859 TrueBase = nullptr;
860 FalseBase = nullptr;
861 uint64_t ScalarSize = DL.getTypeStoreSize(ScalarTy);
862 Conditions.assign(PointerOps.size(), nullptr);
863 for (auto [Idx, P] : enumerate(PointerOps)) {
864 Value *Base = P;
865 uint64_t Offset = 0;
866 if (auto *GEP = dyn_cast<GetElementPtrInst>(P)) {
867 APInt OffsetAP(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
868 if (!GEP->accumulateConstantOffset(DL, OffsetAP) || OffsetAP.isNegative())
869 return false;
870 Offset = OffsetAP.getZExtValue();
871 Base = GEP->getPointerOperand();
872 }
873 auto *Sel = dyn_cast<SelectInst>(Base);
874 if (!Sel)
875 return false;
876 Value *T = Sel->getTrueValue();
877 Value *F = Sel->getFalseValue();
878 if (!TrueBase) {
879 if (T == F)
880 return false;
881 TrueBase = T;
882 FalseBase = F;
883 } else if (TrueBase != T || FalseBase != F) {
884 return false;
885 }
886 // Lane Idx must be at exactly Base + Idx * sizeof(ScalarTy); codegen reads
887 // contiguously from TrueBase/FalseBase starting at lane 0.
888 if (Offset != static_cast<uint64_t>(Idx) * ScalarSize)
889 return false;
890 Conditions[Idx] = Sel->getCondition();
891 }
892 return TrueBase != nullptr;
893}
894
896 const DataLayout &DL) {
898 "Expected only load lanes in a blended load.");
899 const uint64_t ScalarSize = DL.getTypeStoreSize(VL.front()->getType());
900 Align BaseAlignment = cast<LoadInst>(VL.front())->getAlign();
901 for (auto [Idx, V] : enumerate(VL))
902 BaseAlignment =
903 std::min(BaseAlignment, commonAlignment(cast<LoadInst>(V)->getAlign(),
904 Idx * ScalarSize));
905 return BaseAlignment;
906}
907
909 Value *Ptr = cast<LoadInst>(VL.front())->getPointerOperand();
910 if (auto *GEP = dyn_cast<GetElementPtrInst>(Ptr))
911 Ptr = GEP->getPointerOperand();
912 return cast<SelectInst>(Ptr);
913}
914
916 function_ref<bool(Value *)> IsGEPLane,
917 const DataLayout &DL) {
918 constexpr unsigned IndexIdx = 1;
919 Type *VL0Ty = VL0->getOperand(IndexIdx)->getType();
920 Type *PtrIdxTy =
921 DL.getIndexType(VL0->getOperand(0)->getType()->getScalarType());
922 bool AllSameTy = true;
923 bool HasNonConstIdx = false;
924 bool ConstsFitVL0Ty = true;
925 for (Value *V : make_filter_range(VL, IsGEPLane)) {
926 Value *Op = cast<GetElementPtrInst>(V)->getOperand(IndexIdx);
927 if (Op->getType() != VL0Ty)
928 AllSameTy = false;
929 auto *CI = dyn_cast<ConstantInt>(Op);
930 if (!CI) {
931 // Non-constant indices are not cast, they must have the main op type.
932 if (Op->getType() != VL0Ty)
933 return nullptr;
934 HasNonConstIdx = true;
935 continue;
936 }
937 if (!CI->getValue().isSignedIntN(VL0Ty->getIntegerBitWidth()))
938 ConstsFitVL0Ty = false;
939 }
940 if (AllSameTy)
941 return VL0Ty;
942 if (!HasNonConstIdx || VL0Ty == PtrIdxTy)
943 return PtrIdxTy;
944 return ConstsFitVL0Ty ? VL0Ty : nullptr;
945}
946
948 SmallPtrSet<Value *, 16> UniquePtrs(llvm::from_range, PointerOps);
949 if (UniquePtrs.size() != PointerOps.size())
950 return false;
951 auto IsConstantOffsetPtr = [](Value *P) {
953 return !GEP ||
954 (GEP->getNumOperands() == 2 && isConstant(GEP->getOperand(1)));
955 };
956 auto *RefIt = find_if_not(PointerOps, IsConstantOffsetPtr);
957 if (RefIt == PointerOps.end())
958 return false;
959 auto *RefGEP = dyn_cast<GetElementPtrInst>(*RefIt);
960 if (!RefGEP || RefGEP->getNumOperands() != 2)
961 return false;
962 Value *Base = RefGEP->getPointerOperand();
963 Type *PtrTy = RefGEP->getType();
964 Type *SrcElemTy = RefGEP->getSourceElementType();
965 // The stride and the (optional) cast opcode of the runtime indices.
966 Value *Stride = nullptr;
967 unsigned CastOpcode = 0;
968 for (Value *P : PointerOps) {
969 if (P->getType() != PtrTy)
970 return false;
971 if (P == Base)
972 continue;
974 if (!GEP || GEP->getNumOperands() != 2 ||
975 GEP->getPointerOperand() != Base ||
976 GEP->getSourceElementType() != SrcElemTy)
977 return false;
978 Value *Idx = GEP->getOperand(1);
979 if (isConstant(Idx))
980 continue;
981 unsigned LaneCastOpcode = 0;
982 if (auto *Cast = dyn_cast<CastInst>(Idx)) {
983 LaneCastOpcode = Cast->getOpcode();
984 Idx = Cast->getOperand(0);
985 }
986 Value *LaneStride = Idx;
987 if (auto *BO = dyn_cast<BinaryOperator>(Idx)) {
988 if (isa<Constant>(BO->getOperand(1)))
989 LaneStride = BO->getOperand(0);
990 else if (isa<Constant>(BO->getOperand(0)))
991 LaneStride = BO->getOperand(1);
992 }
993 if (!Stride) {
994 Stride = LaneStride;
995 CastOpcode = LaneCastOpcode;
996 continue;
997 }
998 if (LaneStride != Stride || LaneCastOpcode != CastOpcode)
999 return false;
1000 }
1001 return Stride != nullptr;
1002}
1003
1005 bool ExtendingManyInputs) {
1006 if (SubMask.empty())
1007 return;
1008 assert(
1009 (!ExtendingManyInputs || SubMask.size() > Mask.size() ||
1010 // Check if input scalars were extended to match the size of other node.
1011 (SubMask.size() == Mask.size() && Mask.back() == PoisonMaskElem)) &&
1012 "SubMask with many inputs support must be larger than the mask.");
1013 if (Mask.empty()) {
1014 Mask.append(SubMask.begin(), SubMask.end());
1015 return;
1016 }
1017 SmallVector<int> NewMask(SubMask.size(), PoisonMaskElem);
1018 int TermValue = std::min(Mask.size(), SubMask.size());
1019 for (int I = 0, E = SubMask.size(); I < E; ++I) {
1020 if (SubMask[I] == PoisonMaskElem ||
1021 (!ExtendingManyInputs &&
1022 (SubMask[I] >= TermValue || Mask[SubMask[I]] >= TermValue)))
1023 continue;
1024 NewMask[I] = Mask[SubMask[I]];
1025 }
1026 Mask.swap(NewMask);
1027}
1028
1030 const size_t Sz = Order.size();
1031 SmallBitVector UnusedIndices(Sz, /*t=*/true);
1032 SmallBitVector MaskedIndices(Sz);
1033 for (unsigned I = 0; I < Sz; ++I) {
1034 if (Order[I] < Sz)
1035 UnusedIndices.reset(Order[I]);
1036 else
1037 MaskedIndices.set(I);
1038 }
1039 if (MaskedIndices.none())
1040 return;
1041 assert(UnusedIndices.count() == MaskedIndices.count() &&
1042 "Non-synced masked/available indices.");
1043 int Idx = UnusedIndices.find_first();
1044 int MIdx = MaskedIndices.find_first();
1045 while (MIdx >= 0) {
1046 assert(Idx >= 0 && "Indices must be synced.");
1047 Order[MIdx] = Idx;
1048 Idx = UnusedIndices.find_next(Idx);
1049 MIdx = MaskedIndices.find_next(MIdx);
1050 }
1051}
1052
1054 unsigned Opcode0, unsigned Opcode1) {
1055 unsigned ScalarTyNumElements = getNumElements(ScalarTy);
1056 SmallBitVector OpcodeMask(VL.size() * ScalarTyNumElements, false);
1057 for (unsigned Lane : seq<unsigned>(VL.size())) {
1058 if (isa<PoisonValue>(VL[Lane]))
1059 continue;
1060 if (cast<Instruction>(VL[Lane])->getOpcode() == Opcode1)
1061 OpcodeMask.set(Lane * ScalarTyNumElements,
1062 Lane * ScalarTyNumElements + ScalarTyNumElements);
1063 }
1064 return OpcodeMask;
1065}
1066
1068 assert(none_of(Val, [](Constant *C) { return C->getType()->isVectorTy(); }) &&
1069 "Expected scalar constants.");
1070 SmallVector<Constant *> NewVal(Val.size() * VF);
1071 for (auto [I, V] : enumerate(Val))
1072 std::fill_n(NewVal.begin() + I * VF, VF, V);
1073 return NewVal;
1074}
1075
1077 switch (Opcode) {
1078 case Instruction::UDiv:
1079 return Intrinsic::masked_udiv;
1080 case Instruction::SDiv:
1081 return Intrinsic::masked_sdiv;
1082 case Instruction::URem:
1083 return Intrinsic::masked_urem;
1084 case Instruction::SRem:
1085 return Intrinsic::masked_srem;
1086 default:
1087 llvm_unreachable("Unexpected opcode");
1088 }
1089}
1090
1091/// Returns true if \p I is a part of a single-use chain, computing an address,
1092/// which does not pay off the vectorization: all the lanes are extracted for
1093/// the scalar addresses, the extracts delay the memory accesses.
1095 constexpr unsigned MaxIndexChainLength = 3;
1096 const User *U = I->user_back();
1097 for ([[maybe_unused]] unsigned _ : seq<unsigned>(MaxIndexChainLength)) {
1099 return true;
1100 if (!isa<Instruction>(U) || !U->hasOneUse())
1101 return false;
1102 U = U->user_back();
1103 }
1104 return false;
1105}
1106
1108 if (!I->hasOneUse() || isNonProfitableIndex(I))
1109 return false;
1110 // The operation with the identity or the absorbing constant is folded away
1111 // before the codegen, the vector node only repacks the lanes.
1112 if (const auto *BO = dyn_cast<BinaryOperator>(I)) {
1113 unsigned Opcode = BO->getOpcode();
1114 Type *Ty = BO->getType();
1115 for (unsigned Idx : seq<unsigned>(2)) {
1116 const auto *C = dyn_cast<Constant>(BO->getOperand(Idx));
1118 Opcode, Ty, /*AllowRHSConstant=*/Idx == 1) ||
1120 Opcode, Ty, /*AllowLHSConstant=*/Idx == 0)))
1121 return false;
1122 }
1123 }
1124 const User *U = I->user_back();
1127 if (isa<CastInst>(I))
1128 return !isa<FPToSIInst, FPToUIInst>(I) &&
1129 (!isa<CastInst>(U) || U->hasOneUse());
1131 I);
1132}
1133
1134Instruction *lookThroughCastRoundTrip(Value *V, bool MustBeElidable) {
1135 auto *Wide = dyn_cast<FPExtInst>(V);
1136 if (!Wide || !Wide->hasOneUse())
1137 return nullptr;
1138 auto *Narrow = dyn_cast<FPTruncInst>(Wide->getOperand(0));
1139 if (!Narrow || !Narrow->hasOneUse())
1140 return nullptr;
1141 Value *Src = Narrow->getOperand(0);
1142 if (!isa<Instruction>(Src) || Src->getType() != Wide->getType())
1143 return nullptr;
1144 if (MustBeElidable && !(Wide->hasAllowContract() && Wide->hasNoNaNs() &&
1145 Wide->hasNoInfs() && Narrow->hasAllowContract()))
1146 return nullptr;
1147 return Narrow;
1148}
1149
1150namespace {
1151
1152/// Shifts and the mask accumulated from the narrow ops on the current path:
1153/// the shifts above and at the narrow level, the bitwidth of the narrow ops
1154/// (0 if none) and the mask from the absorbed narrow ands.
1155struct NarrowedChainState {
1156 unsigned Shift = 0;
1157 unsigned NarrowShift = 0;
1158 unsigned NarrowBW = 0;
1159 APInt NarrowMask = APInt(1, 0);
1160
1161 /// The mask for the absorbed narrow ops in the leaf type, applied before
1162 /// widening and shifting; all-ones if nothing was absorbed.
1163 APInt getMask(unsigned LeafBW) const {
1164 if (NarrowBW == 0)
1165 return APInt::getAllOnes(LeafBW);
1166 return (NarrowMask & (APInt::getAllOnes(NarrowBW) << NarrowShift))
1167 .lshr(NarrowShift)
1168 .trunc(LeafBW);
1169 }
1170};
1171
1172} // namespace
1173
1174static void
1175collectNarrowedLeavesImpl(Value *V, unsigned RdxOpcode, unsigned WideBW,
1176 NarrowedChainState S, unsigned Depth,
1177 unsigned MaxDepth,
1179 SmallVectorImpl<Instruction *> &ChainInsts) {
1180 if (Depth < MaxDepth) {
1181 if (auto *Z = dyn_cast<ZExtInst>(V);
1182 Z && Z->getSrcTy()->isIntegerTy() && !Z->getSrcTy()->isIntegerTy(1)) {
1183 ChainInsts.push_back(Z);
1184 return collectNarrowedLeavesImpl(Z->getOperand(0), RdxOpcode, WideBW, S,
1185 Depth + 1, MaxDepth, Leaves, ChainInsts);
1186 }
1187 if (auto *BO = dyn_cast<BinaryOperator>(V)) {
1188 if (BO->getOpcode() == RdxOpcode) {
1189 ChainInsts.push_back(BO);
1190 collectNarrowedLeavesImpl(BO->getOperand(0), RdxOpcode, WideBW, S,
1191 Depth + 1, MaxDepth, Leaves, ChainInsts);
1192 collectNarrowedLeavesImpl(BO->getOperand(1), RdxOpcode, WideBW, S,
1193 Depth + 1, MaxDepth, Leaves, ChainInsts);
1194 return;
1195 }
1196 const APInt *Amt;
1197 unsigned BW = V->getType()->getScalarSizeInBits();
1198 auto *Z = dyn_cast<ZExtInst>(BO->getOperand(0));
1199 if (BO->getOpcode() == Instruction::Shl && Z && S.NarrowBW == 0 &&
1200 match(BO->getOperand(1), m_APInt(Amt)) && Amt->ult(BW) &&
1201 Z->getSrcTy()->isIntegerTy() && !Z->getSrcTy()->isIntegerTy(1) &&
1202 (BW == WideBW ||
1203 Z->getSrcTy()->getIntegerBitWidth() + Amt->getZExtValue() <= BW) &&
1204 S.Shift + Amt->getZExtValue() < WideBW) {
1205 ChainInsts.push_back(BO);
1206 ChainInsts.push_back(Z);
1207 S.Shift += Amt->getZExtValue();
1208 return collectNarrowedLeavesImpl(Z->getOperand(0), RdxOpcode, WideBW, S,
1209 Depth + 1, MaxDepth, Leaves,
1210 ChainInsts);
1211 }
1212 // Narrow shls fold into the shift and narrow ands into the mask; the
1213 // mask clears the bits the shls shift out. Only same-width ops compose
1214 // on one path, and the combined shift must stay a valid shift amount in
1215 // both types.
1216 if (BW < WideBW && (S.NarrowBW == 0 || BW == S.NarrowBW)) {
1217 if (BO->getOpcode() == Instruction::Shl &&
1218 match(BO->getOperand(1), m_APInt(Amt)) && Amt->ult(BW) &&
1219 S.NarrowShift + Amt->getZExtValue() < BW &&
1220 S.Shift + S.NarrowShift + Amt->getZExtValue() < WideBW) {
1221 ChainInsts.push_back(BO);
1222 if (BO->hasNoUnsignedWrap() && S.NarrowBW == 0) {
1223 S.Shift += Amt->getZExtValue();
1224 // Lossless shls shift out only known-zero bits; record them as
1225 // the mask so matching lanes can form a splat.
1226 S.NarrowBW = BW;
1227 S.NarrowMask = APInt::getLowBitsSet(BW, BW - Amt->getZExtValue());
1228 } else {
1229 if (S.NarrowBW == 0) {
1230 S.NarrowBW = BW;
1231 S.NarrowMask = APInt::getAllOnes(BW);
1232 }
1233 S.NarrowShift += Amt->getZExtValue();
1234 }
1235 return collectNarrowedLeavesImpl(BO->getOperand(0), RdxOpcode, WideBW,
1236 S, Depth + 1, MaxDepth, Leaves,
1237 ChainInsts);
1238 }
1239 Value *X;
1240 if (match(BO, m_c_And(m_Value(X), m_APInt(Amt)))) {
1241 ChainInsts.push_back(BO);
1242 if (S.NarrowBW == 0) {
1243 S.NarrowBW = BW;
1244 S.NarrowMask = APInt::getAllOnes(BW);
1245 }
1246 S.NarrowMask &= *Amt << S.NarrowShift;
1247 return collectNarrowedLeavesImpl(X, RdxOpcode, WideBW, S, Depth + 1,
1248 MaxDepth, Leaves, ChainInsts);
1249 }
1250 }
1251 }
1252 }
1253 Leaves.emplace_back(V, S.Shift + S.NarrowShift,
1254 S.getMask(V->getType()->getScalarSizeInBits()));
1255}
1256
1257void collectNarrowedLeaves(Value *V, unsigned RdxOpcode, unsigned WideBW,
1258 unsigned MaxDepth,
1260 SmallVectorImpl<Instruction *> &ChainInsts) {
1261 collectNarrowedLeavesImpl(V, RdxOpcode, WideBW, NarrowedChainState(),
1262 /*Depth=*/0, MaxDepth, Leaves, ChainInsts);
1263}
1264
1266 assert(F && "Expected function.");
1267 return F->hasOptSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput;
1268}
1269
1270/// Checks if \p V is a zero-extended sub-field of a wider integer scalar.
1271/// Returns the source scalar, the field width and the field offset.
1272static std::optional<std::tuple<Value *, unsigned, unsigned>>
1274 if (!V->getType()->isIntegerTy())
1275 return std::nullopt;
1276 // Field offset for the field-aligned shift amount, if the shifted value of
1277 // the given bit width keeps at least one full field.
1278 auto GetFieldOffset = [](const APInt *Amt, unsigned BitWidth,
1279 unsigned FieldWidth) -> std::optional<unsigned> {
1280 uint64_t ShAmt = Amt->getLimitedValue(BitWidth);
1281 if (ShAmt % FieldWidth != 0 || ShAmt + FieldWidth > BitWidth)
1282 return std::nullopt;
1283 return ShAmt / FieldWidth;
1284 };
1285 // Checks if the low bits of Val are a sub-field of the given width of a
1286 // wider integer scalar. Val is a scalar integer, since V is one, and so is
1287 // the matched source.
1288 auto MatchLowField =
1289 [&](Value *Val,
1290 unsigned FieldWidth) -> std::optional<std::pair<Value *, unsigned>> {
1291 Value *Src;
1292 const APInt *Amt;
1293 // Only the low bits of Val are observed, so lshr and ashr are equivalent.
1294 if (match(Val, m_Trunc(m_Shr(m_Value(Src), m_APInt(Amt)))) ||
1295 match(Val, m_Shr(m_Value(Src), m_APInt(Amt)))) {
1296 if (std::optional<unsigned> Offset = GetFieldOffset(
1297 Amt, Src->getType()->getIntegerBitWidth(), FieldWidth)) {
1298 // The truncation of the shifted value keeps the field, look through it.
1299 match(Src, m_Trunc(m_Value(Src)));
1300 return std::make_pair(Src, *Offset);
1301 }
1302 return std::nullopt;
1303 }
1304 if (match(Val, m_Trunc(m_Value(Src))) &&
1305 Src->getType()->getIntegerBitWidth() >= FieldWidth)
1306 return std::make_pair(Src, 0u);
1307 // Val itself is the source of its low field.
1308 if (Val->getType()->getIntegerBitWidth() > FieldWidth)
1309 return std::make_pair(Val, 0u);
1310 return std::nullopt;
1311 };
1312 Value *Val;
1313 const APInt *Mask;
1314 // and Val, (1 << FieldWidth) - 1 or zext i<FieldWidth> Val - the low bits of
1315 // Val.
1316 unsigned FieldWidth = 0;
1317 if (match(V, m_c_And(m_Value(Val), m_APInt(Mask))) && Mask->isMask())
1318 FieldWidth = Mask->popcount();
1319 else if (match(V, m_ZExt(m_Value(Val))))
1320 FieldWidth = Val->getType()->getIntegerBitWidth();
1321 if (FieldWidth != 0) {
1322 if (std::optional<std::pair<Value *, unsigned>> Field =
1323 MatchLowField(Val, FieldWidth))
1324 return std::make_tuple(Field->first, FieldWidth, Field->second);
1325 return std::nullopt;
1326 }
1327 unsigned LaneWidth = V->getType()->getIntegerBitWidth();
1328 Value *Src;
1329 const APInt *Amt;
1330 if (match(V, m_Trunc(m_LShr(m_Value(Src), m_APInt(Amt))))) {
1331 unsigned SrcWidth = Src->getType()->getIntegerBitWidth();
1332 uint64_t ShAmt = Amt->getLimitedValue(SrcWidth);
1333 // The field itself, if the lane width is the field width.
1334 if (std::optional<unsigned> Offset =
1335 GetFieldOffset(Amt, SrcWidth, LaneWidth))
1336 return std::make_tuple(Src, LaneWidth, *Offset);
1337 // The zero-extended top field of the source.
1338 unsigned FieldWidth = SrcWidth - ShAmt;
1339 if (FieldWidth > 0 && FieldWidth < LaneWidth && ShAmt % FieldWidth == 0)
1340 return std::make_tuple(Src, FieldWidth, ShAmt / FieldWidth);
1341 return std::nullopt;
1342 }
1343 if (match(V, m_LShr(m_Value(Src), m_APInt(Amt)))) {
1344 // The zero-extended top field of the source, if the result keeps exactly
1345 // one field. Look through a truncation of the shifted value.
1346 unsigned ShfWidth = Src->getType()->getIntegerBitWidth();
1347 uint64_t ShAmt = Amt->getLimitedValue(ShfWidth);
1348 unsigned FieldWidth = ShfWidth - ShAmt;
1349 if (FieldWidth > 0 && ShAmt % FieldWidth == 0) {
1350 match(Src, m_Trunc(m_Value(Src)));
1351 return std::make_tuple(Src, FieldWidth, ShAmt / FieldWidth);
1352 }
1353 return std::nullopt;
1354 }
1355 if (match(V, m_Trunc(m_Value(Src))))
1356 return std::make_tuple(Src, LaneWidth, 0u);
1357 return std::nullopt;
1358}
1359
1360std::optional<std::tuple<Value *, unsigned, SmallVector<int>>>
1362 // Splats are emitted as broadcasts, sub-fields of a constant are folded.
1363 // The bitcast to the field vector maps lane 0 to the least significant
1364 // field on little-endian targets only.
1365 if (VL.size() < 2 || !VL.front()->getType()->isIntegerTy() || isSplat(VL) ||
1366 DL.isBigEndian())
1367 return std::nullopt;
1368 Value *Src = nullptr;
1369 unsigned FieldWidth = 0;
1371 for (auto [Idx, V] : make_filter_range(enumerate(VL), [](const auto &P) {
1372 return !isa<UndefValue>(P.value());
1373 })) {
1374 if (V->getType() != VL.front()->getType())
1375 return std::nullopt;
1376 std::optional<std::tuple<Value *, unsigned, unsigned>> Field =
1378 if (!Field || (Src && (Src != std::get<0>(*Field) ||
1379 FieldWidth != std::get<1>(*Field))))
1380 return std::nullopt;
1381 Src = std::get<0>(*Field);
1382 FieldWidth = std::get<1>(*Field);
1383 Mask[Idx] = std::get<2>(*Field);
1384 }
1385 // The field width is a whole number of bytes and divides the source
1386 // exactly, same as for the packing layout, so the source bitcasts to the
1387 // field vector.
1388 if (!Src || isa<Constant>(Src) || FieldWidth % 8 != 0 ||
1389 Src->getType()->getIntegerBitWidth() % FieldWidth != 0)
1390 return std::nullopt;
1391 // The same field in every lane is a splat, emitted as a broadcast.
1392 if (all_of(Mask, [First = *find_if(Mask, not_equal_to(PoisonMaskElem))](
1393 int MaskElt) {
1394 return MaskElt == PoisonMaskElem || MaskElt == First;
1395 }))
1396 return std::nullopt;
1397 return std::make_tuple(Src, FieldWidth, std::move(Mask));
1398}
1399
1400/// Deeper than the standard analysis recursion depth to keep the numeric
1401/// bound precise through arithmetic carry chains.
1403
1404APInt getScalarMaxValue(const Value *V, unsigned Depth) {
1405 unsigned BitWidth = V->getType()->getScalarSizeInBits();
1407 if (Depth > MaxBitPackAnalysisDepth || !V->getType()->isIntegerTy())
1408 return Unknown;
1409 const APInt *C, *Amt;
1410 if (match(V, m_APInt(C)))
1411 return *C;
1412 Value *L, *R;
1413 if (match(V, m_Add(m_Value(L), m_Value(R))) ||
1414 match(V, m_Or(m_Value(L), m_Value(R))) ||
1415 match(V, m_Xor(m_Value(L), m_Value(R))))
1416 return getScalarMaxValue(L, Depth + 1)
1418 if (match(V, m_NUWSub(m_Value(L), m_Value(R))))
1419 return getScalarMaxValue(L, Depth + 1);
1420 if (match(V, m_Mul(m_Value(L), m_Value(R))))
1421 return getScalarMaxValue(L, Depth + 1)
1423 if (match(V, m_And(m_Value(L), m_Value(R))))
1424 return APIntOps::umin(getScalarMaxValue(L, Depth + 1),
1425 getScalarMaxValue(R, Depth + 1));
1426 if (match(V, m_LShr(m_Value(L), m_APInt(Amt))) && Amt->ult(BitWidth))
1427 return getScalarMaxValue(L, Depth + 1).lshr(*Amt);
1428 if (match(V, m_Shl(m_Value(L), m_APInt(Amt))) && Amt->ult(BitWidth)) {
1429 APInt LMax = getScalarMaxValue(L, Depth + 1);
1430 return LMax.getActiveBits() + Amt->getZExtValue() <= BitWidth
1431 ? LMax.shl(*Amt)
1432 : Unknown;
1433 }
1434 if (match(V, m_ZExt(m_Value(L))))
1435 return getScalarMaxValue(L, Depth + 1).zext(BitWidth);
1436 if (match(V, m_Trunc(m_Value(L)))) {
1437 APInt Max = getScalarMaxValue(L, Depth + 1);
1438 return Max.getActiveBits() <= BitWidth ? Max.trunc(BitWidth) : Unknown;
1439 }
1440 if (match(V, m_SExt(m_Value(L)))) {
1441 APInt Max = getScalarMaxValue(L, Depth + 1);
1442 return Max.isNonNegative() ? Max.zext(BitWidth) : Unknown;
1443 }
1444 Value *F;
1445 if (match(V, m_Select(m_Value(), m_Value(L), m_Value(F))))
1446 return APIntOps::umax(getScalarMaxValue(L, Depth + 1),
1447 getScalarMaxValue(F, Depth + 1));
1448 return Unknown;
1449}
1450
1451std::optional<BitPackInfo> computeBitPackInfo(unsigned BitWidth,
1452 ArrayRef<APInt> PossibleBits,
1453 ArrayRef<uint64_t> ShlAmts,
1454 ArrayRef<APInt> Masks) {
1455 unsigned NumElts = PossibleBits.size();
1456 BitPackInfo Info;
1457 Info.LShrAmts.assign(NumElts, 0);
1458 for (unsigned Idx : seq(NumElts)) {
1459 APInt Possible = PossibleBits[Idx].shl(ShlAmts[Idx]) & Masks[Idx];
1460 if (Possible.isZero())
1461 continue;
1462 unsigned Lo, W;
1463 if (!Possible.isShiftedMask(Lo, W))
1464 return std::nullopt;
1465 if (Info.FieldWidth == 0) {
1466 if (W % 8 != 0 || BitWidth % W != 0)
1467 return std::nullopt;
1468 Info.FieldWidth = W;
1469 Info.LaneOfField.assign(BitWidth / W, BitPackInfo::NoLane);
1470 }
1471 if (W != Info.FieldWidth || Lo % W != 0)
1472 return std::nullopt;
1473 unsigned Field = Lo / W;
1474 if (Info.LaneOfField[Field] != BitPackInfo::NoLane)
1475 return std::nullopt;
1476 Info.LaneOfField[Field] = Idx;
1477 Info.LShrAmts[Idx] = Lo - ShlAmts[Idx];
1478 }
1479 if (Info.FieldWidth == 0)
1480 return std::nullopt;
1481 return Info;
1482}
1483
1484SmallVector<int> getBitPackMask(const BitPackInfo &Info, unsigned NumBytes,
1485 unsigned NumElts, unsigned BytesPerLane) {
1486 unsigned BytesPerField = Info.FieldWidth / 8;
1487 SmallVector<int> Mask;
1488 for (unsigned J : seq(NumBytes)) {
1489 unsigned Lane = Info.LaneOfField[J / BytesPerField];
1490 Mask.push_back(Lane == BitPackInfo::NoLane
1491 ? (int)(NumElts * BytesPerLane)
1492 : (int)(Lane * BytesPerLane + J % BytesPerField));
1493 }
1494 return Mask;
1495}
1496
1498 Type *ResultTy, unsigned ShiftWidth, unsigned &NumInsts) {
1499 NumInsts = 0;
1500 auto *VecTy = cast<FixedVectorType>(X->getType());
1501 unsigned BitWidth = VecTy->getScalarSizeInBits();
1502 assert(BitWidth % 8 == 0 &&
1503 "The byte-multiple field width divides the result bit width.");
1504 unsigned NumElts = VecTy->getNumElements();
1505 Value *Y = X;
1506 if (ShiftWidth != BitWidth) {
1507 // Compacting a zext back to its source is free, use it directly.
1508 if (auto *Z = dyn_cast<ZExtInst>(X);
1509 Z && Z->getSrcTy()->getScalarSizeInBits() == ShiftWidth)
1510 Y = Z->getOperand(0);
1511 else {
1512 Y = Builder.CreateTrunc(
1513 Y, FixedVectorType::get(IntegerType::get(X->getContext(), ShiftWidth),
1514 NumElts));
1515 ++NumInsts;
1516 }
1517 }
1518 if (Info.needsShift()) {
1520 for (uint64_t A : Info.LShrAmts)
1521 Amts.push_back(
1522 ConstantInt::get(IntegerType::get(X->getContext(), ShiftWidth), A));
1523 Y = Builder.CreateLShr(Y, ConstantVector::get(Amts));
1524 ++NumInsts;
1525 }
1526 unsigned InBytes = NumElts * (ShiftWidth / 8);
1527 auto *ByteTy = FixedVectorType::get(Builder.getInt8Ty(), InBytes);
1529 Info, ResultTy->getScalarSizeInBits() / 8, NumElts, ShiftWidth / 8);
1530 // Fields in lane order, possibly reversed, are a truncation of the shifted
1531 // lanes. A reversal of byte fields is a bswap.
1532 bool IsReversed = equal(Info.LaneOfField, reverse(seq<unsigned>(NumElts)));
1533 if (IsReversed || equal(Info.LaneOfField, seq<unsigned>(NumElts))) {
1534 Value *Fields = Builder.CreateTrunc(
1535 Y, Y->getType()->getWithNewBitWidth(Info.FieldWidth));
1536 NumInsts += 1 + (Info.FieldWidth != ShiftWidth) + IsReversed;
1537 if (IsReversed && Info.FieldWidth == 8)
1538 return Builder.CreateUnaryIntrinsic(
1539 Intrinsic::bswap, Builder.CreateBitCast(Fields, ResultTy));
1540 if (IsReversed)
1541 Fields = Builder.CreateVectorReverse(Fields);
1542 return Builder.CreateBitCast(Fields, ResultTy);
1543 }
1544 Value *Packed = Builder.CreateShuffleVector(
1545 Builder.CreateBitCast(Y, ByteTy),
1546 is_contained(Info.LaneOfField, BitPackInfo::NoLane)
1547 ? Constant::getNullValue(ByteTy)
1548 : PoisonValue::get(ByteTy),
1549 Mask);
1550 NumInsts += 3;
1551 return Builder.CreateBitCast(Packed, ResultTy);
1552}
1553
1556 findDbgValues(&From, DVRs);
1557 auto *ExI = dyn_cast<Instruction>(&To);
1558 for (DbgVariableRecord *DVR : DVRs) {
1559 if (!DVR->isDbgValue())
1560 continue;
1561 Instruction *MarkedI = DVR->getInstruction();
1562 if (ExI && MarkedI->getParent() != ExI->getParent())
1563 continue;
1564 if (!ExI || ExI->comesBefore(MarkedI)) {
1565 DVR->replaceVariableLocationOp(&From, &To);
1566 continue;
1567 }
1568 DebugVariableAggregate Var(DVR);
1569 auto HasSameVar = [&](auto Records) {
1570 return any_of(filterDbgVars(Records),
1571 [&](const DbgVariableRecord &Other) {
1572 return DebugVariableAggregate(&Other) == Var;
1573 });
1574 };
1575 if (HasSameVar(make_range(std::next(DVR->getIterator()),
1576 MarkedI->getDbgRecordRange().end())) ||
1577 any_of(make_range(std::next(MarkedI->getIterator()),
1578 std::next(ExI->getIterator())),
1579 [&](const Instruction &I) {
1580 return HasSameVar(I.getDbgRecordRange());
1581 }))
1582 continue;
1583 DbgVariableRecord *NewDVR = DVR->clone();
1584 NewDVR->replaceVariableLocationOp(&From, &To);
1585 ExI->getParent()->insertDbgRecordAfter(NewDVR, ExI);
1586 }
1587}
1588
1590 const InsertElementInst *IE2) {
1591 if (IE1 == IE2)
1592 return false;
1593 const auto *I1 = IE1;
1594 const auto *I2 = IE2;
1595 const InsertElementInst *PrevI1;
1596 const InsertElementInst *PrevI2;
1597 unsigned Idx1 = *getElementIndex(IE1);
1598 unsigned Idx2 = *getElementIndex(IE2);
1599 do {
1600 if (I2 == IE1)
1601 return true;
1602 if (I1 == IE2)
1603 return false;
1604 PrevI1 = I1;
1605 PrevI2 = I2;
1606 if (I1 && (I1 == IE1 || I1->hasOneUse()) &&
1607 getElementIndex(I1).value_or(Idx2) != Idx2)
1608 I1 = dyn_cast<InsertElementInst>(I1->getOperand(0));
1609 if (I2 && ((I2 == IE2 || I2->hasOneUse())) &&
1610 getElementIndex(I2).value_or(Idx1) != Idx1)
1611 I2 = dyn_cast<InsertElementInst>(I2->getOperand(0));
1612 } while ((I1 && PrevI1 != I1) || (I2 && PrevI2 != I2));
1613 llvm_unreachable("Two different buildvectors not expected.");
1614}
1615
1617 if (DebugLoc DL = PN.getDebugLoc())
1618 return DL;
1619 return DebugLoc::getUnknown();
1620}
1621
1622std::optional<unsigned> getAggregateSize(Instruction *InsertInst) {
1623 if (auto *IE = dyn_cast<InsertElementInst>(InsertInst))
1624 return cast<FixedVectorType>(IE->getType())->getNumElements();
1625
1626 unsigned AggregateSize = 1;
1627 auto *IV = cast<InsertValueInst>(InsertInst);
1628 Type *CurrentType = IV->getType();
1629 do {
1630 if (auto *ST = dyn_cast<StructType>(CurrentType)) {
1631 for (auto *Elt : ST->elements())
1632 if (Elt != ST->getElementType(0)) // check homogeneity
1633 return std::nullopt;
1634 AggregateSize *= ST->getNumElements();
1635 CurrentType = ST->getElementType(0);
1636 } else if (auto *AT = dyn_cast<ArrayType>(CurrentType)) {
1637 AggregateSize *= AT->getNumElements();
1638 CurrentType = AT->getElementType();
1639 } else if (auto *VT = dyn_cast<FixedVectorType>(CurrentType)) {
1640 AggregateSize *= VT->getNumElements();
1641 return AggregateSize;
1642 } else if (CurrentType->isSingleValueType()) {
1643 return AggregateSize;
1644 } else {
1645 return std::nullopt;
1646 }
1647 } while (true);
1648}
1649
1651 assert(L && "Expected valid loop");
1652 auto IsLoopInvariant = [&](const Loop *L, ArrayRef<Value *> VL) {
1654 [L](Instruction *I) { return L->isLoopInvariant(I); });
1655 };
1656 while (L && IsLoopInvariant(L, VL))
1657 L = L->getParentLoop();
1658 return L;
1659}
1660
1662 unsigned LoopAwareTripCount) {
1663 if (LoopAwareTripCount == 0)
1664 return 1;
1665 unsigned Scale = SE.getSmallConstantTripCount(L);
1666 if (Scale == 0)
1667 Scale = getLoopEstimatedTripCount(const_cast<Loop *>(L)).value_or(0);
1668 if (Scale != 0) {
1669 // Multiple exiting blocks - choose the minimum between trip count (scale)
1670 // and LoopAwareTripCount, since the multiple exit loops can be terminated
1671 // early.
1672 if (!L->getExitingBlock())
1673 return std::min<unsigned>(LoopAwareTripCount, Scale);
1674 return Scale;
1675 }
1676 return LoopAwareTripCount;
1677}
1678
1679} // namespace llvm::slpvectorizer
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Hexagon Common GEP
#define _
static MaybeAlign getAlign(Value *Ptr)
IRTranslator LLVM IR MI
static std::pair< Value *, APInt > getMask(Value *WideMask, unsigned Factor, ElementCount LeafValueEC)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
#define P(N)
This file contains some templates that are useful if you are working with the STL at all.
Provides some synthesis utilities to produce sequences of values.
This file defines the SmallPtrSet class.
static unsigned getScalarSizeInBits(Type *Ty)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const uint32_t IV[8]
Definition blake3_impl.h:83
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition APInt.h:230
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1057
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1532
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:376
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition APInt.h:1115
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:325
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
Definition APInt.h:506
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
Definition APInt.h:471
LLVM_ABI APInt uadd_sat(const APInt &RHS) const
Definition APInt.cpp:2074
APInt shl(unsigned shiftAmt) const
Left-shift function.
Definition APInt.h:875
LLVM_ABI APInt umul_sat(const APInt &RHS) const
Definition APInt.cpp:2115
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:302
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:853
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & front() const
Get the first element.
Definition ArrayRef.h:144
iterator end() const
Definition ArrayRef.h:130
size_t size() const
Get the array size.
Definition ArrayRef.h:141
iterator begin() const
Definition ArrayRef.h:129
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition ArrayRef.h:185
const T & consume_front()
consume_front() - Returns the first element and drops it from ArrayRef.
Definition ArrayRef.h:156
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
static LLVM_ABI Constant * getBinOpAbsorber(unsigned Opcode, Type *Ty, bool AllowLHSConstant=false)
Return the absorbing element for the given binary operation, i.e.
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
Definition Constant.h:44
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LLVM_ABI void replaceVariableLocationOp(Value *OldValue, Value *NewValue, bool AllowEmpty=false)
LLVM_ABI DbgVariableRecord * clone() const
A debug info location.
Definition DebugLoc.h:126
static DebugLoc getUnknown()
Definition DebugLoc.h:153
Identifies a unique instance of a whole variable (discards/ignores fragment information).
This instruction extracts a single (scalar) element from a VectorType value.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
Common base class shared among various IRBuilders.
Definition IRBuilder.h:111
This instruction inserts a single (scalar) element into a VectorType value.
iterator_range< simple_ilist< DbgRecord >::iterator > getDbgRecordRange() const
Return a range over the DbgRecords attached to this instruction.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isShift() const
bool isIntDivRem() const
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
An instruction for reading from memory.
Value * getPointerOperand()
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
This is the common base class for memset/memcpy/memmove.
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
The main scalar evolution driver.
LLVM_ABI unsigned getSmallConstantTripCount(const Loop *L)
Returns the exact trip count of the loop if we can compute it, and the result is a small constant.
This class represents the LLVM 'select' instruction.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
SmallBitVector & set()
bool test(unsigned Idx) const
Returns true if bit Idx is set.
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
bool all() const
Returns true if all bits are set.
size_type count() const
Returns the number of bits which are set.
SmallBitVector & reset()
bool none() const
Returns true if none of the bits are set.
size_type size() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
void swap(SmallVectorImpl &RHS)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Provides information about what library functions are available for the current target.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
@ SK_Select
Selects elements from the corresponding lane of either source operand.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ SK_PermuteTwoSrc
Merge elements from two source vectors into one with any shuffle mask.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:258
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
Definition Type.h:306
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
bool hasUseList() const
Check if this Value has a use-list.
Definition Value.h:346
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
Definition Value.cpp:151
iterator_range< use_iterator > uses()
Definition Value.h:382
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
A raw_ostream that writes to an std::string.
Caches the results of the expensive analyses that are queried repeatedly for the same values while th...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
Definition APInt.h:2284
const APInt & umax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be unsigned.
Definition APInt.h:2289
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(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.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
BinOpPred_match< LHS, RHS, is_right_shift_op > m_Shr(const LHS &L, const RHS &R)
Matches logical shift operations.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap > m_NUWSub(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::Or > m_Or(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
A private "module" namespace for types and utilities used by this pass.
std::optional< unsigned > getExtractIndex(const Instruction *E)
Definition SLPUtils.cpp:300
template SmallBitVector isUndefVector< true >(const Value *, const SmallBitVector &)
Value * createInsertVector(IRBuilderBase &Builder, Value *Vec, Value *V, unsigned Index, function_ref< Value *(Value *, Value *, ArrayRef< int >)> Generator)
Creates subvector insert.
Definition SLPUtils.cpp:706
bool areAllOperandsNonInsts(Value *V)
Checks if the provided value does not require scheduling.
Definition SLPUtils.cpp:480
std::optional< unsigned > getElementIndex(const Value *Inst, unsigned Offset)
Definition SLPUtils.cpp:254
DebugLoc getDebugLocFromPHI(const PHINode &PN)
bool doesInTreeUserNeedToExtract(Value *Scalar, Instruction *UserInst, TargetLibraryInfo *TLI, const TargetTransformInfo *TTI)
Definition SLPUtils.cpp:809
bool isCopyableGEPAddressVector(ArrayRef< Value * > PointerOps)
Checks if the pointers PointerOps of the gathered loads, which are not compatible in the usual sense ...
Definition SLPUtils.cpp:947
std::optional< std::tuple< Value *, unsigned, SmallVector< int > > > matchGatheredExtractedFields(ArrayRef< Value * > VL, const DataLayout &DL)
Checks if the values in VL are zero-extended sub-fields of the same wider integer scalar.
MemoryLocation getLocation(Instruction *I)
Definition SLPUtils.cpp:837
std::optional< BitPackInfo > computeBitPackInfo(unsigned BitWidth, ArrayRef< APInt > PossibleBits, ArrayRef< uint64_t > ShlAmts, ArrayRef< APInt > Masks)
Computes the bitfield packing layout from the per-lane possibly set bits of the source values,...
bool isSelectedBaseLoad(Type *ScalarTy, ArrayRef< Value * > PointerOps, const DataLayout &DL, Value *&TrueBase, Value *&FalseBase, SmallVectorImpl< Value * > &Conditions)
Checks if the loads with scalar type ScalarTy and pointer operands PointerOps are each (optionally vi...
Definition SLPUtils.cpp:855
SmallBitVector getAltInstrMask(ArrayRef< Value * > VL, Type *ScalarTy, unsigned Opcode0, unsigned Opcode1)
SmallBitVector isUndefVector(const Value *V, const SmallBitVector &UseMask)
Checks if the given value is actually an undefined constant vector.
Definition SLPUtils.cpp:759
Intrinsic::ID getMaskedDivRemIntrinsic(unsigned Opcode)
bool isUsedOutsideBlock(Value *V)
Checks if the provided value does not require scheduling.
Definition SLPUtils.cpp:491
bool doesNotNeedToSchedule(ArrayRef< Value * > VL)
Checks if the specified array of instructions does not require scheduling.
Definition SLPUtils.cpp:508
std::optional< unsigned > getInsertExtractIndex(const Value *Inst, unsigned Offset)
Definition SLPUtils.cpp:447
void redirectDbgValues(Instruction &From, Value &To)
The debug values of the erased From are kept on its replacement To.
void reorderScalars(SmallVectorImpl< Value * > &Scalars, ArrayRef< int > Mask)
Reorders the list of scalars in accordance with the given Mask.
Definition SLPUtils.cpp:333
SmallVector< int > getBitPackMask(const BitPackInfo &Info, unsigned NumBytes, unsigned NumElts, unsigned BytesPerLane)
Returns the byte shuffle mask packing the per-lane fields of the shifted lanes (BytesPerLane bytes ea...
SelectInst * getBlendedLoadSelect(ArrayRef< Value * > VL)
Returns the select instruction picking between the candidate base pointers of the blended loads VL.
Definition SLPUtils.cpp:908
static std::optional< std::tuple< Value *, unsigned, unsigned > > matchExtractedField(Value *V)
Checks if V is a zero-extended sub-field of a wider integer scalar.
bool allSameType(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:440
void combineOrders(MutableArrayRef< unsigned > Order, ArrayRef< unsigned > SecondaryOrder)
Fills unset elements of Order (marked with the sentinel value equal to the order size) with the corre...
Definition SLPUtils.cpp:418
bool allSameOpcode(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:282
bool isSplat(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:165
unsigned getNumElements(Type *Ty)
Definition SLPUtils.cpp:110
std::string shortBundleName(ArrayRef< Value * > VL, int Idx)
Print a short descriptor of the instruction bundle suitable for debug output.
Definition SLPUtils.cpp:127
unsigned getLoopTripCount(const Loop *L, ScalarEvolution &SE, unsigned LoopAwareTripCount)
bool isOnceUsedSeed(const Instruction *I)
Returns true if I forms a vectorizable bundle on its own and its single user does not tear the vector...
unsigned getPartNumElems(unsigned Size, unsigned NumParts)
Returns power-of-2 number of elements in a single register (part), given the total number of elements...
Definition SLPUtils.cpp:118
constexpr unsigned MaxBitPackAnalysisDepth
Deeper than the standard analysis recursion depth to keep the numeric bound precise through arithmeti...
bool isCommutableOperand(const Instruction *I, Value *ValWithUses, unsigned Op, bool IsCopyable)
Checks if the operand is commutative.
Definition SLPUtils.cpp:226
Align computeBlendedLoadBaseAlignment(ArrayRef< Value * > VL, const DataLayout &DL)
Returns the alignment of the shared base pointer of a blended load for the loads VL.
Definition SLPUtils.cpp:895
TargetTransformInfo::TargetCostKind getSLPCostKind(const Function *F)
bool isReverseOrder(ArrayRef< unsigned > Order)
Check if Order represents reverse order.
Definition SLPUtils.cpp:397
Type * getCommonGEPIndexType(ArrayRef< Value * > VL, Instruction *VL0, function_ref< bool(Value *)> IsGEPLane, const DataLayout &DL)
Returns the common type for the indices of the single-index GEP lanes of a GEP node with the main op ...
Definition SLPUtils.cpp:915
void transformScalarShuffleIndiciesToVector(unsigned VecTyNumElements, SmallVectorImpl< int > &Mask)
Definition SLPUtils.cpp:513
SmallVector< int > calculateShufflevectorMask(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:568
SmallBitVector buildUseMask(int VF, ArrayRef< int > Mask, UseMask MaskArg)
Prepares a use bitset for the given mask either for the first argument or for the second.
Definition SLPUtils.cpp:742
bool isCommutative(const Instruction *I, const Value *ValWithUses, bool IsCopyable)
Definition SLPUtils.cpp:188
template SmallBitVector isUndefVector< false >(const Value *, const SmallBitVector &)
unsigned getNumberOfPotentiallyCommutativeOps(Instruction *I)
Definition SLPUtils.cpp:244
bool allConstant(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:159
template std::optional< unsigned > getInsertExtractIndex< InsertElementInst >(const Value *, unsigned)
void inversePermutation(ArrayRef< unsigned > Indices, SmallVectorImpl< int > &Mask)
Compute the inverse permutation Mask of Indices.
Definition SLPUtils.cpp:324
bool allSameBlock(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:137
bool isReassocChainLink(const Instruction *I)
Definition SLPUtils.cpp:82
Intrinsic::ID isEquivalentIntrinsicID(Intrinsic::ID LHS, Intrinsic::ID RHS)
Checks if LHS and RHS are the same intrinsic, or one is llvm.fma and the other is llvm....
Definition SLPUtils.cpp:179
std::optional< TargetTransformInfo::ShuffleKind > isFixedVectorShuffle(ArrayRef< Value * > VL, SmallVectorImpl< int > &Mask, AssumptionCache *AC, SLPAnalysisCache &Cache)
Checks if the vector of instructions can be represented as a shuffle, like: x0 = extractelement <4 x ...
Definition SLPUtils.cpp:608
UseMask
Specifies the way the mask should be analyzed for undefs/poisonous elements in the shuffle mask.
Definition SLPUtils.h:308
@ SecondArg
The mask is expected to be for permutation of 2 vectors, check for the mask elements for the second a...
Definition SLPUtils.h:312
@ UndefsAsMask
Consider undef mask elements (-1) as placeholders for future shuffle elements and mark them as ones a...
Definition SLPUtils.h:315
@ FirstArg
The mask is expected to be for permutation of 1-2 vectors, check for the mask elements for the first ...
Definition SLPUtils.h:309
void reorderOrder(SmallVectorImpl< unsigned > &Order, ArrayRef< int > Mask, bool BottomOrder)
Reorders the given Order according to the given Mask.
Definition SLPUtils.cpp:353
static void collectNarrowedLeavesImpl(Value *V, unsigned RdxOpcode, unsigned WideBW, NarrowedChainState S, unsigned Depth, unsigned MaxDepth, SmallVectorImpl< NarrowedLeafInfo > &Leaves, SmallVectorImpl< Instruction * > &ChainInsts)
void reorderReuses(SmallVectorImpl< int > &Reuses, ArrayRef< int > Mask)
Reorders the given Reuses mask according to the given Mask.
Definition SLPUtils.cpp:343
void addMask(SmallVectorImpl< int > &Mask, ArrayRef< int > SubMask, bool ExtendingManyInputs)
Shuffles Mask in accordance with the given SubMask.
bool isSimple(Instruction *I)
Definition SLPUtils.cpp:845
Instruction * lookThroughCastRoundTrip(Value *V, bool MustBeElidable)
If V is a single-use fpext of a single-use fptrunc forming a round-trip back to the type of V,...
std::optional< unsigned > getAggregateSize(Instruction *InsertInst)
const LoadInst * getLoadOfUndefTolerantBinOp(const Value *V)
Definition SLPUtils.cpp:62
bool isBinOpIdentityConstant(const Value *V, unsigned Opcode)
Definition SLPUtils.cpp:51
bool isUndefTolerantBinOp(const Value *V)
Definition SLPUtils.cpp:56
APInt getScalarMaxValue(const Value *V, unsigned Depth)
Returns a saturating unsigned upper bound of the scalar V.
Value * buildBitPack(IRBuilderBase &Builder, Value *X, const BitPackInfo &Info, Type *ResultTy, unsigned ShiftWidth, unsigned &NumInsts)
Builds the bitfield packing of X into ResultTy per the layout and the shift width.
unsigned getShufflevectorNumGroups(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:528
const Loop * findInnermostNonInvariantLoop(const Loop *L, ArrayRef< Value * > VL)
SmallVector< Constant * > replicateMask(ArrayRef< Constant * > Val, unsigned VF)
Replicates the given Val VF times.
unsigned getReassocCombineOpcode(unsigned Opcode)
Definition SLPUtils.cpp:71
bool isVectorLikeInstWithConstOps(Value *V)
Checks if V is one of vector-like instructions, i.e.
Definition SLPUtils.cpp:90
bool doesNotNeedToBeScheduled(Value *V)
Checks if the specified value does not require scheduling.
Definition SLPUtils.cpp:504
unsigned getNumElems(unsigned Size, unsigned PartNumElems, unsigned Part)
Returns correct remaining number of elements, considering total amount Size, (power-of-2 number) of e...
Definition SLPUtils.cpp:122
constexpr int UsesLimit
Limit of the number of uses for potentially transformed instructions/values, used in checks to avoid ...
Definition SLPUtils.h:59
bool isFirstInsertElement(const InsertElementInst *IE1, const InsertElementInst *IE2)
void collectNarrowedLeaves(Value *V, unsigned RdxOpcode, unsigned WideBW, unsigned MaxDepth, SmallVectorImpl< NarrowedLeafInfo > &Leaves, SmallVectorImpl< Instruction * > &ChainInsts)
Recursively collects the narrow leaves of the widened reduction value V.
bool isRepeatedNonIdentityClusteredMask(ArrayRef< int > Mask, unsigned Sz)
Checks if the given mask is a "clustered" mask with the same clusters of size Sz, which are not ident...
Definition SLPUtils.cpp:406
bool isConstant(Value *V)
Definition SLPUtils.cpp:47
static bool isNonProfitableIndex(const Instruction *I)
Returns true if I is a part of a single-use chain, computing an address, which does not pay off the v...
Value * createExtractVector(IRBuilderBase &Builder, Value *Vec, unsigned SubVecVF, unsigned Index)
Generates subvector extract.
Definition SLPUtils.cpp:735
template std::optional< unsigned > getInsertExtractIndex< ExtractElementInst >(const Value *, unsigned)
void fixupOrderingIndices(MutableArrayRef< unsigned > Order)
Order may have elements assigned special value (size) which is out of bounds.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Definition STLExtras.h:2196
LLVM_ABI std::optional< unsigned > getLoopEstimatedTripCount(Loop *L, unsigned *EstimatedLoopInvocationWeight=nullptr)
Return either:
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI Intrinsic::ID getVectorIntrinsicIDForCall(const CallInst *CI, const TargetLibraryInfo *TLI)
Returns intrinsic ID for call.
LLVM_ABI void findDbgValues(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the dbg.values describing a value.
@ Unknown
Not known to have no common set bits.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr from_range_t from_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isVectorizedTy(Type *Ty)
Returns true if Ty is a vector type or a struct of vector types where all vector types share the same...
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Definition bit.h:362
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
constexpr unsigned MaxAnalysisRecursionDepth
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
ElementCount getVectorizedTypeVF(Type *Ty)
Returns the number of vector elements for a vectorized type.
auto find_if_not(R &&Range, UnaryPredicate P)
Definition STLExtras.h:1793
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:552
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
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr int PoisonMaskElem
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:389
@ Other
Any other memory.
Definition ModRef.h:68
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
TargetTransformInfo TTI
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:206
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
Definition STLExtras.h:2162
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI bool mayHaveNonDefUseDependency(const Instruction &I)
Returns true if the result or effects of the given instructions I depend values not reachable through...
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Description of a bitfield packing of vector lanes into a scalar value: every lane contributes a disjo...
Definition SLPUtils.h:494
static constexpr unsigned NoLane
Definition SLPUtils.h:495
SmallVector< uint64_t, 8 > LShrAmts
Per-lane right-shift amounts bringing the field content to the low bits.
Definition SLPUtils.h:500