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
51Constant *getReassocIdentity(unsigned Opcode, Type *Ty, bool Negated) {
52 // Subtracting -0.0 turns a -0.0 total into +0.0.
53 if (Negated && Opcode == Instruction::FAdd)
54 Opcode = Instruction::FSub;
55 return ConstantExpr::getBinOpIdentity(Opcode, Ty, /*AllowRHSConstant=*/true);
56}
57
58bool isBinOpIdentityConstant(const Value *V, unsigned Opcode, bool Negated) {
60 V == getReassocIdentity(Opcode, V->getType(), Negated);
61}
62
64 const BinaryOperator *BO;
65 return match(V, m_BinOp(BO)) && BO->getType()->isIntOrIntVectorTy() &&
66 !BO->isShift() && !BO->isIntDivRem();
67}
68
71 return nullptr;
72 for (const Value *Op : cast<BinaryOperator>(V)->operands())
73 if (const auto *LI = dyn_cast<LoadInst>(Op))
74 return LI;
75 return nullptr;
76}
77
78unsigned getReassocCombineOpcode(unsigned Opcode) {
79 switch (Opcode) {
80 case Instruction::Sub:
81 return Instruction::Add;
82 case Instruction::FSub:
83 return Instruction::FAdd;
84 default:
85 return Opcode;
86 }
87}
88
90 if (I->getOpcode() == Instruction::Sub)
91 return true;
92 if (I->getOpcode() == Instruction::FSub)
93 return I->hasAllowReassoc();
94 return I->isAssociative();
95}
96
98 auto *I = dyn_cast<Instruction>(V);
99 // Non-instructions are vector-like only if they are undef.
100 if (!I)
101 return isa<UndefValue>(V);
102 switch (I->getOpcode()) {
103 case Instruction::ExtractValue:
104 case Instruction::InsertValue:
105 return true;
106 case Instruction::ExtractElement:
107 return isa<FixedVectorType>(I->getOperand(0)->getType()) &&
108 isConstant(I->getOperand(1));
109 case Instruction::InsertElement:
110 return isa<FixedVectorType>(I->getOperand(0)->getType()) &&
111 isConstant(I->getOperand(2));
112 default:
113 return false;
114 }
115}
116
117unsigned getNumElements(Type *Ty) {
119 "ScalableVectorType is not supported.");
120 if (isVectorizedTy(Ty))
122 return 1;
123}
124
125unsigned getPartNumElems(unsigned Size, unsigned NumParts) {
126 return std::min<unsigned>(Size, bit_ceil(divideCeil(Size, NumParts)));
127}
128
129unsigned getNumElems(unsigned Size, unsigned PartNumElems, unsigned Part) {
130 return std::min<unsigned>(PartNumElems, Size - Part * PartNumElems);
131}
132
133#if !defined(NDEBUG)
134std::string shortBundleName(ArrayRef<Value *> VL, int Idx) {
135 std::string Result;
136 raw_string_ostream OS(Result);
137 if (Idx >= 0)
138 OS << "Idx: " << Idx << ", ";
139 OS << "n=" << VL.size() << " [" << *VL.front() << ", ..]";
140 return Result;
141}
142#endif
143
145 auto *It = find_if(VL, IsaPred<Instruction>);
146 if (It == VL.end())
147 return false;
150 return true;
151
152 BasicBlock *BB = I0->getParent();
153 for (Value *V : make_filter_range(iterator_range(It, VL.end()), [](Value *V) {
154 return !isa<PoisonValue>(V);
155 })) {
156 auto *II = dyn_cast<Instruction>(V);
157 if (!II)
158 return false;
159
160 if (BB != II->getParent())
161 return false;
162 }
163 return true;
164}
165
167 // Constant expressions and globals can't be vectorized like normal integer/FP
168 // constants.
169 return all_of(VL, isConstant);
170}
171
173 Value *FirstNonUndef = nullptr;
174 for (Value *V :
175 make_filter_range(VL, [](Value *V) { return !isa<UndefValue>(V); })) {
176 if (!FirstNonUndef) {
177 FirstNonUndef = V;
178 continue;
179 }
180 if (V != FirstNonUndef)
181 return false;
182 }
183 return FirstNonUndef != nullptr;
184}
185
187 if (LHS == RHS)
188 return RHS;
189 if ((LHS == Intrinsic::fma || LHS == Intrinsic::fmuladd) &&
190 (RHS == Intrinsic::fma || RHS == Intrinsic::fmuladd))
191 return Intrinsic::fma;
193}
194
195bool isCommutative(const Instruction *I, const Value *ValWithUses,
196 bool IsCopyable) {
197 // The trunc X to i1 lanes of a compare have the single operand X.
198 if (auto *Cmp = dyn_cast<CmpInst>(I))
199 return isa<CmpInst>(ValWithUses) && Cmp->isCommutative();
200 if (auto *BO = dyn_cast<BinaryOperator>(I))
201 return BO->isCommutative() ||
202 (BO->getOpcode() == Instruction::Sub && ValWithUses->hasUseList() &&
203 !ValWithUses->hasNUsesOrMore(UsesLimit) &&
204 all_of(
205 ValWithUses->uses(),
206 [&](const Use &U) {
207 // Commutative, if icmp eq/ne sub, 0
208 CmpPredicate Pred;
209 if (match(U.getUser(),
210 m_ICmp(Pred, m_Specific(U.get()), m_Zero())) &&
211 (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE))
212 return true;
213 // Commutative, if abs(sub nsw, true) or abs(sub, false).
214 ConstantInt *Flag;
215 auto *I = dyn_cast<BinaryOperator>(U.get());
216 return match(U.getUser(),
217 m_Intrinsic<Intrinsic::abs>(
218 m_Specific(U.get()), m_ConstantInt(Flag))) &&
219 ((!IsCopyable && I && !I->hasNoSignedWrap()) ||
220 Flag->isOne());
221 })) ||
222 (BO->getOpcode() == Instruction::FSub && ValWithUses->hasUseList() &&
223 !ValWithUses->hasNUsesOrMore(UsesLimit) &&
224 all_of(ValWithUses->uses(), [](const Use &U) {
225 return match(U.getUser(),
226 m_Intrinsic<Intrinsic::fabs>(m_Specific(U.get())));
227 }));
228 return I->isCommutative();
229}
230
231bool isCommutative(const Instruction *I) { return isCommutative(I, I); }
232
233bool isCommutableOperand(const Instruction *I, Value *ValWithUses, unsigned Op,
234 bool IsCopyable) {
235 assert(isCommutative(I, ValWithUses, IsCopyable) &&
236 "The instruction is not commutative.");
237 if (isa<CmpInst>(I))
238 return true;
239 if (auto *BO = dyn_cast<BinaryOperator>(I)) {
240 switch (BO->getOpcode()) {
241 case Instruction::Sub:
242 case Instruction::FSub:
243 return true;
244 default:
245 break;
246 }
247 }
248 return I->isCommutableOperand(Op);
249}
250
253 // IntrinsicInst::isCommutative returns true if swapping the first "two"
254 // arguments to the intrinsic produces the same result.
255 constexpr unsigned IntrinsicNumOperands = 2;
256 return IntrinsicNumOperands;
257 }
258 return I->getNumOperands();
259}
260
261std::optional<unsigned> getElementIndex(const Value *Inst, unsigned Offset) {
262 if (auto Index = getInsertExtractIndex<InsertElementInst>(Inst, Offset))
263 return Index;
265 return Index;
266
267 unsigned Index = Offset;
268
269 const auto *IV = dyn_cast<InsertValueInst>(Inst);
270 if (!IV)
271 return std::nullopt;
272
273 Type *CurrentType = IV->getType();
274 for (unsigned I : IV->indices()) {
275 if (const auto *ST = dyn_cast<StructType>(CurrentType)) {
276 Index *= ST->getNumElements();
277 CurrentType = ST->getElementType(I);
278 } else if (const auto *AT = dyn_cast<ArrayType>(CurrentType)) {
279 Index *= AT->getNumElements();
280 CurrentType = AT->getElementType();
281 } else {
282 return std::nullopt;
283 }
284 Index += I;
285 }
286 return Index;
287}
288
290 auto *It = find_if(VL, IsaPred<Instruction>);
291 if (It == VL.end())
292 return true;
293 Instruction *MainOp = cast<Instruction>(*It);
294 unsigned Opcode = MainOp->getOpcode();
295 bool IsCmpOp = isa<CmpInst>(MainOp);
296 CmpInst::Predicate BasePred = IsCmpOp ? cast<CmpInst>(MainOp)->getPredicate()
298 return all_of(make_range(It, VL.end()), [&](Value *V) {
299 if (auto *CI = dyn_cast<CmpInst>(V))
300 return BasePred == CI->getPredicate();
301 if (auto *I = dyn_cast<Instruction>(V))
302 return I->getOpcode() == Opcode;
303 return isa<PoisonValue>(V);
304 });
305}
306
307std::optional<unsigned> getExtractIndex(const Instruction *E) {
308 unsigned Opcode = E->getOpcode();
309 assert((Opcode == Instruction::ExtractElement ||
310 Opcode == Instruction::ExtractValue) &&
311 "Expected extractelement or extractvalue instruction.");
312 if (Opcode == Instruction::ExtractElement) {
313 auto *CI = dyn_cast<ConstantInt>(E->getOperand(1));
314 if (!CI)
315 return std::nullopt;
316 // Check if the index is out of bound. We can get the source vector from
317 // operand 0.
318 unsigned Idx = CI->getZExtValue();
319 auto *EE = cast<ExtractElementInst>(E);
320 const unsigned VF = getNumElements(EE->getVectorOperandType());
321 if (Idx >= VF)
322 return std::nullopt;
323 return Idx;
324 }
325 auto *EI = cast<ExtractValueInst>(E);
326 if (EI->getNumIndices() != 1)
327 return std::nullopt;
328 return *EI->idx_begin();
329}
330
332 SmallVectorImpl<int> &Mask) {
333 Mask.clear();
334 const unsigned E = Indices.size();
335 Mask.resize(E, PoisonMaskElem);
336 for (unsigned I = 0; I < E; ++I)
337 Mask[Indices[I]] = I;
338}
339
341 assert(!Mask.empty() && "Expected non-empty mask.");
342 SmallVector<Value *> Prev(Scalars.size(),
343 PoisonValue::get(Scalars.front()->getType()));
344 Prev.swap(Scalars);
345 for (unsigned I = 0, E = Prev.size(); I < E; ++I)
346 if (Mask[I] != PoisonMaskElem)
347 Scalars[Mask[I]] = Prev[I];
348}
349
351 assert(!Mask.empty() && Reuses.size() == Mask.size() &&
352 "Expected non-empty mask.");
353 SmallVector<int> Prev(Reuses.begin(), Reuses.end());
354 Prev.swap(Reuses);
355 for (unsigned I = 0, E = Prev.size(); I < E; ++I)
356 if (Mask[I] != PoisonMaskElem)
357 Reuses[Mask[I]] = Prev[I];
358}
359
361 bool BottomOrder) {
362 assert(!Mask.empty() && "Expected non-empty mask.");
363 unsigned Sz = Mask.size();
364 if (BottomOrder) {
365 SmallVector<unsigned> PrevOrder;
366 if (Order.empty()) {
367 PrevOrder.resize(Sz);
368 std::iota(PrevOrder.begin(), PrevOrder.end(), 0);
369 } else {
370 PrevOrder.swap(Order);
371 }
372 Order.assign(Sz, Sz);
373 for (unsigned I = 0; I < Sz; ++I)
374 if (Mask[I] != PoisonMaskElem)
375 Order[I] = PrevOrder[Mask[I]];
376 if (all_of(enumerate(Order), [&](const auto &Data) {
377 return Data.value() == Sz || Data.index() == Data.value();
378 })) {
379 Order.clear();
380 return;
381 }
383 return;
384 }
385 SmallVector<int> MaskOrder;
386 if (Order.empty()) {
387 MaskOrder.resize(Sz);
388 std::iota(MaskOrder.begin(), MaskOrder.end(), 0);
389 } else {
390 inversePermutation(Order, MaskOrder);
391 }
392 reorderReuses(MaskOrder, Mask);
393 if (ShuffleVectorInst::isIdentityMask(MaskOrder, Sz)) {
394 Order.clear();
395 return;
396 }
397 Order.assign(Sz, Sz);
398 for (unsigned I = 0; I < Sz; ++I)
399 if (MaskOrder[I] != PoisonMaskElem)
400 Order[MaskOrder[I]] = I;
402}
403
405 assert(!Order.empty() &&
406 "Order is empty. Please check it before using isReverseOrder.");
407 unsigned Sz = Order.size();
408 return all_of(enumerate(Order), [&](const auto &Pair) {
409 return Pair.value() == Sz || Sz - Pair.index() - 1 == Pair.value();
410 });
411}
412
414 ArrayRef<int> FirstCluster = Mask.slice(0, Sz);
415 if (ShuffleVectorInst::isIdentityMask(FirstCluster, Sz))
416 return false;
417 for (unsigned I = Sz, E = Mask.size(); I < E; I += Sz) {
418 ArrayRef<int> Cluster = Mask.slice(I, Sz);
419 if (Cluster != FirstCluster)
420 return false;
421 }
422 return true;
423}
424
426 ArrayRef<unsigned> SecondaryOrder) {
427 assert((SecondaryOrder.empty() || Order.size() == SecondaryOrder.size()) &&
428 "Expected same size of orders");
429 size_t Sz = Order.size();
430 SmallBitVector UsedIndices(Sz);
431 for (unsigned Idx : seq<unsigned>(0, Sz)) {
432 if (Order[Idx] != Sz)
433 UsedIndices.set(Order[Idx]);
434 }
435 if (SecondaryOrder.empty()) {
436 for (unsigned Idx : seq<unsigned>(0, Sz))
437 if (Order[Idx] == Sz && !UsedIndices.test(Idx))
438 Order[Idx] = Idx;
439 } else {
440 for (unsigned Idx : seq<unsigned>(0, Sz))
441 if (SecondaryOrder[Idx] != Sz && Order[Idx] == Sz &&
442 !UsedIndices.test(SecondaryOrder[Idx]))
443 Order[Idx] = SecondaryOrder[Idx];
444 }
445}
446
448 assert(!VL.empty() && "Expected non-empty list of values.");
449 Type *Ty = VL.consume_front()->getType();
450 return all_of(VL, [&](Value *V) { return V->getType() == Ty; });
451}
452
453template <typename T>
454std::optional<unsigned> getInsertExtractIndex(const Value *Inst,
455 unsigned Offset) {
456 static_assert(std::is_same_v<T, InsertElementInst> ||
457 std::is_same_v<T, ExtractElementInst>,
458 "unsupported T");
459 const auto *IE = dyn_cast<T>(Inst);
460 if (!IE)
461 return std::nullopt;
462 // InsertElement: result is the vector, index is op 2.
463 // ExtractElement: result is scalar, vector is op 0, index is op 1.
464 constexpr bool IsInsert = std::is_same_v<T, InsertElementInst>;
465 Type *VecTy = IsInsert ? IE->getType() : IE->getOperand(0)->getType();
466 const auto *VT = dyn_cast<FixedVectorType>(VecTy);
467 if (!VT)
468 return std::nullopt;
469 const auto *CI = dyn_cast<ConstantInt>(IE->getOperand(IsInsert ? 2 : 1));
470 if (!CI)
471 return std::nullopt;
472 if (CI->getValue().uge(VT->getNumElements()))
473 return std::nullopt;
474 unsigned Index = Offset;
475 Index *= VT->getNumElements();
476 Index += CI->getZExtValue();
477 return Index;
478}
479
480// Only these two specializations are used; instantiate them here so the
481// definition can stay out of the header.
482template std::optional<unsigned>
484template std::optional<unsigned>
486
488 auto *I = dyn_cast<Instruction>(V);
489 if (!I)
490 return true;
491 return all_of(make_isa_range<Instruction>(I->operands()),
492 [I](Instruction *IO) {
493 return isa<PHINode>(IO) || IO->getParent() != I->getParent();
494 }) &&
496}
497
499 auto *I = dyn_cast<Instruction>(V);
500 if (!I)
501 return true;
502 // Limits the number of uses to save compile time.
503 return !I->hasNUsesOrMore(UsesLimit) && all_of(I->users(), [I](User *U) {
504 auto *IU = dyn_cast<Instruction>(U);
505 if (!IU)
506 return true;
507 return IU->getParent() != I->getParent() || isa<PHINode>(IU);
508 }) && !I->mayReadOrWriteMemory();
509}
510
514
519
520void transformScalarShuffleIndiciesToVector(unsigned VecTyNumElements,
521 SmallVectorImpl<int> &Mask) {
522 // The ShuffleBuilder implementation use shufflevector to splat an "element".
523 // But the element have different meaning for SLP (scalar) and REVEC
524 // (vector). We need to expand Mask into masks which shufflevector can use
525 // directly.
526 SmallVector<int> NewMask(Mask.size() * VecTyNumElements);
527 for (unsigned I : seq<unsigned>(Mask.size()))
528 for (auto [J, MaskV] : enumerate(MutableArrayRef(NewMask).slice(
529 I * VecTyNumElements, VecTyNumElements)))
530 MaskV = Mask[I] == PoisonMaskElem ? PoisonMaskElem
531 : Mask[I] * VecTyNumElements + J;
532 Mask.swap(NewMask);
533}
534
536 if (VL.empty())
537 return 0;
539 return 0;
540 auto *SV = cast<ShuffleVectorInst>(VL.front());
541 unsigned SVNumElements =
542 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
543 unsigned ShuffleMaskSize = SV->getShuffleMask().size();
544 if (SVNumElements % ShuffleMaskSize != 0)
545 return 0;
546 unsigned GroupSize = SVNumElements / ShuffleMaskSize;
547 if (GroupSize == 0 || (VL.size() % GroupSize) != 0)
548 return 0;
549 unsigned NumGroup = 0;
550 for (size_t I = 0, E = VL.size(); I != E; I += GroupSize) {
551 auto *SV = cast<ShuffleVectorInst>(VL[I]);
552 Value *Src = SV->getOperand(0);
553 ArrayRef<Value *> Group = VL.slice(I, GroupSize);
554 SmallBitVector ExpectedIndex(GroupSize);
555 if (!all_of(Group, [&](Value *V) {
556 auto *SV = cast<ShuffleVectorInst>(V);
557 // From the same source.
558 if (SV->getOperand(0) != Src)
559 return false;
560 int Index;
561 if (!SV->isExtractSubvectorMask(Index))
562 return false;
563 ExpectedIndex.set(Index / ShuffleMaskSize);
564 return true;
565 }))
566 return 0;
567 if (!ExpectedIndex.all())
568 return 0;
569 ++NumGroup;
570 }
571 assert(NumGroup == (VL.size() / GroupSize) && "Unexpected number of groups");
572 return NumGroup;
573}
574
576 assert(getShufflevectorNumGroups(VL) && "Not supported shufflevector usage.");
577 auto *SV = cast<ShuffleVectorInst>(VL.front());
578 unsigned SVNumElements =
579 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
580 SmallVector<int> Mask;
581 unsigned AccumulateLength = 0;
582 for (Value *V : VL) {
583 auto *SV = cast<ShuffleVectorInst>(V);
584 for (int M : SV->getShuffleMask())
585 Mask.push_back(M == PoisonMaskElem ? PoisonMaskElem
586 : AccumulateLength + M);
587 AccumulateLength += SVNumElements;
588 }
589 return Mask;
590}
591
592/// Checks if the vector of instructions can be represented as a shuffle, like:
593/// %x0 = extractelement <4 x i8> %x, i32 0
594/// %x3 = extractelement <4 x i8> %x, i32 3
595/// %y1 = extractelement <4 x i8> %y, i32 1
596/// %y2 = extractelement <4 x i8> %y, i32 2
597/// %x0x0 = mul i8 %x0, %x0
598/// %x3x3 = mul i8 %x3, %x3
599/// %y1y1 = mul i8 %y1, %y1
600/// %y2y2 = mul i8 %y2, %y2
601/// %ins1 = insertelement <4 x i8> poison, i8 %x0x0, i32 0
602/// %ins2 = insertelement <4 x i8> %ins1, i8 %x3x3, i32 1
603/// %ins3 = insertelement <4 x i8> %ins2, i8 %y1y1, i32 2
604/// %ins4 = insertelement <4 x i8> %ins3, i8 %y2y2, i32 3
605/// ret <4 x i8> %ins4
606/// can be transformed into:
607/// %1 = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 3, i32 5,
608/// i32 6>
609/// %2 = mul <4 x i8> %1, %1
610/// ret <4 x i8> %2
611/// Mask will return the Shuffle Mask equivalent to the extracted elements.
612/// TODO: Can we split off and reuse the shuffle mask detection from
613/// ShuffleVectorInst/getShuffleCost?
614std::optional<TargetTransformInfo::ShuffleKind>
616 AssumptionCache *AC, SLPAnalysisCache &Cache) {
617 const auto *It = find_if(VL, IsaPred<ExtractElementInst>);
618 if (It == VL.end())
619 return std::nullopt;
620 unsigned Size = 0;
621 Value *Vec1 = nullptr;
622 Value *Vec2 = nullptr;
623 // The poison analysis is expensive, it is required only for the undef
624 // vectors.
625 std::optional<bool> HasNonUndefVec;
626 auto IsNonUndefVecPresent = [&]() {
627 if (!HasNonUndefVec)
628 HasNonUndefVec = any_of(make_isa_range<ExtractElementInst>(VL),
629 [&](ExtractElementInst *EE) {
630 Value *Vec = EE->getVectorOperand();
631 if (isa<UndefValue>(Vec))
632 return false;
633 return Cache.isGuaranteedNotToBePoison(Vec, AC);
634 });
635 return *HasNonUndefVec;
636 };
637 enum ShuffleMode { Unknown, Select, Permute };
638 ShuffleMode CommonShuffleMode = Unknown;
639 Mask.assign(VL.size(), PoisonMaskElem);
640 for (unsigned I = 0, E = VL.size(); I < E; ++I) {
641 // Undef, or a copyable lane modeled on an extract main op, can be
642 // represented as an undef element in a vector.
643 if (isa<UndefValue>(VL[I]))
644 continue;
645 auto *EI = dyn_cast<ExtractElementInst>(VL[I]);
646 if (!EI)
647 continue;
648 if (isa<ScalableVectorType>(EI->getVectorOperandType()))
649 return std::nullopt;
650 auto *Vec = EI->getVectorOperand();
651 // We can extractelement from undef or poison vector.
653 continue;
654 // All vector operands must have the same number of vector elements.
655 if (isa<UndefValue>(Vec)) {
656 Mask[I] = I;
657 } else {
658 if (isa<UndefValue>(EI->getIndexOperand()))
659 continue;
660 auto *Idx = dyn_cast<ConstantInt>(EI->getIndexOperand());
661 if (!Idx)
662 return std::nullopt;
663 // Undefined behavior if Idx is negative or out of bounds.
664 if (Idx->getValue().uge(getNumElements(Vec->getType())))
665 continue;
666 unsigned IntIdx = Idx->getValue().getZExtValue();
667 Mask[I] = IntIdx;
668 }
669 // The width is defined only by the lanes that are present in the mask.
670 Size = std::max(Size, getNumElements(Vec->getType()));
671 if (isUndefVector(Vec).all() && IsNonUndefVecPresent())
672 continue;
673 // For correct shuffling we have to have at most 2 different vector operands
674 // in all extractelement instructions.
675 if (!Vec1 || Vec1 == Vec) {
676 Vec1 = Vec;
677 } else if (!Vec2 || Vec2 == Vec) {
678 Vec2 = Vec;
679 } else {
680 return std::nullopt;
681 }
682 }
683 if (Vec2 && Size != std::max(getNumElements(Vec1->getType()),
684 getNumElements(Vec2->getType())))
685 return std::nullopt;
686 for (auto [I, Idx] : enumerate(Mask)) {
687 if (Idx == PoisonMaskElem)
688 continue;
689 auto *Vec = cast<ExtractElementInst>(VL[I])->getVectorOperand();
690 if (Vec == Vec2)
691 Idx += Size;
692 else if (Vec != Vec1)
693 continue;
694 if (CommonShuffleMode == Permute)
695 continue;
696 // If the extract index is not the same as the operation number, it is a
697 // permutation.
698 if (Idx % Size != I) {
699 CommonShuffleMode = Permute;
700 continue;
701 }
702 CommonShuffleMode = Select;
703 }
704 // If we're not crossing lanes in different vectors, consider it as blending.
705 if (CommonShuffleMode == Select && Vec2)
707 // If Vec2 was never used, we have a permutation of a single vector, otherwise
708 // we have permutation of 2 vectors.
711}
712
714 IRBuilderBase &Builder, Value *Vec, Value *V, unsigned Index,
715 function_ref<Value *(Value *, Value *, ArrayRef<int>)> Generator) {
716 if (isa<PoisonValue>(Vec) && isa<PoisonValue>(V))
717 return Vec;
718 const unsigned SubVecVF = getNumElements(V->getType());
719 // Create shuffle, insertvector requires that index is multiple of
720 // the subvector length.
721 const unsigned VecVF = getNumElements(Vec->getType());
722 SmallVector<int> Mask(VecVF, PoisonMaskElem);
723 if (isa<PoisonValue>(Vec)) {
724 auto *Begin = std::next(Mask.begin(), Index);
725 std::iota(Begin, std::next(Begin, SubVecVF), 0);
726 Vec = Builder.CreateShuffleVector(V, Mask);
727 return Vec;
728 }
729 std::iota(Mask.begin(), Mask.end(), 0);
730 std::iota(std::next(Mask.begin(), Index),
731 std::next(Mask.begin(), Index + SubVecVF), VecVF);
732 if (Generator)
733 return Generator(Vec, V, Mask);
734 // 1. Resize V to the size of Vec.
735 SmallVector<int> ResizeMask(VecVF, PoisonMaskElem);
736 std::iota(ResizeMask.begin(), std::next(ResizeMask.begin(), SubVecVF), 0);
737 V = Builder.CreateShuffleVector(V, ResizeMask);
738 // 2. Insert V into Vec.
739 return Builder.CreateShuffleVector(Vec, V, Mask);
740}
741
743 unsigned SubVecVF, unsigned Index) {
744 SmallVector<int> Mask(SubVecVF, PoisonMaskElem);
745 std::iota(Mask.begin(), Mask.end(), Index);
746 return Builder.CreateShuffleVector(Vec, Mask);
747}
748
750 SmallBitVector UseMask(VF, true);
751 for (auto [Idx, Value] : enumerate(Mask)) {
752 if (Value == PoisonMaskElem) {
753 if (MaskArg == UseMask::UndefsAsMask)
754 UseMask.reset(Idx);
755 continue;
756 }
757 if (MaskArg == UseMask::FirstArg && Value < VF)
758 UseMask.reset(Value);
759 else if (MaskArg == UseMask::SecondArg && Value >= VF)
760 UseMask.reset(Value - VF);
761 }
762 return UseMask;
763}
764
765template <bool IsPoisonOnly>
767 SmallBitVector Res(UseMask.empty() ? 1 : UseMask.size(), true);
768 using T = std::conditional_t<IsPoisonOnly, PoisonValue, UndefValue>;
769 if (isa<T>(V))
770 return Res;
771 auto *VecTy = dyn_cast<FixedVectorType>(V->getType());
772 if (!VecTy)
773 return Res.reset();
774 auto *C = dyn_cast<Constant>(V);
775 if (!C) {
776 if (!UseMask.empty()) {
777 const Value *Base = V;
778 while (auto *II = dyn_cast<InsertElementInst>(Base)) {
779 Base = II->getOperand(0);
780 if (isa<T>(II->getOperand(1)))
781 continue;
782 std::optional<unsigned> Idx = getElementIndex(II);
783 if (!Idx) {
784 Res.reset();
785 return Res;
786 }
787 if (*Idx < UseMask.size() && !UseMask.test(*Idx))
788 Res.reset(*Idx);
789 }
790 // TODO: Add analysis for shuffles here too.
791 if (V == Base) {
792 Res.reset();
793 } else {
794 SmallBitVector SubMask(UseMask.size(), false);
795 Res &= isUndefVector<IsPoisonOnly>(Base, SubMask);
796 }
797 } else {
798 Res.reset();
799 }
800 return Res;
801 }
802 for (unsigned I = 0, E = VecTy->getNumElements(); I != E; ++I) {
803 if (Constant *Elem = C->getAggregateElement(I))
804 if (!isa<T>(Elem) &&
805 (UseMask.empty() || (I < UseMask.size() && !UseMask.test(I))))
806 Res.reset(I);
807 }
808 return Res;
809}
810
812 const SmallBitVector &);
814 const SmallBitVector &);
815
818 const TargetTransformInfo *TTI) {
819 if (!UserInst)
820 return false;
821 unsigned Opcode = UserInst->getOpcode();
822 switch (Opcode) {
823 case Instruction::Load: {
824 LoadInst *LI = cast<LoadInst>(UserInst);
825 return (LI->getPointerOperand() == Scalar);
826 }
827 case Instruction::Store: {
828 StoreInst *SI = cast<StoreInst>(UserInst);
829 return (SI->getPointerOperand() == Scalar);
830 }
831 case Instruction::Call: {
832 CallInst *CI = cast<CallInst>(UserInst);
834 return any_of(enumerate(CI->args()), [&](auto &&Arg) {
835 return isVectorIntrinsicWithScalarOpAtArg(ID, Arg.index(), TTI) &&
836 Arg.value().get() == Scalar;
837 });
838 }
839 default:
840 return false;
841 }
842}
843
851
853 if (LoadInst *LI = dyn_cast<LoadInst>(I))
854 return LI->isSimple();
856 return SI->isSimple();
858 return !MI->isVolatile();
859 return true;
860}
861
862bool isSelectedBaseLoad(Type *ScalarTy, ArrayRef<Value *> PointerOps,
863 const DataLayout &DL, Value *&TrueBase,
864 Value *&FalseBase,
865 SmallVectorImpl<Value *> &Conditions) {
866 TrueBase = nullptr;
867 FalseBase = nullptr;
868 uint64_t ScalarSize = DL.getTypeStoreSize(ScalarTy);
869 Conditions.assign(PointerOps.size(), nullptr);
870 for (auto [Idx, P] : enumerate(PointerOps)) {
871 Value *Base = P;
872 uint64_t Offset = 0;
873 if (auto *GEP = dyn_cast<GetElementPtrInst>(P)) {
874 APInt OffsetAP(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
875 if (!GEP->accumulateConstantOffset(DL, OffsetAP) || OffsetAP.isNegative())
876 return false;
877 Offset = OffsetAP.getZExtValue();
878 Base = GEP->getPointerOperand();
879 }
880 auto *Sel = dyn_cast<SelectInst>(Base);
881 if (!Sel)
882 return false;
883 Value *T = Sel->getTrueValue();
884 Value *F = Sel->getFalseValue();
885 if (!TrueBase) {
886 if (T == F)
887 return false;
888 TrueBase = T;
889 FalseBase = F;
890 } else if (TrueBase != T || FalseBase != F) {
891 return false;
892 }
893 // Lane Idx must be at exactly Base + Idx * sizeof(ScalarTy); codegen reads
894 // contiguously from TrueBase/FalseBase starting at lane 0.
895 if (Offset != static_cast<uint64_t>(Idx) * ScalarSize)
896 return false;
897 Conditions[Idx] = Sel->getCondition();
898 }
899 return TrueBase != nullptr;
900}
901
903 const DataLayout &DL) {
905 "Expected only load lanes in a blended load.");
906 const uint64_t ScalarSize = DL.getTypeStoreSize(VL.front()->getType());
907 Align BaseAlignment = cast<LoadInst>(VL.front())->getAlign();
908 for (auto [Idx, V] : enumerate(VL))
909 BaseAlignment =
910 std::min(BaseAlignment, commonAlignment(cast<LoadInst>(V)->getAlign(),
911 Idx * ScalarSize));
912 return BaseAlignment;
913}
914
916 Value *Ptr = cast<LoadInst>(VL.front())->getPointerOperand();
917 if (auto *GEP = dyn_cast<GetElementPtrInst>(Ptr))
918 Ptr = GEP->getPointerOperand();
919 return cast<SelectInst>(Ptr);
920}
921
923 function_ref<bool(Value *)> IsGEPLane,
924 const DataLayout &DL) {
925 constexpr unsigned IndexIdx = 1;
926 Type *VL0Ty = VL0->getOperand(IndexIdx)->getType();
927 Type *PtrIdxTy =
928 DL.getIndexType(VL0->getOperand(0)->getType()->getScalarType());
929 bool AllSameTy = true;
930 bool HasNonConstIdx = false;
931 bool ConstsFitVL0Ty = true;
932 for (Value *V : make_filter_range(VL, IsGEPLane)) {
933 Value *Op = cast<GetElementPtrInst>(V)->getOperand(IndexIdx);
934 if (Op->getType() != VL0Ty)
935 AllSameTy = false;
936 auto *CI = dyn_cast<ConstantInt>(Op);
937 if (!CI) {
938 // Non-constant indices are not cast, they must have the main op type.
939 if (Op->getType() != VL0Ty)
940 return nullptr;
941 HasNonConstIdx = true;
942 continue;
943 }
944 if (!CI->getValue().isSignedIntN(VL0Ty->getIntegerBitWidth()))
945 ConstsFitVL0Ty = false;
946 }
947 if (AllSameTy)
948 return VL0Ty;
949 if (!HasNonConstIdx || VL0Ty == PtrIdxTy)
950 return PtrIdxTy;
951 return ConstsFitVL0Ty ? VL0Ty : nullptr;
952}
953
955 SmallPtrSet<Value *, 16> UniquePtrs(llvm::from_range, PointerOps);
956 if (UniquePtrs.size() != PointerOps.size())
957 return false;
958 auto IsConstantOffsetPtr = [](Value *P) {
960 return !GEP ||
961 (GEP->getNumOperands() == 2 && isConstant(GEP->getOperand(1)));
962 };
963 auto *RefIt = find_if_not(PointerOps, IsConstantOffsetPtr);
964 if (RefIt == PointerOps.end())
965 return false;
966 auto *RefGEP = dyn_cast<GetElementPtrInst>(*RefIt);
967 if (!RefGEP || RefGEP->getNumOperands() != 2)
968 return false;
969 Value *Base = RefGEP->getPointerOperand();
970 Type *PtrTy = RefGEP->getType();
971 Type *SrcElemTy = RefGEP->getSourceElementType();
972 // The stride and the (optional) cast opcode of the runtime indices.
973 Value *Stride = nullptr;
974 unsigned CastOpcode = 0;
975 for (Value *P : PointerOps) {
976 if (P->getType() != PtrTy)
977 return false;
978 if (P == Base)
979 continue;
981 if (!GEP || GEP->getNumOperands() != 2 ||
982 GEP->getPointerOperand() != Base ||
983 GEP->getSourceElementType() != SrcElemTy)
984 return false;
985 Value *Idx = GEP->getOperand(1);
986 if (isConstant(Idx))
987 continue;
988 unsigned LaneCastOpcode = 0;
989 if (auto *Cast = dyn_cast<CastInst>(Idx)) {
990 LaneCastOpcode = Cast->getOpcode();
991 Idx = Cast->getOperand(0);
992 }
993 Value *LaneStride = Idx;
994 if (auto *BO = dyn_cast<BinaryOperator>(Idx)) {
995 if (isa<Constant>(BO->getOperand(1)))
996 LaneStride = BO->getOperand(0);
997 else if (isa<Constant>(BO->getOperand(0)))
998 LaneStride = BO->getOperand(1);
999 }
1000 if (!Stride) {
1001 Stride = LaneStride;
1002 CastOpcode = LaneCastOpcode;
1003 continue;
1004 }
1005 if (LaneStride != Stride || LaneCastOpcode != CastOpcode)
1006 return false;
1007 }
1008 return Stride != nullptr;
1009}
1010
1012 bool ExtendingManyInputs) {
1013 if (SubMask.empty())
1014 return;
1015 assert(
1016 (!ExtendingManyInputs || SubMask.size() > Mask.size() ||
1017 // Check if input scalars were extended to match the size of other node.
1018 (SubMask.size() == Mask.size() && Mask.back() == PoisonMaskElem)) &&
1019 "SubMask with many inputs support must be larger than the mask.");
1020 if (Mask.empty()) {
1021 Mask.append(SubMask.begin(), SubMask.end());
1022 return;
1023 }
1024 SmallVector<int> NewMask(SubMask.size(), PoisonMaskElem);
1025 int TermValue = std::min(Mask.size(), SubMask.size());
1026 for (int I = 0, E = SubMask.size(); I < E; ++I) {
1027 if (SubMask[I] == PoisonMaskElem ||
1028 (!ExtendingManyInputs &&
1029 (SubMask[I] >= TermValue || Mask[SubMask[I]] >= TermValue)))
1030 continue;
1031 NewMask[I] = Mask[SubMask[I]];
1032 }
1033 Mask.swap(NewMask);
1034}
1035
1037 const size_t Sz = Order.size();
1038 SmallBitVector UnusedIndices(Sz, /*t=*/true);
1039 SmallBitVector MaskedIndices(Sz);
1040 for (unsigned I = 0; I < Sz; ++I) {
1041 if (Order[I] < Sz)
1042 UnusedIndices.reset(Order[I]);
1043 else
1044 MaskedIndices.set(I);
1045 }
1046 if (MaskedIndices.none())
1047 return;
1048 assert(UnusedIndices.count() == MaskedIndices.count() &&
1049 "Non-synced masked/available indices.");
1050 int Idx = UnusedIndices.find_first();
1051 int MIdx = MaskedIndices.find_first();
1052 while (MIdx >= 0) {
1053 assert(Idx >= 0 && "Indices must be synced.");
1054 Order[MIdx] = Idx;
1055 Idx = UnusedIndices.find_next(Idx);
1056 MIdx = MaskedIndices.find_next(MIdx);
1057 }
1058}
1059
1061 unsigned Opcode0, unsigned Opcode1) {
1062 unsigned ScalarTyNumElements = getNumElements(ScalarTy);
1063 SmallBitVector OpcodeMask(VL.size() * ScalarTyNumElements, false);
1064 for (unsigned Lane : seq<unsigned>(VL.size())) {
1065 if (isa<PoisonValue>(VL[Lane]))
1066 continue;
1067 if (cast<Instruction>(VL[Lane])->getOpcode() == Opcode1)
1068 OpcodeMask.set(Lane * ScalarTyNumElements,
1069 Lane * ScalarTyNumElements + ScalarTyNumElements);
1070 }
1071 return OpcodeMask;
1072}
1073
1075 assert(none_of(Val, [](Constant *C) { return C->getType()->isVectorTy(); }) &&
1076 "Expected scalar constants.");
1077 SmallVector<Constant *> NewVal(Val.size() * VF);
1078 for (auto [I, V] : enumerate(Val))
1079 std::fill_n(NewVal.begin() + I * VF, VF, V);
1080 return NewVal;
1081}
1082
1084 switch (Opcode) {
1085 case Instruction::UDiv:
1086 return Intrinsic::masked_udiv;
1087 case Instruction::SDiv:
1088 return Intrinsic::masked_sdiv;
1089 case Instruction::URem:
1090 return Intrinsic::masked_urem;
1091 case Instruction::SRem:
1092 return Intrinsic::masked_srem;
1093 default:
1094 llvm_unreachable("Unexpected opcode");
1095 }
1096}
1097
1098/// Returns true if \p I is a part of a single-use chain, computing an address,
1099/// which does not pay off the vectorization: all the lanes are extracted for
1100/// the scalar addresses, the extracts delay the memory accesses.
1102 constexpr unsigned MaxIndexChainLength = 3;
1103 const User *U = I->user_back();
1104 for ([[maybe_unused]] unsigned _ : seq<unsigned>(MaxIndexChainLength)) {
1106 return true;
1107 if (!isa<Instruction>(U) || !U->hasOneUse())
1108 return false;
1109 U = U->user_back();
1110 }
1111 return false;
1112}
1113
1115 if (!I->hasOneUse() || isNonProfitableIndex(I))
1116 return false;
1117 // The operation with the identity or the absorbing constant is folded away
1118 // before the codegen, the vector node only repacks the lanes.
1119 if (const auto *BO = dyn_cast<BinaryOperator>(I)) {
1120 unsigned Opcode = BO->getOpcode();
1121 Type *Ty = BO->getType();
1122 for (unsigned Idx : seq<unsigned>(2)) {
1123 const auto *C = dyn_cast<Constant>(BO->getOperand(Idx));
1125 Opcode, Ty, /*AllowRHSConstant=*/Idx == 1) ||
1127 Opcode, Ty, /*AllowLHSConstant=*/Idx == 0)))
1128 return false;
1129 }
1130 }
1131 const User *U = I->user_back();
1134 if (isa<CastInst>(I))
1135 return !isa<FPToSIInst, FPToUIInst>(I) &&
1136 (!isa<CastInst>(U) || U->hasOneUse());
1138 I);
1139}
1140
1141Instruction *lookThroughCastRoundTrip(Value *V, bool MustBeElidable) {
1142 auto *Wide = dyn_cast<FPExtInst>(V);
1143 if (!Wide || !Wide->hasOneUse())
1144 return nullptr;
1145 auto *Narrow = dyn_cast<FPTruncInst>(Wide->getOperand(0));
1146 if (!Narrow || !Narrow->hasOneUse())
1147 return nullptr;
1148 Value *Src = Narrow->getOperand(0);
1149 if (!isa<Instruction>(Src) || Src->getType() != Wide->getType())
1150 return nullptr;
1151 if (MustBeElidable && !(Wide->hasAllowContract() && Wide->hasNoNaNs() &&
1152 Wide->hasNoInfs() && Narrow->hasAllowContract()))
1153 return nullptr;
1154 return Narrow;
1155}
1156
1157namespace {
1158
1159/// Shifts and the mask accumulated from the narrow ops on the current path:
1160/// the shifts above and at the narrow level, the bitwidth of the narrow ops
1161/// (0 if none) and the mask from the absorbed narrow ands.
1162struct NarrowedChainState {
1163 unsigned Shift = 0;
1164 unsigned NarrowShift = 0;
1165 unsigned NarrowBW = 0;
1166 APInt NarrowMask = APInt(1, 0);
1167
1168 /// The mask for the absorbed narrow ops in the leaf type, applied before
1169 /// widening and shifting; all-ones if nothing was absorbed.
1170 APInt getMask(unsigned LeafBW) const {
1171 if (NarrowBW == 0)
1172 return APInt::getAllOnes(LeafBW);
1173 return (NarrowMask & (APInt::getAllOnes(NarrowBW) << NarrowShift))
1174 .lshr(NarrowShift)
1175 .trunc(LeafBW);
1176 }
1177};
1178
1179} // namespace
1180
1181static void
1182collectNarrowedLeavesImpl(Value *V, unsigned RdxOpcode, unsigned WideBW,
1183 NarrowedChainState S, unsigned Depth,
1184 unsigned MaxDepth,
1186 SmallVectorImpl<Instruction *> &ChainInsts) {
1187 if (Depth < MaxDepth) {
1188 if (auto *Z = dyn_cast<ZExtInst>(V);
1189 Z && Z->getSrcTy()->isIntegerTy() && !Z->getSrcTy()->isIntegerTy(1)) {
1190 ChainInsts.push_back(Z);
1191 return collectNarrowedLeavesImpl(Z->getOperand(0), RdxOpcode, WideBW, S,
1192 Depth + 1, MaxDepth, Leaves, ChainInsts);
1193 }
1194 if (auto *BO = dyn_cast<BinaryOperator>(V)) {
1195 if (BO->getOpcode() == RdxOpcode) {
1196 ChainInsts.push_back(BO);
1197 collectNarrowedLeavesImpl(BO->getOperand(0), RdxOpcode, WideBW, S,
1198 Depth + 1, MaxDepth, Leaves, ChainInsts);
1199 collectNarrowedLeavesImpl(BO->getOperand(1), RdxOpcode, WideBW, S,
1200 Depth + 1, MaxDepth, Leaves, ChainInsts);
1201 return;
1202 }
1203 const APInt *Amt;
1204 unsigned BW = V->getType()->getScalarSizeInBits();
1205 auto *Z = dyn_cast<ZExtInst>(BO->getOperand(0));
1206 if (BO->getOpcode() == Instruction::Shl && Z && S.NarrowBW == 0 &&
1207 match(BO->getOperand(1), m_APInt(Amt)) && Amt->ult(BW) &&
1208 Z->getSrcTy()->isIntegerTy() && !Z->getSrcTy()->isIntegerTy(1) &&
1209 (BW == WideBW ||
1210 Z->getSrcTy()->getIntegerBitWidth() + Amt->getZExtValue() <= BW) &&
1211 S.Shift + Amt->getZExtValue() < WideBW) {
1212 ChainInsts.push_back(BO);
1213 ChainInsts.push_back(Z);
1214 S.Shift += Amt->getZExtValue();
1215 return collectNarrowedLeavesImpl(Z->getOperand(0), RdxOpcode, WideBW, S,
1216 Depth + 1, MaxDepth, Leaves,
1217 ChainInsts);
1218 }
1219 // Narrow shls fold into the shift and narrow ands into the mask; the
1220 // mask clears the bits the shls shift out. Only same-width ops compose
1221 // on one path, and the combined shift must stay a valid shift amount in
1222 // both types.
1223 if (BW < WideBW && (S.NarrowBW == 0 || BW == S.NarrowBW)) {
1224 if (BO->getOpcode() == Instruction::Shl &&
1225 match(BO->getOperand(1), m_APInt(Amt)) && Amt->ult(BW) &&
1226 S.NarrowShift + Amt->getZExtValue() < BW &&
1227 S.Shift + S.NarrowShift + Amt->getZExtValue() < WideBW) {
1228 ChainInsts.push_back(BO);
1229 if (BO->hasNoUnsignedWrap() && S.NarrowBW == 0) {
1230 S.Shift += Amt->getZExtValue();
1231 // Lossless shls shift out only known-zero bits; record them as
1232 // the mask so matching lanes can form a splat.
1233 S.NarrowBW = BW;
1234 S.NarrowMask = APInt::getLowBitsSet(BW, BW - Amt->getZExtValue());
1235 } else {
1236 if (S.NarrowBW == 0) {
1237 S.NarrowBW = BW;
1238 S.NarrowMask = APInt::getAllOnes(BW);
1239 }
1240 S.NarrowShift += Amt->getZExtValue();
1241 }
1242 return collectNarrowedLeavesImpl(BO->getOperand(0), RdxOpcode, WideBW,
1243 S, Depth + 1, MaxDepth, Leaves,
1244 ChainInsts);
1245 }
1246 Value *X;
1247 if (match(BO, m_c_And(m_Value(X), m_APInt(Amt)))) {
1248 ChainInsts.push_back(BO);
1249 if (S.NarrowBW == 0) {
1250 S.NarrowBW = BW;
1251 S.NarrowMask = APInt::getAllOnes(BW);
1252 }
1253 S.NarrowMask &= *Amt << S.NarrowShift;
1254 return collectNarrowedLeavesImpl(X, RdxOpcode, WideBW, S, Depth + 1,
1255 MaxDepth, Leaves, ChainInsts);
1256 }
1257 }
1258 }
1259 }
1260 Leaves.emplace_back(V, S.Shift + S.NarrowShift,
1261 S.getMask(V->getType()->getScalarSizeInBits()));
1262}
1263
1264void collectNarrowedLeaves(Value *V, unsigned RdxOpcode, unsigned WideBW,
1265 unsigned MaxDepth,
1267 SmallVectorImpl<Instruction *> &ChainInsts) {
1268 collectNarrowedLeavesImpl(V, RdxOpcode, WideBW, NarrowedChainState(),
1269 /*Depth=*/0, MaxDepth, Leaves, ChainInsts);
1270}
1271
1273 assert(F && "Expected function.");
1274 return F->hasOptSize() ? TTI::TCK_CodeSize : TTI::TCK_RecipThroughput;
1275}
1276
1277/// Checks if \p V is a zero-extended sub-field of a wider integer scalar.
1278/// Returns the source scalar, the field width and the field offset.
1279static std::optional<std::tuple<Value *, unsigned, unsigned>>
1281 if (!V->getType()->isIntegerTy())
1282 return std::nullopt;
1283 // Field offset for the field-aligned shift amount, if the shifted value of
1284 // the given bit width keeps at least one full field.
1285 auto GetFieldOffset = [](const APInt *Amt, unsigned BitWidth,
1286 unsigned FieldWidth) -> std::optional<unsigned> {
1287 uint64_t ShAmt = Amt->getLimitedValue(BitWidth);
1288 if (ShAmt % FieldWidth != 0 || ShAmt + FieldWidth > BitWidth)
1289 return std::nullopt;
1290 return ShAmt / FieldWidth;
1291 };
1292 // Checks if the low bits of Val are a sub-field of the given width of a
1293 // wider integer scalar. Val is a scalar integer, since V is one, and so is
1294 // the matched source.
1295 auto MatchLowField =
1296 [&](Value *Val,
1297 unsigned FieldWidth) -> std::optional<std::pair<Value *, unsigned>> {
1298 Value *Src;
1299 const APInt *Amt;
1300 // Only the low bits of Val are observed, so lshr and ashr are equivalent.
1301 if (match(Val, m_Trunc(m_Shr(m_Value(Src), m_APInt(Amt)))) ||
1302 match(Val, m_Shr(m_Value(Src), m_APInt(Amt)))) {
1303 if (std::optional<unsigned> Offset = GetFieldOffset(
1304 Amt, Src->getType()->getIntegerBitWidth(), FieldWidth)) {
1305 // The truncation of the shifted value keeps the field, look through it.
1306 match(Src, m_Trunc(m_Value(Src)));
1307 return std::make_pair(Src, *Offset);
1308 }
1309 return std::nullopt;
1310 }
1311 if (match(Val, m_Trunc(m_Value(Src))) &&
1312 Src->getType()->getIntegerBitWidth() >= FieldWidth)
1313 return std::make_pair(Src, 0u);
1314 // Val itself is the source of its low field.
1315 if (Val->getType()->getIntegerBitWidth() > FieldWidth)
1316 return std::make_pair(Val, 0u);
1317 return std::nullopt;
1318 };
1319 Value *Val;
1320 const APInt *Mask;
1321 // and Val, (1 << FieldWidth) - 1 or zext i<FieldWidth> Val - the low bits of
1322 // Val.
1323 unsigned FieldWidth = 0;
1324 if (match(V, m_c_And(m_Value(Val), m_APInt(Mask))) && Mask->isMask())
1325 FieldWidth = Mask->popcount();
1326 else if (match(V, m_ZExt(m_Value(Val))))
1327 FieldWidth = Val->getType()->getIntegerBitWidth();
1328 if (FieldWidth != 0) {
1329 if (std::optional<std::pair<Value *, unsigned>> Field =
1330 MatchLowField(Val, FieldWidth))
1331 return std::make_tuple(Field->first, FieldWidth, Field->second);
1332 return std::nullopt;
1333 }
1334 unsigned LaneWidth = V->getType()->getIntegerBitWidth();
1335 Value *Src;
1336 const APInt *Amt;
1337 if (match(V, m_Trunc(m_LShr(m_Value(Src), m_APInt(Amt))))) {
1338 unsigned SrcWidth = Src->getType()->getIntegerBitWidth();
1339 uint64_t ShAmt = Amt->getLimitedValue(SrcWidth);
1340 // The field itself, if the lane width is the field width.
1341 if (std::optional<unsigned> Offset =
1342 GetFieldOffset(Amt, SrcWidth, LaneWidth))
1343 return std::make_tuple(Src, LaneWidth, *Offset);
1344 // The zero-extended top field of the source.
1345 unsigned FieldWidth = SrcWidth - ShAmt;
1346 if (FieldWidth > 0 && FieldWidth < LaneWidth && ShAmt % FieldWidth == 0)
1347 return std::make_tuple(Src, FieldWidth, ShAmt / FieldWidth);
1348 return std::nullopt;
1349 }
1350 if (match(V, m_LShr(m_Value(Src), m_APInt(Amt)))) {
1351 // The zero-extended top field of the source, if the result keeps exactly
1352 // one field. Look through a truncation of the shifted value.
1353 unsigned ShfWidth = Src->getType()->getIntegerBitWidth();
1354 uint64_t ShAmt = Amt->getLimitedValue(ShfWidth);
1355 unsigned FieldWidth = ShfWidth - ShAmt;
1356 if (FieldWidth > 0 && ShAmt % FieldWidth == 0) {
1357 match(Src, m_Trunc(m_Value(Src)));
1358 return std::make_tuple(Src, FieldWidth, ShAmt / FieldWidth);
1359 }
1360 return std::nullopt;
1361 }
1362 if (match(V, m_Trunc(m_Value(Src))))
1363 return std::make_tuple(Src, LaneWidth, 0u);
1364 return std::nullopt;
1365}
1366
1367std::optional<std::tuple<Value *, unsigned, SmallVector<int>>>
1369 // Splats are emitted as broadcasts, sub-fields of a constant are folded.
1370 // The bitcast to the field vector maps lane 0 to the least significant
1371 // field on little-endian targets only.
1372 if (VL.size() < 2 || !VL.front()->getType()->isIntegerTy() || isSplat(VL) ||
1373 DL.isBigEndian())
1374 return std::nullopt;
1375 Value *Src = nullptr;
1376 unsigned FieldWidth = 0;
1378 for (auto [Idx, V] : make_filter_range(enumerate(VL), [](const auto &P) {
1379 return !isa<UndefValue>(P.value());
1380 })) {
1381 if (V->getType() != VL.front()->getType())
1382 return std::nullopt;
1383 std::optional<std::tuple<Value *, unsigned, unsigned>> Field =
1385 if (!Field || (Src && (Src != std::get<0>(*Field) ||
1386 FieldWidth != std::get<1>(*Field))))
1387 return std::nullopt;
1388 Src = std::get<0>(*Field);
1389 FieldWidth = std::get<1>(*Field);
1390 Mask[Idx] = std::get<2>(*Field);
1391 }
1392 // The field width is a whole number of bytes and divides the source
1393 // exactly, same as for the packing layout, so the source bitcasts to the
1394 // field vector.
1395 if (!Src || isa<Constant>(Src) || FieldWidth % 8 != 0 ||
1396 Src->getType()->getIntegerBitWidth() % FieldWidth != 0)
1397 return std::nullopt;
1398 // The same field in every lane is a splat, emitted as a broadcast.
1399 if (all_of(Mask, [First = *find_if(Mask, not_equal_to(PoisonMaskElem))](
1400 int MaskElt) {
1401 return MaskElt == PoisonMaskElem || MaskElt == First;
1402 }))
1403 return std::nullopt;
1404 return std::make_tuple(Src, FieldWidth, std::move(Mask));
1405}
1406
1407/// Deeper than the standard analysis recursion depth to keep the numeric
1408/// bound precise through arithmetic carry chains.
1410
1411APInt getScalarMaxValue(const Value *V, unsigned Depth) {
1412 unsigned BitWidth = V->getType()->getScalarSizeInBits();
1414 if (Depth > MaxBitPackAnalysisDepth || !V->getType()->isIntegerTy())
1415 return Unknown;
1416 const APInt *C, *Amt;
1417 if (match(V, m_APInt(C)))
1418 return *C;
1419 Value *L, *R;
1420 if (match(V, m_Add(m_Value(L), m_Value(R))) ||
1421 match(V, m_Or(m_Value(L), m_Value(R))) ||
1422 match(V, m_Xor(m_Value(L), m_Value(R))))
1423 return getScalarMaxValue(L, Depth + 1)
1425 if (match(V, m_NUWSub(m_Value(L), m_Value(R))))
1426 return getScalarMaxValue(L, Depth + 1);
1427 if (match(V, m_Mul(m_Value(L), m_Value(R))))
1428 return getScalarMaxValue(L, Depth + 1)
1430 if (match(V, m_And(m_Value(L), m_Value(R))))
1431 return APIntOps::umin(getScalarMaxValue(L, Depth + 1),
1432 getScalarMaxValue(R, Depth + 1));
1433 if (match(V, m_LShr(m_Value(L), m_APInt(Amt))) && Amt->ult(BitWidth))
1434 return getScalarMaxValue(L, Depth + 1).lshr(*Amt);
1435 if (match(V, m_Shl(m_Value(L), m_APInt(Amt))) && Amt->ult(BitWidth)) {
1436 APInt LMax = getScalarMaxValue(L, Depth + 1);
1437 return LMax.getActiveBits() + Amt->getZExtValue() <= BitWidth
1438 ? LMax.shl(*Amt)
1439 : Unknown;
1440 }
1441 if (match(V, m_ZExt(m_Value(L))))
1442 return getScalarMaxValue(L, Depth + 1).zext(BitWidth);
1443 if (match(V, m_Trunc(m_Value(L)))) {
1444 APInt Max = getScalarMaxValue(L, Depth + 1);
1445 return Max.getActiveBits() <= BitWidth ? Max.trunc(BitWidth) : Unknown;
1446 }
1447 if (match(V, m_SExt(m_Value(L)))) {
1448 APInt Max = getScalarMaxValue(L, Depth + 1);
1449 return Max.isNonNegative() ? Max.zext(BitWidth) : Unknown;
1450 }
1451 Value *F;
1452 if (match(V, m_Select(m_Value(), m_Value(L), m_Value(F))))
1453 return APIntOps::umax(getScalarMaxValue(L, Depth + 1),
1454 getScalarMaxValue(F, Depth + 1));
1455 return Unknown;
1456}
1457
1458std::optional<BitPackInfo> computeBitPackInfo(unsigned BitWidth,
1459 ArrayRef<APInt> PossibleBits,
1460 ArrayRef<uint64_t> ShlAmts,
1461 ArrayRef<APInt> Masks) {
1462 unsigned NumElts = PossibleBits.size();
1463 BitPackInfo Info;
1464 Info.LShrAmts.assign(NumElts, 0);
1465 for (unsigned Idx : seq(NumElts)) {
1466 APInt Possible = PossibleBits[Idx].shl(ShlAmts[Idx]) & Masks[Idx];
1467 if (Possible.isZero())
1468 continue;
1469 unsigned Lo, W;
1470 if (!Possible.isShiftedMask(Lo, W))
1471 return std::nullopt;
1472 if (Info.FieldWidth == 0) {
1473 if (W % 8 != 0 || BitWidth % W != 0)
1474 return std::nullopt;
1475 Info.FieldWidth = W;
1476 Info.LaneOfField.assign(BitWidth / W, BitPackInfo::NoLane);
1477 }
1478 if (W != Info.FieldWidth || Lo % W != 0)
1479 return std::nullopt;
1480 unsigned Field = Lo / W;
1481 if (Info.LaneOfField[Field] != BitPackInfo::NoLane)
1482 return std::nullopt;
1483 Info.LaneOfField[Field] = Idx;
1484 Info.LShrAmts[Idx] = Lo - ShlAmts[Idx];
1485 }
1486 if (Info.FieldWidth == 0)
1487 return std::nullopt;
1488 return Info;
1489}
1490
1491SmallVector<int> getBitPackMask(const BitPackInfo &Info, unsigned NumBytes,
1492 unsigned NumElts, unsigned BytesPerLane) {
1493 unsigned BytesPerField = Info.FieldWidth / 8;
1494 SmallVector<int> Mask;
1495 for (unsigned J : seq(NumBytes)) {
1496 unsigned Lane = Info.LaneOfField[J / BytesPerField];
1497 Mask.push_back(Lane == BitPackInfo::NoLane
1498 ? (int)(NumElts * BytesPerLane)
1499 : (int)(Lane * BytesPerLane + J % BytesPerField));
1500 }
1501 return Mask;
1502}
1503
1505 Type *ResultTy, unsigned ShiftWidth, unsigned &NumInsts) {
1506 NumInsts = 0;
1507 auto *VecTy = cast<FixedVectorType>(X->getType());
1508 unsigned BitWidth = VecTy->getScalarSizeInBits();
1509 assert(BitWidth % 8 == 0 &&
1510 "The byte-multiple field width divides the result bit width.");
1511 unsigned NumElts = VecTy->getNumElements();
1512 Value *Y = X;
1513 if (ShiftWidth != BitWidth) {
1514 // Compacting a zext back to its source is free, use it directly.
1515 if (auto *Z = dyn_cast<ZExtInst>(X);
1516 Z && Z->getSrcTy()->getScalarSizeInBits() == ShiftWidth)
1517 Y = Z->getOperand(0);
1518 else {
1519 Y = Builder.CreateTrunc(
1520 Y, FixedVectorType::get(IntegerType::get(X->getContext(), ShiftWidth),
1521 NumElts));
1522 ++NumInsts;
1523 }
1524 }
1525 if (Info.needsShift()) {
1527 for (uint64_t A : Info.LShrAmts)
1528 Amts.push_back(
1529 ConstantInt::get(IntegerType::get(X->getContext(), ShiftWidth), A));
1530 Y = Builder.CreateLShr(Y, ConstantVector::get(Amts));
1531 ++NumInsts;
1532 }
1533 unsigned InBytes = NumElts * (ShiftWidth / 8);
1534 auto *ByteTy = FixedVectorType::get(Builder.getInt8Ty(), InBytes);
1536 Info, ResultTy->getScalarSizeInBits() / 8, NumElts, ShiftWidth / 8);
1537 // Fields in lane order, possibly reversed, are a truncation of the shifted
1538 // lanes. A reversal of byte fields is a bswap.
1539 bool IsReversed = equal(Info.LaneOfField, reverse(seq<unsigned>(NumElts)));
1540 if (IsReversed || equal(Info.LaneOfField, seq<unsigned>(NumElts))) {
1541 Value *Fields = Builder.CreateTrunc(
1542 Y, Y->getType()->getWithNewBitWidth(Info.FieldWidth));
1543 NumInsts += 1 + (Info.FieldWidth != ShiftWidth) + IsReversed;
1544 if (IsReversed && Info.FieldWidth == 8)
1545 return Builder.CreateUnaryIntrinsic(
1546 Intrinsic::bswap, Builder.CreateBitCast(Fields, ResultTy));
1547 if (IsReversed)
1548 Fields = Builder.CreateVectorReverse(Fields);
1549 return Builder.CreateBitCast(Fields, ResultTy);
1550 }
1551 Value *Packed = Builder.CreateShuffleVector(
1552 Builder.CreateBitCast(Y, ByteTy),
1553 is_contained(Info.LaneOfField, BitPackInfo::NoLane)
1554 ? Constant::getNullValue(ByteTy)
1555 : PoisonValue::get(ByteTy),
1556 Mask);
1557 NumInsts += 3;
1558 return Builder.CreateBitCast(Packed, ResultTy);
1559}
1560
1563 findDbgValues(&From, DVRs);
1564 auto *ExI = dyn_cast<Instruction>(&To);
1565 for (DbgVariableRecord *DVR : DVRs) {
1566 if (!DVR->isDbgValue())
1567 continue;
1568 Instruction *MarkedI = DVR->getInstruction();
1569 if (ExI && MarkedI->getParent() != ExI->getParent())
1570 continue;
1571 if (!ExI || ExI->comesBefore(MarkedI)) {
1572 DVR->replaceVariableLocationOp(&From, &To);
1573 continue;
1574 }
1575 DebugVariableAggregate Var(DVR);
1576 auto HasSameVar = [&](auto Records) {
1577 return any_of(filterDbgVars(Records),
1578 [&](const DbgVariableRecord &Other) {
1579 return DebugVariableAggregate(&Other) == Var;
1580 });
1581 };
1582 if (HasSameVar(make_range(std::next(DVR->getIterator()),
1583 MarkedI->getDbgRecordRange().end())) ||
1584 any_of(make_range(std::next(MarkedI->getIterator()),
1585 std::next(ExI->getIterator())),
1586 [&](const Instruction &I) {
1587 return HasSameVar(I.getDbgRecordRange());
1588 }))
1589 continue;
1590 DbgVariableRecord *NewDVR = DVR->clone();
1591 NewDVR->replaceVariableLocationOp(&From, &To);
1592 ExI->getParent()->insertDbgRecordAfter(NewDVR, ExI);
1593 }
1594}
1595
1597 const InsertElementInst *IE2) {
1598 if (IE1 == IE2)
1599 return false;
1600 const auto *I1 = IE1;
1601 const auto *I2 = IE2;
1602 const InsertElementInst *PrevI1;
1603 const InsertElementInst *PrevI2;
1604 unsigned Idx1 = *getElementIndex(IE1);
1605 unsigned Idx2 = *getElementIndex(IE2);
1606 do {
1607 if (I2 == IE1)
1608 return true;
1609 if (I1 == IE2)
1610 return false;
1611 PrevI1 = I1;
1612 PrevI2 = I2;
1613 if (I1 && (I1 == IE1 || I1->hasOneUse()) &&
1614 getElementIndex(I1).value_or(Idx2) != Idx2)
1615 I1 = dyn_cast<InsertElementInst>(I1->getOperand(0));
1616 if (I2 && ((I2 == IE2 || I2->hasOneUse())) &&
1617 getElementIndex(I2).value_or(Idx1) != Idx1)
1618 I2 = dyn_cast<InsertElementInst>(I2->getOperand(0));
1619 } while ((I1 && PrevI1 != I1) || (I2 && PrevI2 != I2));
1620 llvm_unreachable("Two different buildvectors not expected.");
1621}
1622
1624 if (DebugLoc DL = PN.getDebugLoc())
1625 return DL;
1626 return DebugLoc::getUnknown();
1627}
1628
1629std::optional<unsigned> getAggregateSize(Instruction *InsertInst) {
1630 if (auto *IE = dyn_cast<InsertElementInst>(InsertInst))
1631 return cast<FixedVectorType>(IE->getType())->getNumElements();
1632
1633 unsigned AggregateSize = 1;
1634 auto *IV = cast<InsertValueInst>(InsertInst);
1635 Type *CurrentType = IV->getType();
1636 do {
1637 if (auto *ST = dyn_cast<StructType>(CurrentType)) {
1638 for (auto *Elt : ST->elements())
1639 if (Elt != ST->getElementType(0)) // check homogeneity
1640 return std::nullopt;
1641 AggregateSize *= ST->getNumElements();
1642 CurrentType = ST->getElementType(0);
1643 } else if (auto *AT = dyn_cast<ArrayType>(CurrentType)) {
1644 AggregateSize *= AT->getNumElements();
1645 CurrentType = AT->getElementType();
1646 } else if (auto *VT = dyn_cast<FixedVectorType>(CurrentType)) {
1647 AggregateSize *= VT->getNumElements();
1648 return AggregateSize;
1649 } else if (CurrentType->isSingleValueType()) {
1650 return AggregateSize;
1651 } else {
1652 return std::nullopt;
1653 }
1654 } while (true);
1655}
1656
1658 assert(L && "Expected valid loop");
1659 auto IsLoopInvariant = [&](const Loop *L, ArrayRef<Value *> VL) {
1661 [L](Instruction *I) { return L->isLoopInvariant(I); });
1662 };
1663 while (L && IsLoopInvariant(L, VL))
1664 L = L->getParentLoop();
1665 return L;
1666}
1667
1669 unsigned LoopAwareTripCount) {
1670 if (LoopAwareTripCount == 0)
1671 return 1;
1672 unsigned Scale = SE.getSmallConstantTripCount(L);
1673 if (Scale == 0)
1674 Scale = getLoopEstimatedTripCount(const_cast<Loop *>(L)).value_or(0);
1675 if (Scale != 0) {
1676 // Multiple exiting blocks - choose the minimum between trip count (scale)
1677 // and LoopAwareTripCount, since the multiple exit loops can be terminated
1678 // early.
1679 if (!L->getExitingBlock())
1680 return std::min<unsigned>(LoopAwareTripCount, Scale);
1681 return Scale;
1682 }
1683 return LoopAwareTripCount;
1684}
1685
1688 function_ref<Value *(InsertElementInst *)> GetBaseOperand) {
1689 // Instructions must be from the same basic blocks.
1690 if (VU->getParent() != V->getParent())
1691 return false;
1692 // Checks if 2 insertelements are from the same buildvector.
1693 if (VU->getType() != V->getType())
1694 return false;
1695 // Multiple used inserts are separate nodes.
1696 if (!VU->hasOneUse() && !V->hasOneUse())
1697 return false;
1698 auto *IE1 = VU;
1699 auto *IE2 = V;
1700 std::optional<unsigned> Idx1 = getElementIndex(IE1);
1701 std::optional<unsigned> Idx2 = getElementIndex(IE2);
1702 if (Idx1 == std::nullopt || Idx2 == std::nullopt)
1703 return false;
1704 // Go through the vector operand of insertelement instructions trying to find
1705 // either VU as the original vector for IE2 or V as the original vector for
1706 // IE1.
1708 bool IsReusedIdx = false;
1709 do {
1710 if (IE2 == VU && !IE1)
1711 return VU->hasOneUse();
1712 if (IE1 == V && !IE2)
1713 return V->hasOneUse();
1714 if (IE1 && IE1 != V) {
1715 unsigned Idx1 = getElementIndex(IE1).value_or(*Idx2);
1716 IsReusedIdx |= ReusedIdx.test(Idx1);
1717 ReusedIdx.set(Idx1);
1718 if ((IE1 != VU && !IE1->hasOneUse()) || IsReusedIdx)
1719 IE1 = nullptr;
1720 else
1721 IE1 = dyn_cast_if_present<InsertElementInst>(GetBaseOperand(IE1));
1722 }
1723 if (IE2 && IE2 != VU) {
1724 unsigned Idx2 = getElementIndex(IE2).value_or(*Idx1);
1725 IsReusedIdx |= ReusedIdx.test(Idx2);
1726 ReusedIdx.set(Idx2);
1727 if ((IE2 != V && !IE2->hasOneUse()) || IsReusedIdx)
1728 IE2 = nullptr;
1729 else
1730 IE2 = dyn_cast_if_present<InsertElementInst>(GetBaseOperand(IE2));
1731 }
1732 } while (!IsReusedIdx && (IE1 || IE2));
1733 return false;
1734}
1735
1736} // namespace llvm::slpvectorizer
unsigned NumParts
const TargetLowering & TLI
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.
VectorType * getType() const
Overload to return most specific vector type.
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:150
iterator_range< use_iterator > uses()
Definition Value.h:382
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
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:307
template SmallBitVector isUndefVector< true >(const Value *, const SmallBitVector &)
Constant * getReassocIdentity(unsigned Opcode, Type *Ty, bool Negated)
Definition SLPUtils.cpp:51
Value * createInsertVector(IRBuilderBase &Builder, Value *Vec, Value *V, unsigned Index, function_ref< Value *(Value *, Value *, ArrayRef< int >)> Generator)
Creates subvector insert.
Definition SLPUtils.cpp:713
bool areAllOperandsNonInsts(Value *V)
Checks if the provided value does not require scheduling.
Definition SLPUtils.cpp:487
std::optional< unsigned > getElementIndex(const Value *Inst, unsigned Offset)
Definition SLPUtils.cpp:261
DebugLoc getDebugLocFromPHI(const PHINode &PN)
bool isBinOpIdentityConstant(const Value *V, unsigned Opcode, bool Negated)
Definition SLPUtils.cpp:58
bool doesInTreeUserNeedToExtract(Value *Scalar, Instruction *UserInst, TargetLibraryInfo *TLI, const TargetTransformInfo *TTI)
Definition SLPUtils.cpp:816
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:954
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:844
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:862
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:766
Intrinsic::ID getMaskedDivRemIntrinsic(unsigned Opcode)
bool isUsedOutsideBlock(Value *V)
Checks if the provided value does not require scheduling.
Definition SLPUtils.cpp:498
bool doesNotNeedToSchedule(ArrayRef< Value * > VL)
Checks if the specified array of instructions does not require scheduling.
Definition SLPUtils.cpp:515
std::optional< unsigned > getInsertExtractIndex(const Value *Inst, unsigned Offset)
Definition SLPUtils.cpp:454
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:340
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:915
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:447
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:425
bool allSameOpcode(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:289
bool isSplat(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:172
unsigned getNumElements(Type *Ty)
Definition SLPUtils.cpp:117
std::string shortBundleName(ArrayRef< Value * > VL, int Idx)
Print a short descriptor of the instruction bundle suitable for debug output.
Definition SLPUtils.cpp:134
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:125
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:233
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:902
TargetTransformInfo::TargetCostKind getSLPCostKind(const Function *F)
bool isReverseOrder(ArrayRef< unsigned > Order)
Check if Order represents reverse order.
Definition SLPUtils.cpp:404
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:922
void transformScalarShuffleIndiciesToVector(unsigned VecTyNumElements, SmallVectorImpl< int > &Mask)
Definition SLPUtils.cpp:520
bool areTwoInsertFromSameBuildVector(InsertElementInst *VU, InsertElementInst *V, function_ref< Value *(InsertElementInst *)> GetBaseOperand)
Check if two insertelement instructions are from the same buildvector.
SmallVector< int > calculateShufflevectorMask(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:575
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:749
bool isCommutative(const Instruction *I, const Value *ValWithUses, bool IsCopyable)
Definition SLPUtils.cpp:195
template SmallBitVector isUndefVector< false >(const Value *, const SmallBitVector &)
unsigned getNumberOfPotentiallyCommutativeOps(Instruction *I)
Definition SLPUtils.cpp:251
bool allConstant(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:166
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:331
bool allSameBlock(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:144
bool isReassocChainLink(const Instruction *I)
Definition SLPUtils.cpp:89
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:186
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:615
UseMask
Specifies the way the mask should be analyzed for undefs/poisonous elements in the shuffle mask.
Definition SLPUtils.h:313
@ SecondArg
The mask is expected to be for permutation of 2 vectors, check for the mask elements for the second a...
Definition SLPUtils.h:317
@ UndefsAsMask
Consider undef mask elements (-1) as placeholders for future shuffle elements and mark them as ones a...
Definition SLPUtils.h:320
@ FirstArg
The mask is expected to be for permutation of 1-2 vectors, check for the mask elements for the first ...
Definition SLPUtils.h:314
void reorderOrder(SmallVectorImpl< unsigned > &Order, ArrayRef< int > Mask, bool BottomOrder)
Reorders the given Order according to the given Mask.
Definition SLPUtils.cpp:360
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:350
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:852
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:69
bool isUndefTolerantBinOp(const Value *V)
Definition SLPUtils.cpp:63
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:535
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:78
bool isVectorLikeInstWithConstOps(Value *V)
Checks if V is one of vector-like instructions, i.e.
Definition SLPUtils.cpp:97
bool doesNotNeedToBeScheduled(Value *V)
Checks if the specified value does not require scheduling.
Definition SLPUtils.cpp:511
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:129
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:413
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:742
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
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
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:499
static constexpr unsigned NoLane
Definition SLPUtils.h:500
SmallVector< uint64_t, 8 > LShrAmts
Per-lane right-shift amounts bringing the field content to the low bits.
Definition SLPUtils.h:505