LLVM 24.0.0git
BasicTTIImpl.h
Go to the documentation of this file.
1//===- BasicTTIImpl.h -------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// This file provides a helper that implements much of the TTI interface in
11/// terms of the target-independent code generator and TargetLowering
12/// interfaces.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CODEGEN_BASICTTIIMPL_H
17#define LLVM_CODEGEN_BASICTTIIMPL_H
18
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/BitVector.h"
21#include "llvm/ADT/STLExtras.h"
35#include "llvm/IR/BasicBlock.h"
36#include "llvm/IR/Constant.h"
37#include "llvm/IR/Constants.h"
38#include "llvm/IR/DataLayout.h"
40#include "llvm/IR/InstrTypes.h"
41#include "llvm/IR/Instruction.h"
43#include "llvm/IR/Intrinsics.h"
44#include "llvm/IR/Operator.h"
45#include "llvm/IR/Type.h"
46#include "llvm/IR/Value.h"
55#include <algorithm>
56#include <cassert>
57#include <cstdint>
58#include <limits>
59#include <optional>
60#include <utility>
61
62namespace llvm {
63
64class Function;
65class GlobalValue;
66class LLVMContext;
67class ScalarEvolution;
68class SCEV;
69class TargetMachine;
70
71/// Returns -partial-unrolling-threshold if specified.
72LLVM_ABI std::optional<unsigned> getPartialUnrollingThreshold();
73
74/// Base class which can be used to help build a TTI implementation.
75///
76/// This class provides as much implementation of the TTI interface as is
77/// possible using the target independent parts of the code generator.
78///
79/// In order to subclass it, your class must implement a getST() method to
80/// return the subtarget, and a getTLI() method to return the target lowering.
81/// We need these methods implemented in the derived class so that this class
82/// doesn't have to duplicate storage for them.
83template <typename T>
85private:
87 using TTI = TargetTransformInfo;
88
89 /// Helper function to access this as a T.
90 const T *thisT() const { return static_cast<const T *>(this); }
91
92 /// Estimate a cost of Broadcast as an extract and sequence of insert
93 /// operations.
95 getBroadcastShuffleOverhead(FixedVectorType *VTy,
98 // Broadcast cost is equal to the cost of extracting the zero'th element
99 // plus the cost of inserting it into every element of the result vector.
100 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, VTy,
101 CostKind, 0, nullptr, nullptr);
102
103 for (int i = 0, e = VTy->getNumElements(); i < e; ++i) {
104 Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, VTy,
105 CostKind, i, nullptr, nullptr);
106 }
107 return Cost;
108 }
109
110 /// Estimate a cost of shuffle as a sequence of extract and insert
111 /// operations.
113 getPermuteShuffleOverhead(FixedVectorType *VTy,
116 // Shuffle cost is equal to the cost of extracting element from its argument
117 // plus the cost of inserting them onto the result vector.
118
119 // e.g. <4 x float> has a mask of <0,5,2,7> i.e we need to extract from
120 // index 0 of first vector, index 1 of second vector,index 2 of first
121 // vector and finally index 3 of second vector and insert them at index
122 // <0,1,2,3> of result vector.
123 for (int i = 0, e = VTy->getNumElements(); i < e; ++i) {
124 Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, VTy,
125 CostKind, i, nullptr, nullptr);
126 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, VTy,
127 CostKind, i, nullptr, nullptr);
128 }
129 return Cost;
130 }
131
132 /// Estimate a cost of subvector extraction as a sequence of extract and
133 /// insert operations.
134 InstructionCost getExtractSubvectorOverhead(VectorType *VTy,
136 int Index,
137 FixedVectorType *SubVTy) const {
138 assert(VTy && SubVTy &&
139 "Can only extract subvectors from vectors");
140 int NumSubElts = SubVTy->getNumElements();
142 (Index + NumSubElts) <=
143 (int)cast<FixedVectorType>(VTy)->getNumElements()) &&
144 "SK_ExtractSubvector index out of range");
145
147 // Subvector extraction cost is equal to the cost of extracting element from
148 // the source type plus the cost of inserting them into the result vector
149 // type.
150 for (int i = 0; i != NumSubElts; ++i) {
151 Cost +=
152 thisT()->getVectorInstrCost(Instruction::ExtractElement, VTy,
153 CostKind, i + Index, nullptr, nullptr);
154 Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, SubVTy,
155 CostKind, i, nullptr, nullptr);
156 }
157 return Cost;
158 }
159
160 /// Estimate a cost of subvector insertion as a sequence of extract and
161 /// insert operations.
162 InstructionCost getInsertSubvectorOverhead(VectorType *VTy,
164 int Index,
165 FixedVectorType *SubVTy) const {
166 assert(VTy && SubVTy &&
167 "Can only insert subvectors into vectors");
168 int NumSubElts = SubVTy->getNumElements();
170 (Index + NumSubElts) <=
171 (int)cast<FixedVectorType>(VTy)->getNumElements()) &&
172 "SK_InsertSubvector index out of range");
173
175 // Subvector insertion cost is equal to the cost of extracting element from
176 // the source type plus the cost of inserting them into the result vector
177 // type.
178 for (int i = 0; i != NumSubElts; ++i) {
179 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, SubVTy,
180 CostKind, i, nullptr, nullptr);
181 Cost +=
182 thisT()->getVectorInstrCost(Instruction::InsertElement, VTy, CostKind,
183 i + Index, nullptr, nullptr);
184 }
185 return Cost;
186 }
187
188 /// Local query method delegates up to T which *must* implement this!
189 const TargetSubtargetInfo *getST() const {
190 return static_cast<const T *>(this)->getST();
191 }
192
193 /// Local query method delegates up to T which *must* implement this!
194 const TargetLoweringBase *getTLI() const {
195 return static_cast<const T *>(this)->getTLI();
196 }
197
198 static ISD::MemIndexedMode getISDIndexedMode(TTI::MemIndexedMode M) {
199 switch (M) {
201 return ISD::UNINDEXED;
202 case TTI::MIM_PreInc:
203 return ISD::PRE_INC;
204 case TTI::MIM_PreDec:
205 return ISD::PRE_DEC;
206 case TTI::MIM_PostInc:
207 return ISD::POST_INC;
208 case TTI::MIM_PostDec:
209 return ISD::POST_DEC;
210 }
211 llvm_unreachable("Unexpected MemIndexedMode");
212 }
213
214 InstructionCost getCommonMaskedMemoryOpCost(unsigned Opcode, Type *DataTy,
215 Align Alignment,
216 bool VariableMask,
217 bool IsGatherScatter,
219 unsigned AddressSpace = 0) const {
220 // We cannot scalarize scalable vectors, so return Invalid.
221 if (isa<ScalableVectorType>(DataTy))
223
224 auto *VT = cast<FixedVectorType>(DataTy);
225 unsigned VF = VT->getNumElements();
226
227 // Assume the target does not have support for gather/scatter operations
228 // and provide a rough estimate.
229 //
230 // First, compute the cost of the individual memory operations.
231 InstructionCost AddrExtractCost =
232 IsGatherScatter ? getScalarizationOverhead(
234 PointerType::get(VT->getContext(), 0), VF),
235 /*Insert=*/false, /*Extract=*/true, CostKind)
236 : 0;
237
238 // The cost of the scalar loads/stores.
239 InstructionCost MemoryOpCost =
240 VF * thisT()->getMemoryOpCost(Opcode, VT->getElementType(), Alignment,
242
243 // Next, compute the cost of packing the result in a vector.
244 InstructionCost PackingCost =
245 getScalarizationOverhead(VT, Opcode != Instruction::Store,
246 Opcode == Instruction::Store, CostKind);
247
248 InstructionCost ConditionalCost = 0;
249 if (VariableMask) {
250 // Compute the cost of conditionally executing the memory operations with
251 // variable masks. This includes extracting the individual conditions, a
252 // branches and PHIs to combine the results.
253 // NOTE: Estimating the cost of conditionally executing the memory
254 // operations accurately is quite difficult and the current solution
255 // provides a very rough estimate only.
256 ConditionalCost =
259 /*Insert=*/false, /*Extract=*/true, CostKind) +
260 VF * (thisT()->getCFInstrCost(Instruction::CondBr, CostKind) +
261 thisT()->getCFInstrCost(Instruction::PHI, CostKind));
262 }
263
264 return AddrExtractCost + MemoryOpCost + PackingCost + ConditionalCost;
265 }
266
267 /// Checks if the provided mask \p is a splat mask, i.e. it contains only -1
268 /// or same non -1 index value and this index value contained at least twice.
269 /// So, mask <0, -1,-1, -1> is not considered splat (it is just identity),
270 /// same for <-1, 0, -1, -1> (just a slide), while <2, -1, 2, -1> is a splat
271 /// with \p Index=2.
272 static bool isSplatMask(ArrayRef<int> Mask, unsigned NumSrcElts, int &Index) {
273 // Check that the broadcast index meets at least twice.
274 bool IsCompared = false;
275 if (int SplatIdx = PoisonMaskElem;
276 all_of(enumerate(Mask), [&](const auto &P) {
277 if (P.value() == PoisonMaskElem)
278 return P.index() != Mask.size() - 1 || IsCompared;
279 if (static_cast<unsigned>(P.value()) >= NumSrcElts * 2)
280 return false;
281 if (SplatIdx == PoisonMaskElem) {
282 SplatIdx = P.value();
283 return P.index() != Mask.size() - 1;
284 }
285 IsCompared = true;
286 return SplatIdx == P.value();
287 })) {
288 Index = SplatIdx;
289 return true;
290 }
291 return false;
292 }
293
294 /// Several intrinsics that return structs (including llvm.sincos[pi] and
295 /// llvm.modf) can be lowered to a vector library call (for certain VFs). The
296 /// vector library functions correspond to the scalar calls (e.g. sincos or
297 /// modf), which unlike the intrinsic return values via output pointers. This
298 /// helper checks if a vector call exists for the given intrinsic, and returns
299 /// the cost, which includes the cost of the mask (if required), and the loads
300 /// for values returned via output pointers. \p LC is the scalar libcall and
301 /// \p CallRetElementIndex (optional) is the struct element which is mapped to
302 /// the call return value. If std::nullopt is returned, then no vector library
303 /// call is available, so the intrinsic should be assigned the default cost
304 /// (e.g. scalarization).
305 std::optional<InstructionCost> getMultipleResultIntrinsicVectorLibCallCost(
307 std::optional<unsigned> CallRetElementIndex = {}) const {
308 Type *RetTy = ICA.getReturnType();
309 // Vector variants of the intrinsic can be mapped to a vector library call.
310 if (!isa<StructType>(RetTy) ||
312 return std::nullopt;
313
314 Type *Ty = getContainedTypes(RetTy).front();
315 EVT VT = getTLI()->getValueType(DL, Ty);
316
317 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
318
319 switch (ICA.getID()) {
320 case Intrinsic::modf:
321 LC = RTLIB::getMODF(VT);
322 break;
323 case Intrinsic::sincospi:
324 LC = RTLIB::getSINCOSPI(VT);
325 break;
326 case Intrinsic::sincos:
327 LC = RTLIB::getSINCOS(VT);
328 break;
329 default:
330 return std::nullopt;
331 }
332
333 // Find associated libcall.
334 RTLIB::LibcallImpl LibcallImpl = getTLI()->getLibcallImpl(LC);
335 if (LibcallImpl == RTLIB::Unsupported)
336 return std::nullopt;
337
338 LLVMContext &Ctx = RetTy->getContext();
339
340 // Cost the call + mask.
341 auto Cost =
342 thisT()->getCallInstrCost(nullptr, RetTy, ICA.getArgTypes(), CostKind);
343
346 auto VecTy = VectorType::get(IntegerType::getInt1Ty(Ctx), VF);
347 Cost += thisT()->getShuffleCost(TargetTransformInfo::SK_Broadcast, VecTy,
348 VecTy, CostKind, {}, 0, nullptr, {});
349 }
350
351 // Lowering to a library call (with output pointers) may require us to emit
352 // reloads for the results.
353 for (auto [Idx, VectorTy] : enumerate(getContainedTypes(RetTy))) {
354 if (Idx == CallRetElementIndex)
355 continue;
356 Cost += thisT()->getMemoryOpCost(
357 Instruction::Load, VectorTy,
358 thisT()->getDataLayout().getABITypeAlign(VectorTy), 0, CostKind);
359 }
360 return Cost;
361 }
362
363 /// Filter out constant and duplicated entries in \p Ops and return a vector
364 /// containing the types from \p Tys corresponding to the remaining operands.
366 filterConstantAndDuplicatedOperands(ArrayRef<const Value *> Ops,
367 ArrayRef<Type *> Tys) {
368 SmallPtrSet<const Value *, 4> UniqueOperands;
369 SmallVector<Type *, 4> FilteredTys;
370 for (const auto &[Op, Ty] : zip_equal(Ops, Tys)) {
371 if (isa<Constant>(Op) || !UniqueOperands.insert(Op).second)
372 continue;
373 FilteredTys.push_back(Ty);
374 }
375 return FilteredTys;
376 }
377
378protected:
379 explicit BasicTTIImplBase(const TargetMachine *TM, const DataLayout &DL)
380 : BaseT(DL) {}
381 ~BasicTTIImplBase() override = default;
382
385
386public:
387 /// \name Scalar TTI Implementations
388 /// @{
390 unsigned AddressSpace, Align Alignment,
391 unsigned *Fast) const override {
392 EVT E = EVT::getIntegerVT(Context, BitWidth);
393 return getTLI()->allowsMisalignedMemoryAccesses(
395 }
396
397 bool areInlineCompatible(const Function *Caller,
398 const Function *Callee) const override {
399 const TargetMachine &TM = getTLI()->getTargetMachine();
400
401 const TargetSubtargetInfo *CallerSTI = TM.getSubtargetImpl(*Caller);
402 const TargetSubtargetInfo *CalleeSTI = TM.getSubtargetImpl(*Callee);
403 FeatureBitset InlineIgnoreFeatures = CallerSTI->getInlineIgnoreFeatures();
404 FeatureBitset InlineInverseFeatures = CallerSTI->getInlineInverseFeatures();
405 FeatureBitset InlineMustMatchFeatures =
406 CallerSTI->getInlineMustMatchFeatures();
407
408 FeatureBitset CallerBits =
409 (CallerSTI->getFeatureBits() ^ InlineInverseFeatures) &
410 ~InlineIgnoreFeatures;
411 FeatureBitset CalleeBits =
412 (CalleeSTI->getFeatureBits() ^ InlineInverseFeatures) &
413 ~InlineIgnoreFeatures;
414
415 if ((CallerBits & InlineMustMatchFeatures) !=
416 (CalleeBits & InlineMustMatchFeatures))
417 return false;
418
419 // Inline a callee if its target-features are a subset of the callers
420 // target-features.
421 return (CallerBits & CalleeBits) == CalleeBits;
422 }
423
424 bool hasBranchDivergence(const Function *F = nullptr) const override {
425 return false;
426 }
427
428 bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const override {
429 return false;
430 }
431
432 bool addrspacesMayAlias(unsigned AS0, unsigned AS1) const override {
433 return true;
434 }
435
436 unsigned getFlatAddressSpace() const override {
437 // Return an invalid address space.
438 return -1;
439 }
440
442 Intrinsic::ID IID) const override {
443 return false;
444 }
445
446 bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const override {
447 return getTLI()->getTargetMachine().isNoopAddrSpaceCast(DL, FromAS, ToAS);
448 }
449
450 unsigned getAssumedAddrSpace(const Value *V) const override {
451 return getTLI()->getTargetMachine().getAssumedAddrSpace(V);
452 }
453
454 std::pair<const Value *, unsigned>
455 getPredicatedAddrSpace(const Value *V) const override {
456 return getTLI()->getTargetMachine().getPredicatedAddrSpace(V);
457 }
458
460 Value *NewV) const override {
461 return nullptr;
462 }
463
464 bool isLegalAddImmediate(int64_t imm) const override {
465 return getTLI()->isLegalAddImmediate(imm);
466 }
467
468 bool isLegalAddScalableImmediate(int64_t Imm) const override {
469 return getTLI()->isLegalAddScalableImmediate(Imm);
470 }
471
472 bool isLegalICmpImmediate(int64_t imm) const override {
473 return getTLI()->isLegalICmpImmediate(imm);
474 }
475
476 bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
477 bool HasBaseReg, int64_t Scale, unsigned AddrSpace,
478 Instruction *I = nullptr,
479 int64_t ScalableOffset = 0) const override {
481 AM.BaseGV = BaseGV;
482 AM.BaseOffs = BaseOffset;
483 AM.HasBaseReg = HasBaseReg;
484 AM.Scale = Scale;
485 AM.ScalableOffset = ScalableOffset;
486 return getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace, I);
487 }
488
489 int64_t getPreferredLargeGEPBaseOffset(int64_t MinOffset, int64_t MaxOffset) {
490 return getTLI()->getPreferredLargeGEPBaseOffset(MinOffset, MaxOffset);
491 }
492
493 unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy,
494 Align Alignment,
495 unsigned AddrSpace) const override {
496 auto &&IsSupportedByTarget = [this, ScalarMemTy, ScalarValTy, Alignment,
497 AddrSpace](unsigned VF) {
498 auto *SrcTy = FixedVectorType::get(ScalarMemTy, VF / 2);
499 EVT VT = getTLI()->getValueType(DL, SrcTy);
500 if (getTLI()->isOperationLegal(ISD::STORE, VT) ||
501 getTLI()->isOperationCustom(ISD::STORE, VT))
502 return true;
503
504 EVT ValVT =
505 getTLI()->getValueType(DL, FixedVectorType::get(ScalarValTy, VF / 2));
506 EVT LegalizedVT =
507 getTLI()->getTypeToTransformTo(ScalarMemTy->getContext(), VT);
508 return getTLI()->isTruncStoreLegal(LegalizedVT, ValVT, Alignment,
509 AddrSpace);
510 };
511 while (VF > 2 && IsSupportedByTarget(VF))
512 VF /= 2;
513 return VF;
514 }
515
516 bool isIndexedLoadLegal(TTI::MemIndexedMode M, Type *Ty) const override {
517 EVT VT = getTLI()->getValueType(DL, Ty, /*AllowUnknown=*/true);
518 return getTLI()->isIndexedLoadLegal(getISDIndexedMode(M), VT);
519 }
520
521 bool isIndexedStoreLegal(TTI::MemIndexedMode M, Type *Ty) const override {
522 EVT VT = getTLI()->getValueType(DL, Ty, /*AllowUnknown=*/true);
523 return getTLI()->isIndexedStoreLegal(getISDIndexedMode(M), VT);
524 }
525
527 const TTI::LSRCost &C2) const override {
529 }
530
534
538
542
544 StackOffset BaseOffset, bool HasBaseReg,
545 int64_t Scale,
546 unsigned AddrSpace) const override {
548 AM.BaseGV = BaseGV;
549 AM.BaseOffs = BaseOffset.getFixed();
550 AM.HasBaseReg = HasBaseReg;
551 AM.Scale = Scale;
552 AM.ScalableOffset = BaseOffset.getScalable();
553 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
554 return 0;
556 }
557
558 bool isTruncateFree(Type *Ty1, Type *Ty2) const override {
559 return getTLI()->isTruncateFree(Ty1, Ty2);
560 }
561
562 bool isProfitableToHoist(Instruction *I) const override {
563 return getTLI()->isProfitableToHoist(I);
564 }
565
566 bool useAA() const override { return getST()->useAA(); }
567
568 bool isTypeLegal(Type *Ty) const override {
569 EVT VT = getTLI()->getValueType(DL, Ty, /*AllowUnknown=*/true);
570 return getTLI()->isTypeLegal(VT);
571 }
572
573 unsigned getRegUsageForType(Type *Ty) const override {
574 EVT ETy = getTLI()->getValueType(DL, Ty);
575 return getTLI()->getNumRegisters(Ty->getContext(), ETy);
576 }
577
578 InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr,
581 Type *AccessType) const override {
582 return BaseT::getGEPCost(PointeeType, Ptr, Operands, CostKind, AccessType);
583 }
584
586 const SwitchInst &SI, unsigned &JumpTableSize, ProfileSummaryInfo *PSI,
587 BlockFrequencyInfo *BFI) const override {
588 /// Try to find the estimated number of clusters. Note that the number of
589 /// clusters identified in this function could be different from the actual
590 /// numbers found in lowering. This function ignore switches that are
591 /// lowered with a mix of jump table / bit test / BTree. This function was
592 /// initially intended to be used when estimating the cost of switch in
593 /// inline cost heuristic, but it's a generic cost model to be used in other
594 /// places (e.g., in loop unrolling).
595 unsigned N = SI.getNumCases();
596 const TargetLoweringBase *TLI = getTLI();
597 const DataLayout &DL = this->getDataLayout();
598
599 JumpTableSize = 0;
600 bool IsJTAllowed = TLI->areJTsAllowed(SI.getParent()->getParent());
601
602 // Early exit if both a jump table and bit test are not allowed.
603 if (N < 1 || (!IsJTAllowed && DL.getIndexSizeInBits(0u) < N))
604 return N;
605
606 APInt MaxCaseVal = SI.case_begin()->getCaseValue()->getValue();
607 APInt MinCaseVal = MaxCaseVal;
608 for (auto CI : SI.cases()) {
609 const APInt &CaseVal = CI.getCaseValue()->getValue();
610 if (CaseVal.sgt(MaxCaseVal))
611 MaxCaseVal = CaseVal;
612 if (CaseVal.slt(MinCaseVal))
613 MinCaseVal = CaseVal;
614 }
615
616 // Check if suitable for a bit test
617 if (N <= DL.getIndexSizeInBits(0u)) {
619 for (auto I : SI.cases()) {
620 const BasicBlock *BB = I.getCaseSuccessor();
621 ++DestMap[BB];
622 }
623
624 if (TLI->isSuitableForBitTests(DestMap, MinCaseVal, MaxCaseVal, DL))
625 return 1;
626 }
627
628 // Check if suitable for a jump table.
629 if (IsJTAllowed) {
630 if (N < 2 || N < TLI->getMinimumJumpTableEntries())
631 return N;
633 (MaxCaseVal - MinCaseVal)
634 .getLimitedValue(std::numeric_limits<uint64_t>::max() - 1) + 1;
635 // Check whether a range of clusters is dense enough for a jump table
636 if (TLI->isSuitableForJumpTable(&SI, N, Range, PSI, BFI)) {
637 JumpTableSize = Range;
638 return 1;
639 }
640 }
641 return N;
642 }
643
644 bool shouldBuildLookupTables() const override {
645 const TargetLoweringBase *TLI = getTLI();
646 return TLI->isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) ||
647 TLI->isOperationLegalOrCustom(ISD::BRIND, MVT::Other);
648 }
649
650 bool shouldBuildRelLookupTables() const override {
651 const TargetMachine &TM = getTLI()->getTargetMachine();
652 // If non-PIC mode, do not generate a relative lookup table.
653 if (!TM.isPositionIndependent())
654 return false;
655
656 /// Relative lookup table entries consist of 32-bit offsets.
657 /// Do not generate relative lookup tables for large code models
658 /// in 64-bit achitectures where 32-bit offsets might not be enough.
659 if (TM.getCodeModel() == CodeModel::Medium ||
661 return false;
662
663 const Triple &TargetTriple = TM.getTargetTriple();
664 if (!TargetTriple.isArch64Bit())
665 return false;
666
667 // TODO: Triggers issues on aarch64 on darwin, so temporarily disable it
668 // there.
669 if (TargetTriple.getArch() == Triple::aarch64 && TargetTriple.isOSDarwin())
670 return false;
671
672 return true;
673 }
674
675 bool haveFastSqrt(Type *Ty) const override {
676 const TargetLoweringBase *TLI = getTLI();
677 EVT VT = TLI->getValueType(DL, Ty);
678 return TLI->isTypeLegal(VT) &&
680 }
681
682 bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override { return true; }
683
684 InstructionCost getFPOpCost(Type *Ty) const override {
685 // Check whether FADD is available, as a proxy for floating-point in
686 // general.
687 const TargetLoweringBase *TLI = getTLI();
688 EVT VT = TLI->getValueType(DL, Ty);
692 }
693
695 const Function &Fn) const override {
696 switch (Inst.getOpcode()) {
697 default:
698 break;
699 case Instruction::SDiv:
700 case Instruction::SRem:
701 case Instruction::UDiv:
702 case Instruction::URem: {
703 if (!isa<ConstantInt>(Inst.getOperand(1)))
704 return false;
705 EVT VT = getTLI()->getValueType(DL, Inst.getType());
706 return !getTLI()->isIntDivCheap(VT, Fn.getAttributes());
707 }
708 };
709
710 return false;
711 }
712
713 unsigned getInliningThresholdMultiplier() const override { return 1; }
714 unsigned adjustInliningThreshold(const CallBase *CB) const override {
715 return 0;
716 }
717 unsigned getCallerAllocaCost(const CallBase *CB,
718 const AllocaInst *AI) const override {
719 return 0;
720 }
721
722 int getInlinerVectorBonusPercent() const override { return 150; }
723
726 OptimizationRemarkEmitter *ORE) const override {
727 // This unrolling functionality is target independent, but to provide some
728 // motivation for its intended use, for x86:
729
730 // According to the Intel 64 and IA-32 Architectures Optimization Reference
731 // Manual, Intel Core models and later have a loop stream detector (and
732 // associated uop queue) that can benefit from partial unrolling.
733 // The relevant requirements are:
734 // - The loop must have no more than 4 (8 for Nehalem and later) branches
735 // taken, and none of them may be calls.
736 // - The loop can have no more than 18 (28 for Nehalem and later) uops.
737
738 // According to the Software Optimization Guide for AMD Family 15h
739 // Processors, models 30h-4fh (Steamroller and later) have a loop predictor
740 // and loop buffer which can benefit from partial unrolling.
741 // The relevant requirements are:
742 // - The loop must have fewer than 16 branches
743 // - The loop must have less than 40 uops in all executed loop branches
744
745 // The number of taken branches in a loop is hard to estimate here, and
746 // benchmarking has revealed that it is better not to be conservative when
747 // estimating the branch count. As a result, we'll ignore the branch limits
748 // until someone finds a case where it matters in practice.
749
750 unsigned MaxOps;
751 const TargetSubtargetInfo *ST = getST();
752 if (std::optional<unsigned> Threshold = getPartialUnrollingThreshold())
753 MaxOps = *Threshold;
754 else if (ST->getSchedModel().LoopMicroOpBufferSize > 0)
755 MaxOps = ST->getSchedModel().LoopMicroOpBufferSize;
756 else
757 return;
758
759 // Scan the loop: don't unroll loops with calls.
760 for (BasicBlock *BB : L->blocks()) {
761 for (Instruction &I : *BB) {
762 if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
763 if (const Function *F = cast<CallBase>(I).getCalledFunction()) {
764 if (!thisT()->isLoweredToCall(F))
765 continue;
766 }
767
768 if (ORE) {
769 ORE->emit([&]() {
770 return OptimizationRemark("TTI", "DontUnroll", L->getStartLoc(),
771 L->getHeader())
772 << "advising against unrolling the loop because it "
773 "contains a "
774 << ore::NV("Call", &I);
775 });
776 }
777 return;
778 }
779 }
780 }
781
782 // Enable runtime and partial unrolling up to the specified size.
783 // Enable using trip count upper bound to unroll loops.
784 UP.Partial = UP.Runtime = UP.UpperBound = true;
785 UP.PartialThreshold = MaxOps;
786
787 // Avoid unrolling when optimizing for size.
788 UP.OptSizeThreshold = 0;
790
791 // Set number of instructions optimized when "back edge"
792 // becomes "fall through" to default value of 2.
793 UP.BEInsns = 2;
794 }
795
797 TTI::PeelingPreferences &PP) const override {
798 PP.PeelCount = 0;
799 PP.AllowPeeling = true;
800 PP.AllowLoopNestsPeeling = false;
801 PP.PeelProfiledIterations = true;
802 }
803
806 HardwareLoopInfo &HWLoopInfo) const override {
807 return BaseT::isHardwareLoopProfitable(L, SE, AC, LibInfo, HWLoopInfo);
808 }
809
810 unsigned getEpilogueVectorizationMinVF() const override {
812 }
813
817
821
822 std::optional<Instruction *>
825 }
826
827 std::optional<Value *>
829 APInt DemandedMask, KnownBits &Known,
830 bool &KnownBitsComputed) const override {
831 return BaseT::simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
832 KnownBitsComputed);
833 }
834
836 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
837 APInt &UndefElts2, APInt &UndefElts3,
838 std::function<void(Instruction *, unsigned, APInt, APInt &)>
839 SimplifyAndSetOp) const override {
841 IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
842 SimplifyAndSetOp);
843 }
844
846 return getST()->getMispredictionPenalty();
847 }
848
849 std::optional<unsigned>
851 return std::optional<unsigned>(
852 getST()->getCacheSize(static_cast<unsigned>(Level)));
853 }
854
855 std::optional<unsigned>
857 std::optional<unsigned> TargetResult =
858 getST()->getCacheAssociativity(static_cast<unsigned>(Level));
859
860 if (TargetResult)
861 return TargetResult;
862
863 return BaseT::getCacheAssociativity(Level);
864 }
865
866 unsigned getCacheLineSize() const override {
867 return getST()->getCacheLineSize();
868 }
869
870 unsigned getPrefetchDistance() const override {
871 return getST()->getPrefetchDistance();
872 }
873
874 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
875 unsigned NumStridedMemAccesses,
876 unsigned NumPrefetches,
877 bool HasCall) const override {
878 return getST()->getMinPrefetchStride(NumMemAccesses, NumStridedMemAccesses,
879 NumPrefetches, HasCall);
880 }
881
882 unsigned getMaxPrefetchIterationsAhead() const override {
883 return getST()->getMaxPrefetchIterationsAhead();
884 }
885
886 bool enableWritePrefetching() const override {
887 return getST()->enableWritePrefetching();
888 }
889
890 bool shouldPrefetchAddressSpace(unsigned AS) const override {
891 return getST()->shouldPrefetchAddressSpace(AS);
892 }
893
894 /// @}
895
896 /// \name Vector TTI Implementations
897 /// @{
898
903
904 std::optional<unsigned> getVScaleForTuning() const override {
905 return std::nullopt;
906 }
907
908 /// Estimate the overhead of scalarizing an instruction. Insert and Extract
909 /// are set if the demanded result elements need to be inserted and/or
910 /// extracted from vectors.
912 getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts,
913 bool Insert, bool Extract,
915 bool ForPoisonSrc = true, ArrayRef<Value *> VL = {},
917 TTI::VectorInstrContext::None) const override {
918 /// FIXME: a bitfield is not a reasonable abstraction for talking about
919 /// which elements are needed from a scalable vector
920 if (isa<ScalableVectorType>(InTy))
922 auto *Ty = cast<FixedVectorType>(InTy);
923
924 assert(DemandedElts.getBitWidth() == Ty->getNumElements() &&
925 (VL.empty() || VL.size() == Ty->getNumElements()) &&
926 "Vector size mismatch");
927
929
930 for (int i = 0, e = Ty->getNumElements(); i < e; ++i) {
931 if (!DemandedElts[i])
932 continue;
933 if (Insert) {
934 Value *InsertedVal = VL.empty() ? nullptr : VL[i];
935 Cost +=
936 thisT()->getVectorInstrCost(Instruction::InsertElement, Ty,
937 CostKind, i, nullptr, InsertedVal, VIC);
938 }
939 if (Extract)
940 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty,
941 CostKind, i, nullptr, nullptr, VIC);
942 }
943
944 return Cost;
945 }
946
947 bool
949 unsigned ScalarOpdIdx) const override {
950 return false;
951 }
952
954 int OpdIdx) const override {
955 return OpdIdx == -1;
956 }
957
958 bool
960 int RetIdx) const override {
961 return RetIdx == 0;
962 }
963
964 /// Helper wrapper for the DemandedElts variant of getScalarizationOverhead.
966 VectorType *InTy, bool Insert, bool Extract, TTI::TargetCostKind CostKind,
967 bool ForPoisonSrc = true, ArrayRef<Value *> VL = {},
969 if (isa<ScalableVectorType>(InTy))
971 auto *Ty = cast<FixedVectorType>(InTy);
972
973 APInt DemandedElts = APInt::getAllOnes(Ty->getNumElements());
974 // Use CRTP to allow target overrides
975 return thisT()->getScalarizationOverhead(Ty, DemandedElts, Insert, Extract,
976 CostKind, ForPoisonSrc, VL, VIC);
977 }
978
979 /// Estimate the overhead of scalarizing an instruction's
980 /// operands. The (potentially vector) types to use for each of
981 /// argument are passes via Tys.
985 TTI::VectorInstrContext::None) const override {
987 for (Type *Ty : Tys) {
988 // Disregard things like metadata arguments.
989 if (!Ty->isIntOrIntVectorTy() && !Ty->isFPOrFPVectorTy() &&
990 !Ty->isPtrOrPtrVectorTy())
991 continue;
992
993 if (auto *VecTy = dyn_cast<VectorType>(Ty))
994 Cost += getScalarizationOverhead(VecTy, /*Insert*/ false,
995 /*Extract*/ true, CostKind,
996 /*ForPoisonSrc=*/true, {}, VIC);
997 }
998
999 return Cost;
1000 }
1001
1002 /// Estimate the overhead of scalarizing the inputs and outputs of an
1003 /// instruction, with return type RetTy and arguments Args of type Tys. If
1004 /// Args are unknown (empty), then the cost associated with one argument is
1005 /// added as a heuristic.
1008 ArrayRef<Type *> Tys,
1011 RetTy, /*Insert*/ true, /*Extract*/ false, CostKind);
1012 if (!Args.empty())
1014 filterConstantAndDuplicatedOperands(Args, Tys), CostKind);
1015 else
1016 // When no information on arguments is provided, we add the cost
1017 // associated with one argument as a heuristic.
1018 Cost += getScalarizationOverhead(RetTy, /*Insert*/ false,
1019 /*Extract*/ true, CostKind);
1020
1021 return Cost;
1022 }
1023
1024 /// Estimate the cost of type-legalization and the legalized type.
1025 std::pair<InstructionCost, MVT> getTypeLegalizationCost(Type *Ty) const {
1026 auto [It, Inserted] = TypeLegalizationCostCache.try_emplace(Ty);
1027 if (Inserted)
1028 It->second = computeTypeLegalizationCost(Ty);
1029 return It->second;
1030 }
1031
1032private:
1033 std::pair<InstructionCost, MVT> computeTypeLegalizationCost(Type *Ty) const {
1034 LLVMContext &C = Ty->getContext();
1035 EVT MTy = getTLI()->getValueType(DL, Ty);
1036
1038 // We keep legalizing the type until we find a legal kind. We assume that
1039 // the only operation that costs anything is the split. After splitting
1040 // we need to handle two types.
1041 while (true) {
1043
1045 // Ensure we return a sensible simple VT here, since many callers of
1046 // this function require it.
1047 MVT VT = MTy.isSimple() ? MTy.getSimpleVT() : MVT::i64;
1048 return std::make_pair(InstructionCost::getInvalid(), VT);
1049 }
1050
1051 if (LK.first == TargetLoweringBase::TypeLegal)
1052 return std::make_pair(Cost, MTy.getSimpleVT());
1053
1054 if (LK.first == TargetLoweringBase::TypeSplitVector ||
1056 Cost *= 2;
1057
1058 // Do not loop with f128 type.
1059 if (MTy == LK.second)
1060 return std::make_pair(Cost, MTy.getSimpleVT());
1061
1062 // Keep legalizing the type.
1063 MTy = LK.second;
1064 }
1065 }
1066
1067 /// Memoizes type legalization cost. The mapping does not depend on the IR, so
1068 /// entries stay valid for the lifetime of this object.
1069 mutable DenseMap<Type *, std::pair<InstructionCost, MVT>>
1070 TypeLegalizationCostCache;
1071
1072public:
1074 bool HasUnorderedReductions) const override {
1075 return 1;
1076 }
1077
1079 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
1082 ArrayRef<const Value *> Args = {},
1083 const Instruction *CtxI = nullptr) const override {
1084 // Check if any of the operands are vector operands.
1085 const TargetLoweringBase *TLI = getTLI();
1086 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1087 assert(ISD && "Invalid opcode");
1088
1089 // TODO: Handle more cost kinds.
1091 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind,
1092 Opd1Info, Opd2Info,
1093 Args, CtxI);
1094
1095 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
1096
1097 bool IsFloat = Ty->isFPOrFPVectorTy();
1098 // Assume that floating point arithmetic operations cost twice as much as
1099 // integer operations.
1100 InstructionCost OpCost = (IsFloat ? 2 : 1);
1101
1102 if (TLI->isOperationLegalOrPromote(ISD, LT.second)) {
1103 // The operation is legal. Assume it costs 1.
1104 // TODO: Once we have extract/insert subvector cost we need to use them.
1105 return LT.first * OpCost;
1106 }
1107
1108 if (!TLI->isOperationExpand(ISD, LT.second)) {
1109 // If the operation is custom lowered, then assume that the code is twice
1110 // as expensive.
1111 return LT.first * 2 * OpCost;
1112 }
1113
1114 // An 'Expand' of URem and SRem is special because it may default
1115 // to expanding the operation into a sequence of sub-operations
1116 // i.e. X % Y -> X-(X/Y)*Y.
1117 if (ISD == ISD::UREM || ISD == ISD::SREM) {
1118 bool IsSigned = ISD == ISD::SREM;
1119 if (TLI->isOperationLegalOrCustom(IsSigned ? ISD::SDIVREM : ISD::UDIVREM,
1120 LT.second) ||
1121 TLI->isOperationLegalOrCustom(IsSigned ? ISD::SDIV : ISD::UDIV,
1122 LT.second)) {
1123 unsigned DivOpc = IsSigned ? Instruction::SDiv : Instruction::UDiv;
1124 InstructionCost DivCost = thisT()->getArithmeticInstrCost(
1125 DivOpc, Ty, CostKind, Opd1Info, Opd2Info);
1126 InstructionCost MulCost =
1127 thisT()->getArithmeticInstrCost(Instruction::Mul, Ty, CostKind);
1128 InstructionCost SubCost =
1129 thisT()->getArithmeticInstrCost(Instruction::Sub, Ty, CostKind);
1130 return DivCost + MulCost + SubCost;
1131 }
1132 }
1133
1134 // We cannot scalarize scalable vectors, so return Invalid.
1137
1138 // Else, assume that we need to scalarize this op.
1139 // TODO: If one of the types get legalized by splitting, handle this
1140 // similarly to what getCastInstrCost() does.
1141 if (auto *VTy = dyn_cast<FixedVectorType>(Ty)) {
1142 InstructionCost Cost = thisT()->getArithmeticInstrCost(
1143 Opcode, VTy->getScalarType(), CostKind, Opd1Info, Opd2Info,
1144 Args, CtxI);
1145 // Return the cost of multiple scalar invocation plus the cost of
1146 // inserting and extracting the values.
1147 SmallVector<Type *> Tys(Args.size(), Ty);
1148 return getScalarizationOverhead(VTy, Args, Tys, CostKind) +
1149 VTy->getNumElements() * Cost;
1150 }
1151
1152 // We don't know anything about this scalar instruction.
1153 return OpCost;
1154 }
1155
1157 ArrayRef<int> Mask,
1158 VectorType *SrcTy, int &Index,
1159 VectorType *&SubTy) const {
1160 if (Mask.empty())
1161 return Kind;
1162 int NumDstElts = Mask.size();
1163 int NumSrcElts = SrcTy->getElementCount().getKnownMinValue();
1164 switch (Kind) {
1166 if (ShuffleVectorInst::isReverseMask(Mask, NumSrcElts))
1167 return TTI::SK_Reverse;
1168 if (ShuffleVectorInst::isZeroEltSplatMask(Mask, NumSrcElts))
1169 return TTI::SK_Broadcast;
1170 if (isSplatMask(Mask, NumSrcElts, Index))
1171 return TTI::SK_Broadcast;
1172 if (ShuffleVectorInst::isExtractSubvectorMask(Mask, NumSrcElts, Index) &&
1173 (Index + NumDstElts) <= NumSrcElts) {
1174 SubTy = FixedVectorType::get(SrcTy->getElementType(), NumDstElts);
1176 }
1177 break;
1178 }
1179 case TTI::SK_PermuteTwoSrc: {
1180 if (all_of(Mask, [NumSrcElts](int M) { return M < NumSrcElts; }))
1182 Index, SubTy);
1183 int NumSubElts;
1184 if (NumDstElts > 2 && ShuffleVectorInst::isInsertSubvectorMask(
1185 Mask, NumSrcElts, NumSubElts, Index)) {
1186 if (Index + NumSubElts > NumSrcElts)
1187 return Kind;
1188 SubTy = FixedVectorType::get(SrcTy->getElementType(), NumSubElts);
1190 }
1191 if (ShuffleVectorInst::isSelectMask(Mask, NumSrcElts))
1192 return TTI::SK_Select;
1193 if (ShuffleVectorInst::isTransposeMask(Mask, NumSrcElts))
1194 return TTI::SK_Transpose;
1195 if (ShuffleVectorInst::isSpliceMask(Mask, NumSrcElts, Index))
1196 return TTI::SK_Splice;
1197 break;
1198 }
1199 case TTI::SK_Select:
1200 case TTI::SK_Reverse:
1201 case TTI::SK_Broadcast:
1202 case TTI::SK_Transpose:
1205 case TTI::SK_Splice:
1206 break;
1207 }
1208 return Kind;
1209 }
1210
1214 VectorType *SubTp, ArrayRef<const Value *> Args = {},
1215 const Instruction *CtxI = nullptr,
1217 TTI::VectorInstrContext::None) const override {
1218 switch (improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp)) {
1219 case TTI::SK_Broadcast:
1220 if (auto *FVT = dyn_cast<FixedVectorType>(SrcTy))
1221 return getBroadcastShuffleOverhead(FVT, CostKind);
1223 case TTI::SK_Select:
1224 case TTI::SK_Splice:
1225 case TTI::SK_Reverse:
1226 case TTI::SK_Transpose:
1229 if (auto *FVT = dyn_cast<FixedVectorType>(SrcTy))
1230 return getPermuteShuffleOverhead(FVT, CostKind);
1233 return getExtractSubvectorOverhead(SrcTy, CostKind, Index,
1234 cast<FixedVectorType>(SubTp));
1236 return getInsertSubvectorOverhead(DstTy, CostKind, Index,
1237 cast<FixedVectorType>(SubTp));
1238 }
1239 llvm_unreachable("Unknown TTI::ShuffleKind");
1240 }
1241
1243 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
1245 const Instruction *I = nullptr) const override {
1246 if (BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I) == 0)
1247 return 0;
1248
1249 const TargetLoweringBase *TLI = getTLI();
1250 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1251 assert(ISD && "Invalid opcode");
1252 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(Src);
1253 std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(Dst);
1254
1255 TypeSize SrcSize = SrcLT.second.getSizeInBits();
1256 TypeSize DstSize = DstLT.second.getSizeInBits();
1257 bool IntOrPtrSrc = Src->isIntegerTy() || Src->isPointerTy();
1258 bool IntOrPtrDst = Dst->isIntegerTy() || Dst->isPointerTy();
1259
1260 switch (Opcode) {
1261 default:
1262 break;
1263 case Instruction::Trunc:
1264 // Check for NOOP conversions.
1265 if (TLI->isTruncateFree(SrcLT.second, DstLT.second))
1266 return 0;
1267 [[fallthrough]];
1268 case Instruction::BitCast:
1269 // Bitcast between types that are legalized to the same type are free and
1270 // assume int to/from ptr of the same size is also free.
1271 if (SrcLT.first == DstLT.first && IntOrPtrSrc == IntOrPtrDst &&
1272 SrcSize == DstSize)
1273 return 0;
1274 break;
1275 case Instruction::FPExt:
1276 if (I && getTLI()->isExtFree(I))
1277 return 0;
1278 break;
1279 case Instruction::ZExt:
1280 if (TLI->isZExtFree(SrcLT.second, DstLT.second))
1281 return 0;
1282 [[fallthrough]];
1283 case Instruction::SExt:
1284 if (I && getTLI()->isExtFree(I))
1285 return 0;
1286
1287 // If this is a zext/sext of a load, return 0 if the corresponding
1288 // extending load exists on target and the result type is legal.
1289 if (CCH == TTI::CastContextHint::Normal) {
1290 EVT ExtVT = EVT::getEVT(Dst);
1291 EVT LoadVT = EVT::getEVT(Src);
1292 unsigned LType =
1293 Opcode == Instruction::ZExt ? ISD::ZEXTLOAD : ISD::SEXTLOAD;
1294 if (I) {
1295 if (auto *LI = dyn_cast<LoadInst>(I->getOperand(0))) {
1296 if (DstLT.first == SrcLT.first &&
1297 TLI->isLoadLegal(ExtVT, LoadVT, LI->getAlign(),
1298 LI->getPointerAddressSpace(), LType, false))
1299 return 0;
1300 } else if (auto *II = dyn_cast<IntrinsicInst>(I->getOperand(0))) {
1301 switch (II->getIntrinsicID()) {
1302 case Intrinsic::masked_load: {
1303 Type *PtrType = II->getArgOperand(0)->getType();
1304 assert(PtrType->isPointerTy());
1305
1306 if (DstLT.first == SrcLT.first &&
1307 TLI->isLoadLegal(
1308 ExtVT, LoadVT, II->getParamAlign(0).valueOrOne(),
1309 PtrType->getPointerAddressSpace(), LType, false))
1310 return 0;
1311
1312 break;
1313 }
1314 default:
1315 break;
1316 }
1317 }
1318 }
1319 }
1320 break;
1321 case Instruction::AddrSpaceCast:
1322 if (TLI->isFreeAddrSpaceCast(DL, Src->getPointerAddressSpace(),
1323 Dst->getPointerAddressSpace()))
1324 return 0;
1325 break;
1326 }
1327
1328 auto *SrcVTy = dyn_cast<VectorType>(Src);
1329 auto *DstVTy = dyn_cast<VectorType>(Dst);
1330
1331 // If the cast is marked as legal (or promote) then assume low cost.
1332 if (SrcLT.first == DstLT.first &&
1333 TLI->isOperationLegalOrPromote(ISD, DstLT.second))
1334 return SrcLT.first;
1335
1336 // Handle scalar conversions.
1337 if (!SrcVTy && !DstVTy) {
1338 // Just check the op cost. If the operation is legal then assume it costs
1339 // 1.
1340 if (!TLI->isOperationExpand(ISD, DstLT.second))
1341 return 1;
1342
1343 // Assume that illegal scalar instruction are expensive.
1344 return 4;
1345 }
1346
1347 // Check vector-to-vector casts.
1348 if (DstVTy && SrcVTy) {
1349 // If the cast is between same-sized registers, then the check is simple.
1350 if (SrcLT.first == DstLT.first && SrcSize == DstSize) {
1351
1352 // Assume that Zext is done using AND.
1353 if (Opcode == Instruction::ZExt)
1354 return SrcLT.first;
1355
1356 // Assume that sext is done using SHL and SRA.
1357 if (Opcode == Instruction::SExt)
1358 return SrcLT.first * 2;
1359
1360 // Just check the op cost. If the operation is legal then assume it
1361 // costs
1362 // 1 and multiply by the type-legalization overhead.
1363 if (!TLI->isOperationExpand(ISD, DstLT.second))
1364 return SrcLT.first * 1;
1365 }
1366
1367 // If we are legalizing by splitting, query the concrete TTI for the cost
1368 // of casting the original vector twice. We also need to factor in the
1369 // cost of the split itself. Count that as 1, to be consistent with
1370 // getTypeLegalizationCost().
1371 bool SplitSrc =
1372 TLI->getTypeAction(Src->getContext(), TLI->getValueType(DL, Src)) ==
1374 bool SplitDst =
1375 TLI->getTypeAction(Dst->getContext(), TLI->getValueType(DL, Dst)) ==
1377 if ((SplitSrc || SplitDst) && SrcVTy->getElementCount().isKnownEven() &&
1378 DstVTy->getElementCount().isKnownEven()) {
1379 Type *SplitDstTy = VectorType::getHalfElementsVectorType(DstVTy);
1380 Type *SplitSrcTy = VectorType::getHalfElementsVectorType(SrcVTy);
1381 const T *TTI = thisT();
1382 // If both types need to be split then the split is free.
1383 InstructionCost SplitCost =
1384 (!SplitSrc || !SplitDst) ? TTI->getVectorSplitCost() : 0;
1385 return SplitCost +
1386 (2 * TTI->getCastInstrCost(Opcode, SplitDstTy, SplitSrcTy, CCH,
1387 CostKind, I));
1388 }
1389
1390 // Scalarization cost is Invalid, can't assume any num elements.
1391 if (isa<ScalableVectorType>(DstVTy))
1393
1394 // In other cases where the source or destination are illegal, assume
1395 // the operation will get scalarized.
1396 unsigned Num = cast<FixedVectorType>(DstVTy)->getNumElements();
1397 InstructionCost Cost = thisT()->getCastInstrCost(
1398 Opcode, Dst->getScalarType(), Src->getScalarType(), CCH, CostKind, I);
1399
1400 // Return the cost of multiple scalar invocation plus the cost of
1401 // inserting and extracting the values.
1402 return getScalarizationOverhead(DstVTy, /*Insert*/ true, /*Extract*/ true,
1403 CostKind) +
1404 Num * Cost;
1405 }
1406
1407 // We already handled vector-to-vector and scalar-to-scalar conversions.
1408 // This
1409 // is where we handle bitcast between vectors and scalars. We need to assume
1410 // that the conversion is scalarized in one way or another.
1411 if (Opcode == Instruction::BitCast) {
1412 // Illegal bitcasts are done by storing and loading from a stack slot.
1413 return (SrcVTy ? getScalarizationOverhead(SrcVTy, /*Insert*/ false,
1414 /*Extract*/ true, CostKind)
1415 : 0) +
1416 (DstVTy ? getScalarizationOverhead(DstVTy, /*Insert*/ true,
1417 /*Extract*/ false, CostKind)
1418 : 0);
1419 }
1420
1421 llvm_unreachable("Unhandled cast");
1422 }
1423
1425 getExtractWithExtendCost(unsigned Opcode, Type *Dst, VectorType *VecTy,
1426 unsigned Index,
1427 TTI::TargetCostKind CostKind) const override {
1428 return thisT()->getVectorInstrCost(Instruction::ExtractElement, VecTy,
1429 CostKind, Index, nullptr, nullptr) +
1430 thisT()->getCastInstrCost(Opcode, Dst, VecTy->getElementType(),
1432 }
1433
1436 const Instruction *I = nullptr) const override {
1437 return BaseT::getCFInstrCost(Opcode, CostKind, I);
1438 }
1439
1441 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
1445 const Instruction *I = nullptr) const override {
1446 const TargetLoweringBase *TLI = getTLI();
1447 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1448 assert(ISD && "Invalid opcode");
1449
1450 if (getTLI()->getValueType(DL, ValTy, true) == MVT::Other)
1451 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
1452 Op1Info, Op2Info, I);
1453
1454 // Selects on vectors are actually vector selects.
1455 if (ISD == ISD::SELECT) {
1456 assert(CondTy && "CondTy must exist");
1457 if (CondTy->isVectorTy())
1458 ISD = ISD::VSELECT;
1459 }
1460 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
1461
1462 if (!(ValTy->isVectorTy() && !LT.second.isVector()) &&
1463 !TLI->isOperationExpand(ISD, LT.second)) {
1464 // The operation is legal. Assume it costs 1. Multiply
1465 // by the type-legalization overhead.
1466 return LT.first * 1;
1467 }
1468
1469 // Otherwise, assume that the cast is scalarized.
1470 // TODO: If one of the types get legalized by splitting, handle this
1471 // similarly to what getCastInstrCost() does.
1472 if (auto *ValVTy = dyn_cast<VectorType>(ValTy)) {
1473 if (isa<ScalableVectorType>(ValTy))
1475
1476 unsigned Num = cast<FixedVectorType>(ValVTy)->getNumElements();
1477 InstructionCost Cost = thisT()->getCmpSelInstrCost(
1478 Opcode, ValVTy->getScalarType(), CondTy->getScalarType(), VecPred,
1479 CostKind, Op1Info, Op2Info, I);
1480
1481 // Return the cost of multiple scalar invocation plus the cost of
1482 // inserting and extracting the values.
1483 return getScalarizationOverhead(ValVTy, /*Insert*/ true,
1484 /*Extract*/ false, CostKind) +
1485 Num * Cost;
1486 }
1487
1488 // Unknown scalar opcode.
1489 return 1;
1490 }
1491
1494 unsigned Index, const Value *Op0, const Value *Op1,
1496 TTI::VectorInstrContext::None) const override {
1497 return getRegUsageForType(Val->getScalarType());
1498 }
1499
1500 /// \param ScalarUserAndIdx encodes the information about extracts from a
1501 /// vector with 'Scalar' being the value being extracted,'User' being the user
1502 /// of the extract(nullptr if user is not known before vectorization) and
1503 /// 'Idx' being the extract lane.
1505 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
1506 Value *Scalar,
1507 ArrayRef<std::tuple<Value *, User *, int>> ScalarUserAndIdx,
1509 TTI::VectorInstrContext::None) const override {
1510 return getVectorInstrCost(Opcode, Val, CostKind, Index, nullptr, nullptr,
1511 VIC);
1512 }
1513
1516 TTI::TargetCostKind CostKind, unsigned Index,
1518 TTI::VectorInstrContext::None) const override {
1519 Value *Op0 = nullptr;
1520 Value *Op1 = nullptr;
1521 if (auto *IE = dyn_cast<InsertElementInst>(&I)) {
1522 Op0 = IE->getOperand(0);
1523 Op1 = IE->getOperand(1);
1524 }
1525 // If VIC is None, compute it from the instruction
1528 return thisT()->getVectorInstrCost(I.getOpcode(), Val, CostKind, Index, Op0,
1529 Op1, VIC);
1530 }
1531
1535 unsigned Index) const override {
1536 unsigned NewIndex = -1;
1537 if (auto *FVTy = dyn_cast<FixedVectorType>(Val)) {
1538 assert(Index < FVTy->getNumElements() &&
1539 "Unexpected index from end of vector");
1540 NewIndex = FVTy->getNumElements() - 1 - Index;
1541 }
1542 return thisT()->getVectorInstrCost(Opcode, Val, CostKind, NewIndex, nullptr,
1543 nullptr);
1544 }
1545
1547 getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF,
1548 const APInt &DemandedDstElts,
1549 TTI::TargetCostKind CostKind) const override {
1550 assert(DemandedDstElts.getBitWidth() == (unsigned)VF * ReplicationFactor &&
1551 "Unexpected size of DemandedDstElts.");
1552
1554
1555 auto *SrcVT = FixedVectorType::get(EltTy, VF);
1556 auto *ReplicatedVT = FixedVectorType::get(EltTy, VF * ReplicationFactor);
1557
1558 // The Mask shuffling cost is extract all the elements of the Mask
1559 // and insert each of them Factor times into the wide vector:
1560 //
1561 // E.g. an interleaved group with factor 3:
1562 // %mask = icmp ult <8 x i32> %vec1, %vec2
1563 // %interleaved.mask = shufflevector <8 x i1> %mask, <8 x i1> undef,
1564 // <24 x i32> <0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7>
1565 // The cost is estimated as extract all mask elements from the <8xi1> mask
1566 // vector and insert them factor times into the <24xi1> shuffled mask
1567 // vector.
1568 APInt DemandedSrcElts = APIntOps::ScaleBitMask(DemandedDstElts, VF);
1569 Cost += thisT()->getScalarizationOverhead(SrcVT, DemandedSrcElts,
1570 /*Insert*/ false,
1571 /*Extract*/ true, CostKind);
1572 Cost += thisT()->getScalarizationOverhead(ReplicatedVT, DemandedDstElts,
1573 /*Insert*/ true,
1574 /*Extract*/ false, CostKind);
1575
1576 return Cost;
1577 }
1578
1580 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
1583 const Instruction *I = nullptr) const override {
1584 assert(!Src->isVoidTy() && "Invalid type");
1585 // Assume types, such as structs, are expensive.
1586 if (getTLI()->getValueType(DL, Src, true) == MVT::Other)
1587 return 4;
1588 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
1589
1590 // FIXME: Arbitrary cost
1591 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
1592 return 4;
1593
1594 // Assuming that all loads of legal types cost 1.
1595 InstructionCost Cost = LT.first;
1597 return Cost;
1598
1599 const DataLayout &DL = this->getDataLayout();
1600 if (Src->isVectorTy() &&
1601 // In practice it's not currently possible to have a change in lane
1602 // length for extending loads or truncating stores so both types should
1603 // have the same scalable property.
1604 TypeSize::isKnownLT(DL.getTypeStoreSizeInBits(Src),
1605 LT.second.getSizeInBits())) {
1606 // This is a vector load that legalizes to a larger type than the vector
1607 // itself. Unless the corresponding extending load or truncating store is
1608 // legal, then this will scalarize.
1610 EVT MemVT = getTLI()->getValueType(DL, Src);
1611 if (Opcode == Instruction::Store)
1612 LA = getTLI()->getTruncStoreAction(LT.second, MemVT, Alignment,
1613 AddressSpace);
1614 else
1615 LA = getTLI()->getLoadAction(LT.second, MemVT, Alignment, AddressSpace,
1616 ISD::EXTLOAD, false);
1617
1618 if (LA != TargetLowering::Legal && LA != TargetLowering::Custom) {
1619 // This is a vector load/store for some illegal type that is scalarized.
1620 // We must account for the cost of building or decomposing the vector.
1622 cast<VectorType>(Src), Opcode != Instruction::Store,
1623 Opcode == Instruction::Store, CostKind);
1624 }
1625 }
1626
1627 return Cost;
1628 }
1629
1631 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
1632 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
1633 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override {
1634
1635 // We cannot scalarize scalable vectors, so return Invalid.
1636 if (isa<ScalableVectorType>(VecTy))
1638
1639 auto *VT = cast<FixedVectorType>(VecTy);
1640
1641 unsigned NumElts = VT->getNumElements();
1642 assert(Factor > 1 && NumElts % Factor == 0 && "Invalid interleave factor");
1643
1644 unsigned NumSubElts = NumElts / Factor;
1645 auto *SubVT = FixedVectorType::get(VT->getElementType(), NumSubElts);
1646
1647 // Firstly, the cost of load/store operation.
1649 if (UseMaskForCond || UseMaskForGaps) {
1650 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
1651 : Intrinsic::masked_store;
1652 Cost = thisT()->getMemIntrinsicInstrCost(
1653 MemIntrinsicCostAttributes(IID, VecTy, Alignment, AddressSpace),
1654 CostKind);
1655 } else
1656 Cost = thisT()->getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace,
1657 CostKind);
1658
1659 // Legalize the vector type, and get the legalized and unlegalized type
1660 // sizes.
1661 MVT VecTyLT = getTypeLegalizationCost(VecTy).second;
1662 unsigned VecTySize = thisT()->getDataLayout().getTypeStoreSize(VecTy);
1663 unsigned VecTyLTSize = VecTyLT.getStoreSize();
1664
1665 // Scale the cost of the memory operation by the fraction of legalized
1666 // instructions that will actually be used. We shouldn't account for the
1667 // cost of dead instructions since they will be removed.
1668 //
1669 // E.g., An interleaved load of factor 8:
1670 // %vec = load <16 x i64>, <16 x i64>* %ptr
1671 // %v0 = shufflevector %vec, undef, <0, 8>
1672 //
1673 // If <16 x i64> is legalized to 8 v2i64 loads, only 2 of the loads will be
1674 // used (those corresponding to elements [0:1] and [8:9] of the unlegalized
1675 // type). The other loads are unused.
1676 //
1677 // TODO: Note that legalization can turn masked loads/stores into unmasked
1678 // (legalized) loads/stores. This can be reflected in the cost.
1679 if (Cost.isValid() && VecTySize > VecTyLTSize) {
1680 // The number of loads of a legal type it will take to represent a load
1681 // of the unlegalized vector type.
1682 unsigned NumLegalInsts = divideCeil(VecTySize, VecTyLTSize);
1683
1684 // The number of elements of the unlegalized type that correspond to a
1685 // single legal instruction.
1686 unsigned NumEltsPerLegalInst = divideCeil(NumElts, NumLegalInsts);
1687
1688 // Determine which legal instructions will be used.
1689 BitVector UsedInsts(NumLegalInsts, false);
1690 for (unsigned Index : Indices)
1691 for (unsigned Elt = 0; Elt < NumSubElts; ++Elt)
1692 UsedInsts.set((Index + Elt * Factor) / NumEltsPerLegalInst);
1693
1694 // Scale the cost of the load by the fraction of legal instructions that
1695 // will be used.
1696 Cost = divideCeil(UsedInsts.count() * Cost.getValue(), NumLegalInsts);
1697 }
1698
1699 // Then plus the cost of interleave operation.
1700 assert(Indices.size() <= Factor &&
1701 "Interleaved memory op has too many members");
1702
1703 const APInt DemandedAllSubElts = APInt::getAllOnes(NumSubElts);
1704 const APInt DemandedAllResultElts = APInt::getAllOnes(NumElts);
1705
1706 APInt DemandedLoadStoreElts = APInt::getZero(NumElts);
1707 for (unsigned Index : Indices) {
1708 assert(Index < Factor && "Invalid index for interleaved memory op");
1709 for (unsigned Elm = 0; Elm < NumSubElts; Elm++)
1710 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
1711 }
1712
1713 if (Opcode == Instruction::Load) {
1714 // The interleave cost is similar to extract sub vectors' elements
1715 // from the wide vector, and insert them into sub vectors.
1716 //
1717 // E.g. An interleaved load of factor 2 (with one member of index 0):
1718 // %vec = load <8 x i32>, <8 x i32>* %ptr
1719 // %v0 = shuffle %vec, undef, <0, 2, 4, 6> ; Index 0
1720 // The cost is estimated as extract elements at 0, 2, 4, 6 from the
1721 // <8 x i32> vector and insert them into a <4 x i32> vector.
1722 InstructionCost InsSubCost = thisT()->getScalarizationOverhead(
1723 SubVT, DemandedAllSubElts,
1724 /*Insert*/ true, /*Extract*/ false, CostKind);
1725 Cost += Indices.size() * InsSubCost;
1726 Cost += thisT()->getScalarizationOverhead(VT, DemandedLoadStoreElts,
1727 /*Insert*/ false,
1728 /*Extract*/ true, CostKind);
1729 } else {
1730 // The interleave cost is extract elements from sub vectors, and
1731 // insert them into the wide vector.
1732 //
1733 // E.g. An interleaved store of factor 3 with 2 members at indices 0,1:
1734 // (using VF=4):
1735 // %v0_v1 = shuffle %v0, %v1, <0,4,undef,1,5,undef,2,6,undef,3,7,undef>
1736 // %gaps.mask = <true, true, false, true, true, false,
1737 // true, true, false, true, true, false>
1738 // call llvm.masked.store <12 x i32> %v0_v1, <12 x i32>* %ptr,
1739 // i32 Align, <12 x i1> %gaps.mask
1740 // The cost is estimated as extract all elements (of actual members,
1741 // excluding gaps) from both <4 x i32> vectors and insert into the <12 x
1742 // i32> vector.
1743 InstructionCost ExtSubCost = thisT()->getScalarizationOverhead(
1744 SubVT, DemandedAllSubElts,
1745 /*Insert*/ false, /*Extract*/ true, CostKind);
1746 Cost += ExtSubCost * Indices.size();
1747 Cost += thisT()->getScalarizationOverhead(VT, DemandedLoadStoreElts,
1748 /*Insert*/ true,
1749 /*Extract*/ false, CostKind);
1750 }
1751
1752 if (!UseMaskForCond)
1753 return Cost;
1754
1755 Type *I8Type = Type::getInt8Ty(VT->getContext());
1756
1757 Cost += thisT()->getReplicationShuffleCost(
1758 I8Type, Factor, NumSubElts,
1759 UseMaskForGaps ? DemandedLoadStoreElts : DemandedAllResultElts,
1760 CostKind);
1761
1762 // The Gaps mask is invariant and created outside the loop, therefore the
1763 // cost of creating it is not accounted for here. However if we have both
1764 // a MaskForGaps and some other mask that guards the execution of the
1765 // memory access, we need to account for the cost of And-ing the two masks
1766 // inside the loop.
1767 if (UseMaskForGaps) {
1768 auto *MaskVT = FixedVectorType::get(I8Type, NumElts);
1769 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::And, MaskVT,
1770 CostKind);
1771 }
1772
1773 return Cost;
1774 }
1775
1776 /// Get intrinsic cost based on arguments.
1779 TTI::TargetCostKind CostKind) const override {
1780 // Check for generically free intrinsics.
1782 return 0;
1783
1784 // Assume that target intrinsics are cheap.
1785 Intrinsic::ID IID = ICA.getID();
1788
1789 // VP Intrinsics should have the same cost as their non-vp counterpart.
1790 // TODO: Adjust the cost to make the vp intrinsic cheaper than its non-vp
1791 // counterpart when the vector length argument is smaller than the maximum
1792 // vector length.
1793 // TODO: Support other kinds of VPIntrinsics
1794 if (VPIntrinsic::isVPIntrinsic(ICA.getID())) {
1795 std::optional<unsigned> FOp =
1797 if (FOp) {
1798 if (ICA.getID() == Intrinsic::vp_load) {
1799 Align Alignment;
1800 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1801 Alignment = VPI->getPointerAlignment().valueOrOne();
1802 unsigned AS = 0;
1803 if (ICA.getArgTypes().size() > 1)
1804 if (auto *PtrTy = dyn_cast<PointerType>(ICA.getArgTypes()[0]))
1805 AS = PtrTy->getAddressSpace();
1806 return thisT()->getMemoryOpCost(*FOp, ICA.getReturnType(), Alignment,
1807 AS, CostKind);
1808 }
1809 if (ICA.getID() == Intrinsic::vp_store) {
1810 Align Alignment;
1811 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1812 Alignment = VPI->getPointerAlignment().valueOrOne();
1813 unsigned AS = 0;
1814 if (ICA.getArgTypes().size() >= 2)
1815 if (auto *PtrTy = dyn_cast<PointerType>(ICA.getArgTypes()[1]))
1816 AS = PtrTy->getAddressSpace();
1817 return thisT()->getMemoryOpCost(*FOp, ICA.getArgTypes()[0], Alignment,
1818 AS, CostKind);
1819 }
1820 if (ICA.getID() == Intrinsic::vp_udiv ||
1821 ICA.getID() == Intrinsic::vp_sdiv ||
1822 ICA.getID() == Intrinsic::vp_urem ||
1823 ICA.getID() == Intrinsic::vp_srem) {
1824 return thisT()->getArithmeticInstrCost(*FOp, ICA.getReturnType(),
1825 CostKind);
1826 }
1827 }
1828 if (ICA.getID() == Intrinsic::vp_load_ff) {
1829 Type *RetTy = ICA.getReturnType();
1830 Type *DataTy = cast<StructType>(RetTy)->getElementType(0);
1831 Align Alignment;
1832 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1833 Alignment = VPI->getPointerAlignment().valueOrOne();
1834 return thisT()->getMemIntrinsicInstrCost(
1835 MemIntrinsicCostAttributes(ICA.getID(), DataTy, Alignment),
1836 CostKind);
1837 }
1838 if (ICA.getID() == Intrinsic::vp_scatter) {
1839 if (ICA.isTypeBasedOnly()) {
1840 IntrinsicCostAttributes MaskedScatter(
1843 ICA.getFlags());
1844 return getTypeBasedIntrinsicInstrCost(MaskedScatter, CostKind);
1845 }
1846 Align Alignment;
1847 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1848 Alignment = VPI->getPointerAlignment().valueOrOne();
1849 bool VarMask = isa<Constant>(ICA.getArgs()[2]);
1850 return thisT()->getMemIntrinsicInstrCost(
1851 MemIntrinsicCostAttributes(Intrinsic::vp_scatter,
1852 ICA.getArgTypes()[0], ICA.getArgs()[1],
1853 VarMask, Alignment, nullptr),
1854 CostKind);
1855 }
1856 if (ICA.getID() == Intrinsic::vp_gather) {
1857 if (ICA.isTypeBasedOnly()) {
1858 IntrinsicCostAttributes MaskedGather(
1861 ICA.getFlags());
1862 return getTypeBasedIntrinsicInstrCost(MaskedGather, CostKind);
1863 }
1864 Align Alignment;
1865 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1866 Alignment = VPI->getPointerAlignment().valueOrOne();
1867 bool VarMask = isa<Constant>(ICA.getArgs()[1]);
1868 return thisT()->getMemIntrinsicInstrCost(
1869 MemIntrinsicCostAttributes(Intrinsic::vp_gather,
1870 ICA.getReturnType(), ICA.getArgs()[0],
1871 VarMask, Alignment, nullptr),
1872 CostKind);
1873 }
1874
1875 if (ICA.getID() == Intrinsic::vp_merge) {
1876 TTI::OperandValueInfo OpInfoX, OpInfoY;
1877 if (!ICA.isTypeBasedOnly()) {
1878 OpInfoX = TTI::getOperandInfo(ICA.getArgs()[0]);
1879 OpInfoY = TTI::getOperandInfo(ICA.getArgs()[1]);
1880 }
1881 return getCmpSelInstrCost(
1882 Instruction::Select, ICA.getReturnType(), ICA.getArgTypes()[0],
1883 CmpInst::BAD_ICMP_PREDICATE, CostKind, OpInfoX, OpInfoY);
1884 }
1885
1886 std::optional<Intrinsic::ID> FID =
1888
1889 // Not functionally equivalent but close enough for cost modelling.
1890 if (ICA.getID() == Intrinsic::experimental_vp_reverse)
1891 FID = Intrinsic::vector_reverse;
1892
1893 if (FID) {
1894 // Non-vp version will have same arg types except mask and vector
1895 // length.
1896 assert(ICA.getArgTypes().size() >= 2 &&
1897 "Expected VPIntrinsic to have Mask and Vector Length args and "
1898 "types");
1899
1900 ArrayRef<const Value *> NewArgs = ArrayRef(ICA.getArgs());
1901 if (!ICA.isTypeBasedOnly())
1902 NewArgs = NewArgs.drop_back(2);
1904
1905 // VPReduction intrinsics have a start value argument that their non-vp
1906 // counterparts do not have, except for the fadd and fmul non-vp
1907 // counterpart.
1909 *FID != Intrinsic::vector_reduce_fadd &&
1910 *FID != Intrinsic::vector_reduce_fmul) {
1911 if (!ICA.isTypeBasedOnly())
1912 NewArgs = NewArgs.drop_front();
1913 NewTys = NewTys.drop_front();
1914 }
1915
1916 IntrinsicCostAttributes NewICA(*FID, ICA.getReturnType(), NewArgs,
1917 NewTys, ICA.getFlags());
1918 return thisT()->getIntrinsicInstrCost(NewICA, CostKind);
1919 }
1920 }
1921
1922 if (ICA.isTypeBasedOnly())
1924
1925 Type *RetTy = ICA.getReturnType();
1926
1927 ElementCount RetVF = isVectorizedTy(RetTy) ? getVectorizedTypeVF(RetTy)
1929
1930 const IntrinsicInst *I = ICA.getInst();
1931 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
1932 FastMathFlags FMF = ICA.getFlags();
1933 switch (IID) {
1934 default:
1935 break;
1936
1937 case Intrinsic::powi:
1938 if (auto *RHSC = dyn_cast<ConstantInt>(Args[1])) {
1939 bool ShouldOptForSize = I->getParent()->getParent()->hasOptSize();
1940 if (getTLI()->isBeneficialToExpandPowI(RHSC->getSExtValue(),
1941 ShouldOptForSize)) {
1942 // The cost is modeled on the expansion performed by ExpandPowI in
1943 // SelectionDAGBuilder.
1944 APInt Exponent = RHSC->getValue().abs();
1945 unsigned ActiveBits = Exponent.getActiveBits();
1946 unsigned PopCount = Exponent.popcount();
1947 InstructionCost Cost = (ActiveBits + PopCount - 2) *
1948 thisT()->getArithmeticInstrCost(
1949 Instruction::FMul, RetTy, CostKind);
1950 if (RHSC->isNegative())
1951 Cost += thisT()->getArithmeticInstrCost(Instruction::FDiv, RetTy,
1952 CostKind);
1953 return Cost;
1954 }
1955 }
1956 break;
1957 case Intrinsic::cttz:
1958 // FIXME: If necessary, this should go in target-specific overrides.
1959 if (RetVF.isScalar() && getTLI()->isCheapToSpeculateCttz(RetTy))
1961 break;
1962
1963 case Intrinsic::ctlz:
1964 // FIXME: If necessary, this should go in target-specific overrides.
1965 if (RetVF.isScalar() && getTLI()->isCheapToSpeculateCtlz(RetTy))
1967 break;
1968
1969 case Intrinsic::memcpy:
1970 return thisT()->getMemcpyCost(ICA.getInst());
1971
1972 case Intrinsic::masked_scatter: {
1973 const Value *Mask = Args[2];
1974 bool VarMask = !isa<Constant>(Mask);
1975 Align Alignment = I->getParamAlign(1).valueOrOne();
1976 return thisT()->getMemIntrinsicInstrCost(
1977 MemIntrinsicCostAttributes(Intrinsic::masked_scatter,
1978 ICA.getArgTypes()[0], Args[1], VarMask,
1979 Alignment, I),
1980 CostKind);
1981 }
1982 case Intrinsic::masked_gather: {
1983 const Value *Mask = Args[1];
1984 bool VarMask = !isa<Constant>(Mask);
1985 Align Alignment = I->getParamAlign(0).valueOrOne();
1986 return thisT()->getMemIntrinsicInstrCost(
1987 MemIntrinsicCostAttributes(Intrinsic::masked_gather, RetTy, Args[0],
1988 VarMask, Alignment, I),
1989 CostKind);
1990 }
1991 case Intrinsic::masked_compressstore: {
1992 const Value *Data = Args[0];
1993 const Value *Mask = Args[2];
1994 Align Alignment = I->getParamAlign(1).valueOrOne();
1995 return thisT()->getMemIntrinsicInstrCost(
1996 MemIntrinsicCostAttributes(IID, Data->getType(), !isa<Constant>(Mask),
1997 Alignment, I),
1998 CostKind);
1999 }
2000 case Intrinsic::masked_expandload: {
2001 const Value *Mask = Args[1];
2002 Align Alignment = I->getParamAlign(0).valueOrOne();
2003 return thisT()->getMemIntrinsicInstrCost(
2004 MemIntrinsicCostAttributes(IID, RetTy, !isa<Constant>(Mask),
2005 Alignment, I),
2006 CostKind);
2007 }
2008 case Intrinsic::experimental_vp_strided_store: {
2009 const Value *Data = Args[0];
2010 const Value *Ptr = Args[1];
2011 const Value *Stride = Args[2];
2012 const Value *Mask = Args[3];
2013 const Value *EVL = Args[4];
2014 bool VarMask = !isa<Constant>(Mask) || !isa<Constant>(EVL);
2015 Type *EltTy = cast<VectorType>(Data->getType())->getElementType();
2016 Align Alignment =
2017 I->getParamAlign(1).value_or(thisT()->DL.getABITypeAlign(EltTy));
2018 return thisT()->getMemIntrinsicInstrCost(
2019 MemIntrinsicCostAttributes(IID, Data->getType(), Ptr, VarMask,
2020 Alignment, I, Stride),
2021 CostKind);
2022 }
2023 case Intrinsic::experimental_vp_strided_load: {
2024 const Value *Ptr = Args[0];
2025 const Value *Stride = Args[1];
2026 const Value *Mask = Args[2];
2027 const Value *EVL = Args[3];
2028 bool VarMask = !isa<Constant>(Mask) || !isa<Constant>(EVL);
2029 Type *EltTy = cast<VectorType>(RetTy)->getElementType();
2030 Align Alignment =
2031 I->getParamAlign(0).value_or(thisT()->DL.getABITypeAlign(EltTy));
2032 return thisT()->getMemIntrinsicInstrCost(
2033 MemIntrinsicCostAttributes(IID, RetTy, Ptr, VarMask, Alignment, I,
2034 Stride),
2035 CostKind);
2036 }
2037 case Intrinsic::stepvector: {
2038 if (isa<ScalableVectorType>(RetTy))
2040 // The cost of materialising a constant integer vector.
2042 }
2043 case Intrinsic::vector_extract: {
2044 // FIXME: Handle case where a scalable vector is extracted from a scalable
2045 // vector
2046 if (isa<ScalableVectorType>(RetTy))
2048 unsigned Index = cast<ConstantInt>(Args[1])->getZExtValue();
2049 return thisT()->getShuffleCost(
2051 cast<VectorType>(Args[0]->getType()), CostKind, {}, Index,
2052 cast<VectorType>(RetTy));
2053 }
2054 case Intrinsic::vector_insert: {
2055 // FIXME: Handle case where a scalable vector is inserted into a scalable
2056 // vector
2057 if (isa<ScalableVectorType>(Args[1]->getType()))
2059 unsigned Index = cast<ConstantInt>(Args[2])->getZExtValue();
2060 return thisT()->getShuffleCost(
2062 cast<VectorType>(Args[0]->getType()), CostKind, {}, Index,
2063 cast<VectorType>(Args[1]->getType()));
2064 }
2065 case Intrinsic::vector_splice_left:
2066 case Intrinsic::vector_splice_right: {
2067 auto *COffset = dyn_cast<ConstantInt>(Args[2]);
2068 if (!COffset)
2069 break;
2070 unsigned Index = COffset->getZExtValue();
2071 return thisT()->getShuffleCost(
2073 cast<VectorType>(Args[0]->getType()), CostKind, {},
2074 IID == Intrinsic::vector_splice_left ? Index : -Index,
2075 cast<VectorType>(RetTy));
2076 }
2077 case Intrinsic::vector_reduce_add:
2078 case Intrinsic::vector_reduce_mul:
2079 case Intrinsic::vector_reduce_and:
2080 case Intrinsic::vector_reduce_or:
2081 case Intrinsic::vector_reduce_xor:
2082 case Intrinsic::vector_reduce_smax:
2083 case Intrinsic::vector_reduce_smin:
2084 case Intrinsic::vector_reduce_fmax:
2085 case Intrinsic::vector_reduce_fmin:
2086 case Intrinsic::vector_reduce_fmaximum:
2087 case Intrinsic::vector_reduce_fminimum:
2088 case Intrinsic::vector_reduce_fmaximumnum:
2089 case Intrinsic::vector_reduce_fminimumnum:
2090 case Intrinsic::vector_reduce_umax:
2091 case Intrinsic::vector_reduce_umin: {
2092 IntrinsicCostAttributes Attrs(IID, RetTy, Args[0]->getType(), FMF, I, 1);
2094 }
2095 case Intrinsic::vector_reduce_fadd:
2096 case Intrinsic::vector_reduce_fmul: {
2098 IID, RetTy, {Args[0]->getType(), Args[1]->getType()}, FMF, I, 1);
2100 }
2101 case Intrinsic::fshl:
2102 case Intrinsic::fshr: {
2103 const Value *X = Args[0];
2104 const Value *Y = Args[1];
2105 const Value *Z = Args[2];
2108 const TTI::OperandValueInfo OpInfoZ = TTI::getOperandInfo(Z);
2109
2110 // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
2111 // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
2113 Cost +=
2114 thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
2115 Cost += thisT()->getArithmeticInstrCost(
2116 BinaryOperator::Shl, RetTy, CostKind, OpInfoX,
2117 {OpInfoZ.Kind, TTI::OP_None});
2118 Cost += thisT()->getArithmeticInstrCost(
2119 BinaryOperator::LShr, RetTy, CostKind, OpInfoY,
2120 {OpInfoZ.Kind, TTI::OP_None});
2121
2122 if (!OpInfoZ.isConstant()) {
2123 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy,
2124 CostKind);
2125 // Non-constant shift amounts requires a modulo. If the typesize is a
2126 // power-2 then this will be converted to an and, otherwise it will use
2127 // a urem.
2128 Cost += thisT()->getArithmeticInstrCost(
2129 isPowerOf2_32(RetTy->getScalarSizeInBits()) ? BinaryOperator::And
2130 : BinaryOperator::URem,
2131 RetTy, CostKind, OpInfoZ,
2132 {TTI::OK_UniformConstantValue, TTI::OP_None});
2133 // For non-rotates (X != Y) we must add shift-by-zero handling costs.
2134 if (X != Y) {
2135 Type *CondTy = RetTy->getWithNewBitWidth(1);
2136 Cost += thisT()->getCmpSelInstrCost(
2137 BinaryOperator::ICmp, RetTy, CondTy, CmpInst::ICMP_EQ, CostKind);
2138 Cost +=
2139 thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
2141 }
2142 }
2143 return Cost;
2144 }
2145 case Intrinsic::experimental_cttz_elts: {
2146 EVT ArgType = getTLI()->getValueType(DL, ICA.getArgTypes()[0], true);
2147
2148 // TODO: The costs below reflect the expansion code in
2149 // TargetLowering::expandCttzElts, but we may want to sacrifice some
2150 // accuracy in favour of compile time.
2151
2152 // Find the smallest "sensible" element type to use for the expansion.
2153 bool ZeroIsPoison = !cast<ConstantInt>(Args[1])->isZero();
2154 ConstantRange VScaleRange(APInt(64, 1), APInt::getZero(64));
2155 if (isa<ScalableVectorType>(ICA.getArgTypes()[0]) && I && I->getCaller())
2156 VScaleRange = getVScaleRange(I->getCaller(), 64);
2157
2158 unsigned EltWidth = getTLI()->getBitWidthForCttzElements(
2159 getTLI()->getValueType(DL, RetTy), ArgType.getVectorElementCount(),
2160 ZeroIsPoison, &VScaleRange);
2161 Type *NewEltTy = IntegerType::getIntNTy(RetTy->getContext(), EltWidth);
2162
2163 // Create the new vector type & get the vector length
2164 Type *NewVecTy = VectorType::get(
2165 NewEltTy, cast<VectorType>(Args[0]->getType())->getElementCount());
2166
2167 IntrinsicCostAttributes StepVecAttrs(Intrinsic::stepvector, NewVecTy, {},
2168 FMF);
2170 thisT()->getIntrinsicInstrCost(StepVecAttrs, CostKind);
2171
2172 Cost +=
2173 thisT()->getArithmeticInstrCost(Instruction::Sub, NewVecTy, CostKind);
2174 Cost += thisT()->getCastInstrCost(Instruction::SExt, NewVecTy,
2175 Args[0]->getType(),
2177 Cost +=
2178 thisT()->getArithmeticInstrCost(Instruction::And, NewVecTy, CostKind);
2179
2180 IntrinsicCostAttributes ReducAttrs(Intrinsic::vector_reduce_umax,
2181 NewEltTy, NewVecTy, FMF, I, 1);
2182 Cost += thisT()->getTypeBasedIntrinsicInstrCost(ReducAttrs, CostKind);
2183 Cost +=
2184 thisT()->getArithmeticInstrCost(Instruction::Sub, NewEltTy, CostKind);
2185
2186 return Cost;
2187 }
2188 case Intrinsic::get_active_lane_mask:
2189 case Intrinsic::experimental_vector_match:
2190 case Intrinsic::experimental_vector_histogram_add:
2191 case Intrinsic::experimental_vector_histogram_uadd_sat:
2192 case Intrinsic::experimental_vector_histogram_umax:
2193 case Intrinsic::experimental_vector_histogram_umin:
2194 case Intrinsic::masked_udiv:
2195 case Intrinsic::masked_sdiv:
2196 case Intrinsic::masked_urem:
2197 case Intrinsic::masked_srem:
2198 return thisT()->getTypeBasedIntrinsicInstrCost(ICA, CostKind);
2199 case Intrinsic::modf:
2200 case Intrinsic::sincos:
2201 case Intrinsic::sincospi: {
2202 std::optional<unsigned> CallRetElementIndex;
2203 // The first element of the modf result is returned by value in the
2204 // libcall.
2205 if (ICA.getID() == Intrinsic::modf)
2206 CallRetElementIndex = 0;
2207
2208 if (auto Cost = getMultipleResultIntrinsicVectorLibCallCost(
2209 ICA, CostKind, CallRetElementIndex))
2210 return *Cost;
2211 // Otherwise, fallback to default scalarization cost.
2212 break;
2213 }
2214 case Intrinsic::loop_dependence_war_mask:
2215 case Intrinsic::loop_dependence_raw_mask: {
2216 // Compute the cost of the expanded version of these intrinsics:
2217 //
2218 // The possible expansions are...
2219 //
2220 // loop_dependence_war_mask:
2221 // diff = (addrB - addrA) / eltSize
2222 // cmp = icmp sle diff, 0
2223 // upper_bound = select cmp, -1, diff
2224 // mask = get_active_lane_mask 0, upper_bound
2225 //
2226 // loop_dependence_raw_mask:
2227 // diff = (abs(addrB - addrA)) / eltSize
2228 // cmp = icmp eq diff, 0
2229 // upper_bound = select cmp, -1, diff
2230 // mask = get_active_lane_mask 0, upper_bound
2231 //
2232 Type *AddrTy = ICA.getArgTypes()[0];
2233 bool IsReadAfterWrite = IID == Intrinsic::loop_dependence_raw_mask;
2234
2236 thisT()->getArithmeticInstrCost(Instruction::Sub, AddrTy, CostKind);
2237 if (IsReadAfterWrite) {
2238 IntrinsicCostAttributes AbsAttrs(Intrinsic::abs, AddrTy, {AddrTy}, {});
2239 Cost += thisT()->getIntrinsicInstrCost(AbsAttrs, CostKind);
2240 }
2241
2242 TTI::OperandValueInfo EltSizeOpInfo =
2243 TTI::getOperandInfo(ICA.getArgs()[2]);
2244 Cost += thisT()->getArithmeticInstrCost(Instruction::SDiv, AddrTy,
2245 CostKind, {}, EltSizeOpInfo);
2246
2247 Type *CondTy = IntegerType::getInt1Ty(RetTy->getContext());
2248 CmpInst::Predicate Pred =
2249 IsReadAfterWrite ? CmpInst::ICMP_EQ : CmpInst::ICMP_SLE;
2250 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, CondTy, AddrTy,
2251 Pred, CostKind);
2252 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, AddrTy,
2253 CondTy, Pred, CostKind);
2254
2255 IntrinsicCostAttributes Attrs(Intrinsic::get_active_lane_mask, RetTy,
2256 {AddrTy, AddrTy}, FMF);
2257 Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
2258 return Cost;
2259 }
2260 }
2261
2262 // Assume that we need to scalarize this intrinsic.)
2263 // Compute the scalarization overhead based on Args for a vector
2264 // intrinsic.
2265 InstructionCost ScalarizationCost = InstructionCost::getInvalid();
2266 if (RetVF.isVector() && !RetVF.isScalable()) {
2267 ScalarizationCost = 0;
2268 if (!RetTy->isVoidTy()) {
2269 for (Type *VectorTy : getContainedTypes(RetTy)) {
2270 ScalarizationCost += getScalarizationOverhead(
2271 cast<VectorType>(VectorTy),
2272 /*Insert=*/true, /*Extract=*/false, CostKind);
2273 }
2274 }
2275 ScalarizationCost += getOperandsScalarizationOverhead(
2276 filterConstantAndDuplicatedOperands(Args, ICA.getArgTypes()),
2277 CostKind);
2278 }
2279
2280 IntrinsicCostAttributes Attrs(IID, RetTy, ICA.getArgTypes(), FMF, I,
2281 ScalarizationCost);
2282 return thisT()->getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
2283 }
2284
2285 /// Get intrinsic cost based on argument types.
2286 /// If ScalarizationCostPassed is std::numeric_limits<unsigned>::max(), the
2287 /// cost of scalarizing the arguments and the return value will be computed
2288 /// based on types.
2292 Intrinsic::ID IID = ICA.getID();
2293 Type *RetTy = ICA.getReturnType();
2294 const SmallVectorImpl<Type *> &Tys = ICA.getArgTypes();
2295 FastMathFlags FMF = ICA.getFlags();
2296 InstructionCost ScalarizationCostPassed = ICA.getScalarizationCost();
2297 bool SkipScalarizationCost = ICA.skipScalarizationCost();
2298
2299 VectorType *VecOpTy = nullptr;
2300 if (!Tys.empty()) {
2301 // The vector reduction operand is operand 0 except for fadd/fmul.
2302 // Their operand 0 is a scalar start value, so the vector op is operand 1.
2303 unsigned VecTyIndex = 0;
2304 if (IID == Intrinsic::vector_reduce_fadd ||
2305 IID == Intrinsic::vector_reduce_fmul)
2306 VecTyIndex = 1;
2307 assert(Tys.size() > VecTyIndex && "Unexpected IntrinsicCostAttributes");
2308 VecOpTy = dyn_cast<VectorType>(Tys[VecTyIndex]);
2309 }
2310
2311 // Library call cost - other than size, make it expensive.
2312 unsigned SingleCallCost = CostKind == TTI::TCK_CodeSize ? 1 : 10;
2313 unsigned ISD = 0;
2314 switch (IID) {
2315 default: {
2316 // Scalable vectors cannot be scalarized, so return Invalid.
2317 if (isa<ScalableVectorType>(RetTy) || any_of(Tys, [](const Type *Ty) {
2318 return isa<ScalableVectorType>(Ty);
2319 }))
2321
2322 // Assume that we need to scalarize this intrinsic.
2323 InstructionCost ScalarizationCost =
2324 SkipScalarizationCost ? ScalarizationCostPassed : 0;
2325 unsigned ScalarCalls = 1;
2326 Type *ScalarRetTy = RetTy;
2327 if (auto *RetVTy = dyn_cast<VectorType>(RetTy)) {
2328 if (!SkipScalarizationCost)
2329 ScalarizationCost = getScalarizationOverhead(
2330 RetVTy, /*Insert*/ true, /*Extract*/ false, CostKind);
2331 ScalarCalls = std::max(ScalarCalls,
2332 cast<FixedVectorType>(RetVTy)->getNumElements());
2333 ScalarRetTy = RetTy->getScalarType();
2334 }
2335 SmallVector<Type *, 4> ScalarTys;
2336 for (Type *Ty : Tys) {
2337 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
2338 if (!SkipScalarizationCost)
2339 ScalarizationCost += getScalarizationOverhead(
2340 VTy, /*Insert*/ false, /*Extract*/ true, CostKind);
2341 ScalarCalls = std::max(ScalarCalls,
2342 cast<FixedVectorType>(VTy)->getNumElements());
2343 Ty = Ty->getScalarType();
2344 }
2345 ScalarTys.push_back(Ty);
2346 }
2347 if (ScalarCalls == 1)
2348 return 1; // Return cost of a scalar intrinsic. Assume it to be cheap.
2349
2350 IntrinsicCostAttributes ScalarAttrs(IID, ScalarRetTy, ScalarTys, FMF);
2351 InstructionCost ScalarCost =
2352 thisT()->getIntrinsicInstrCost(ScalarAttrs, CostKind);
2353
2354 return ScalarCalls * ScalarCost + ScalarizationCost;
2355 }
2356 // Look for intrinsics that can be lowered directly or turned into a scalar
2357 // intrinsic call.
2358 case Intrinsic::sqrt:
2359 ISD = ISD::FSQRT;
2360 break;
2361 case Intrinsic::sin:
2362 ISD = ISD::FSIN;
2363 break;
2364 case Intrinsic::cos:
2365 ISD = ISD::FCOS;
2366 break;
2367 case Intrinsic::sincos:
2368 ISD = ISD::FSINCOS;
2369 break;
2370 case Intrinsic::sincospi:
2372 break;
2373 case Intrinsic::modf:
2374 ISD = ISD::FMODF;
2375 break;
2376 case Intrinsic::tan:
2377 ISD = ISD::FTAN;
2378 break;
2379 case Intrinsic::asin:
2380 ISD = ISD::FASIN;
2381 break;
2382 case Intrinsic::acos:
2383 ISD = ISD::FACOS;
2384 break;
2385 case Intrinsic::atan:
2386 ISD = ISD::FATAN;
2387 break;
2388 case Intrinsic::atan2:
2389 ISD = ISD::FATAN2;
2390 break;
2391 case Intrinsic::sinh:
2392 ISD = ISD::FSINH;
2393 break;
2394 case Intrinsic::cosh:
2395 ISD = ISD::FCOSH;
2396 break;
2397 case Intrinsic::tanh:
2398 ISD = ISD::FTANH;
2399 break;
2400 case Intrinsic::exp:
2401 ISD = ISD::FEXP;
2402 break;
2403 case Intrinsic::exp2:
2404 ISD = ISD::FEXP2;
2405 break;
2406 case Intrinsic::exp10:
2407 ISD = ISD::FEXP10;
2408 break;
2409 case Intrinsic::log:
2410 ISD = ISD::FLOG;
2411 break;
2412 case Intrinsic::log10:
2413 ISD = ISD::FLOG10;
2414 break;
2415 case Intrinsic::log2:
2416 ISD = ISD::FLOG2;
2417 break;
2418 case Intrinsic::ldexp:
2419 ISD = ISD::FLDEXP;
2420 break;
2421 case Intrinsic::fabs:
2422 ISD = ISD::FABS;
2423 break;
2424 case Intrinsic::canonicalize:
2426 break;
2427 case Intrinsic::minnum:
2428 ISD = ISD::FMINNUM;
2429 break;
2430 case Intrinsic::maxnum:
2431 ISD = ISD::FMAXNUM;
2432 break;
2433 case Intrinsic::minimum:
2435 break;
2436 case Intrinsic::maximum:
2438 break;
2439 case Intrinsic::minimumnum:
2441 break;
2442 case Intrinsic::maximumnum:
2444 break;
2445 case Intrinsic::copysign:
2447 break;
2448 case Intrinsic::floor:
2449 ISD = ISD::FFLOOR;
2450 break;
2451 case Intrinsic::ceil:
2452 ISD = ISD::FCEIL;
2453 break;
2454 case Intrinsic::trunc:
2455 ISD = ISD::FTRUNC;
2456 break;
2457 case Intrinsic::nearbyint:
2459 break;
2460 case Intrinsic::rint:
2461 ISD = ISD::FRINT;
2462 break;
2463 case Intrinsic::lrint:
2464 ISD = ISD::LRINT;
2465 break;
2466 case Intrinsic::llrint:
2467 ISD = ISD::LLRINT;
2468 break;
2469 case Intrinsic::round:
2470 ISD = ISD::FROUND;
2471 break;
2472 case Intrinsic::roundeven:
2474 break;
2475 case Intrinsic::lround:
2476 ISD = ISD::LROUND;
2477 break;
2478 case Intrinsic::llround:
2479 ISD = ISD::LLROUND;
2480 break;
2481 case Intrinsic::pow:
2482 ISD = ISD::FPOW;
2483 break;
2484 case Intrinsic::fma:
2485 ISD = ISD::FMA;
2486 break;
2487 case Intrinsic::fmuladd:
2488 ISD = ISD::FMA;
2489 break;
2490 case Intrinsic::experimental_constrained_fmuladd:
2492 break;
2493 // FIXME: We should return 0 whenever getIntrinsicCost == TCC_Free.
2494 case Intrinsic::lifetime_start:
2495 case Intrinsic::lifetime_end:
2496 case Intrinsic::sideeffect:
2497 case Intrinsic::pseudoprobe:
2498 case Intrinsic::arithmetic_fence:
2499 return 0;
2500 case Intrinsic::masked_store: {
2501 Type *Ty = Tys[0];
2502 Align TyAlign = thisT()->DL.getABITypeAlign(Ty);
2503 return thisT()->getMemIntrinsicInstrCost(
2504 MemIntrinsicCostAttributes(IID, Ty, TyAlign, 0), CostKind);
2505 }
2506 case Intrinsic::masked_load: {
2507 Type *Ty = RetTy;
2508 Align TyAlign = thisT()->DL.getABITypeAlign(Ty);
2509 return thisT()->getMemIntrinsicInstrCost(
2510 MemIntrinsicCostAttributes(IID, Ty, TyAlign, 0), CostKind);
2511 }
2512 case Intrinsic::speculative_load: {
2513 const IntrinsicInst *I = ICA.getInst();
2514 Align Alignment = I ? I->getParamAlign(0).valueOrOne() : Align(1);
2515 unsigned AS = Tys[0]->getPointerAddressSpace();
2516 return thisT()->getMemIntrinsicInstrCost(
2517 MemIntrinsicCostAttributes(IID, RetTy, Alignment, AS), CostKind);
2518 }
2519 case Intrinsic::experimental_vp_strided_store: {
2520 auto *Ty = cast<VectorType>(ICA.getArgTypes()[0]);
2521 Align Alignment = thisT()->DL.getABITypeAlign(Ty->getElementType());
2522 return thisT()->getMemIntrinsicInstrCost(
2523 MemIntrinsicCostAttributes(IID, Ty, /*Ptr=*/nullptr,
2524 /*VariableMask=*/true, Alignment,
2525 ICA.getInst()),
2526 CostKind);
2527 }
2528 case Intrinsic::experimental_vp_strided_load: {
2529 auto *Ty = cast<VectorType>(ICA.getReturnType());
2530 Align Alignment = thisT()->DL.getABITypeAlign(Ty->getElementType());
2531 return thisT()->getMemIntrinsicInstrCost(
2532 MemIntrinsicCostAttributes(IID, Ty, /*Ptr=*/nullptr,
2533 /*VariableMask=*/true, Alignment,
2534 ICA.getInst()),
2535 CostKind);
2536 }
2537 case Intrinsic::vector_reduce_add:
2538 case Intrinsic::vector_reduce_mul:
2539 case Intrinsic::vector_reduce_and:
2540 case Intrinsic::vector_reduce_or:
2541 case Intrinsic::vector_reduce_xor:
2542 return thisT()->getArithmeticReductionCost(
2543 getArithmeticReductionInstruction(IID), VecOpTy, std::nullopt,
2544 CostKind);
2545 case Intrinsic::vector_reduce_fadd:
2546 case Intrinsic::vector_reduce_fmul:
2547 return thisT()->getArithmeticReductionCost(
2548 getArithmeticReductionInstruction(IID), VecOpTy, FMF, CostKind);
2549 case Intrinsic::vector_reduce_smax:
2550 case Intrinsic::vector_reduce_smin:
2551 case Intrinsic::vector_reduce_umax:
2552 case Intrinsic::vector_reduce_umin:
2553 case Intrinsic::vector_reduce_fmax:
2554 case Intrinsic::vector_reduce_fmin:
2555 case Intrinsic::vector_reduce_fmaximum:
2556 case Intrinsic::vector_reduce_fminimum:
2557 case Intrinsic::vector_reduce_fmaximumnum:
2558 case Intrinsic::vector_reduce_fminimumnum:
2559 return thisT()->getMinMaxReductionCost(getMinMaxReductionIntrinsicOp(IID),
2560 VecOpTy, ICA.getFlags(), CostKind);
2561 case Intrinsic::experimental_vector_match: {
2562 auto *SearchTy = cast<VectorType>(ICA.getArgTypes()[0]);
2563 auto *NeedleTy = cast<FixedVectorType>(ICA.getArgTypes()[1]);
2564 unsigned SearchSize = NeedleTy->getNumElements();
2565
2566 // Approximate the cost based on the expansion code in
2567 // TargetLowering::expandVectorMatch.
2569 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, NeedleTy,
2570 CostKind, 1, nullptr, nullptr);
2571 Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, SearchTy,
2572 CostKind, 0, nullptr, nullptr);
2573 Cost += thisT()->getShuffleCost(TTI::SK_Broadcast, SearchTy, SearchTy,
2574 CostKind, {}, 0, nullptr);
2575 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SearchTy, RetTy,
2577 Cost +=
2578 thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
2579 Cost *= SearchSize;
2580 Cost +=
2581 thisT()->getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
2582 return Cost;
2583 }
2584 case Intrinsic::vector_reverse:
2585 return thisT()->getShuffleCost(TTI::SK_Reverse, cast<VectorType>(RetTy),
2586 cast<VectorType>(ICA.getArgTypes()[0]),
2587 CostKind, {}, 0, cast<VectorType>(RetTy));
2588 case Intrinsic::experimental_vector_histogram_add:
2589 case Intrinsic::experimental_vector_histogram_uadd_sat:
2590 case Intrinsic::experimental_vector_histogram_umax:
2591 case Intrinsic::experimental_vector_histogram_umin: {
2593 Type *EltTy = ICA.getArgTypes()[1];
2594
2595 // Targets with scalable vectors must handle this on their own.
2596 if (!PtrsTy)
2598
2599 Align Alignment = thisT()->DL.getABITypeAlign(EltTy);
2601 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, PtrsTy,
2602 CostKind, 1, nullptr, nullptr);
2603 Cost += thisT()->getMemoryOpCost(Instruction::Load, EltTy, Alignment, 0,
2604 CostKind);
2605 switch (IID) {
2606 default:
2607 llvm_unreachable("Unhandled histogram update operation.");
2608 case Intrinsic::experimental_vector_histogram_add:
2609 Cost +=
2610 thisT()->getArithmeticInstrCost(Instruction::Add, EltTy, CostKind);
2611 break;
2612 case Intrinsic::experimental_vector_histogram_uadd_sat: {
2613 IntrinsicCostAttributes UAddSat(Intrinsic::uadd_sat, EltTy, {EltTy});
2614 Cost += thisT()->getIntrinsicInstrCost(UAddSat, CostKind);
2615 break;
2616 }
2617 case Intrinsic::experimental_vector_histogram_umax: {
2618 IntrinsicCostAttributes UMax(Intrinsic::umax, EltTy, {EltTy});
2619 Cost += thisT()->getIntrinsicInstrCost(UMax, CostKind);
2620 break;
2621 }
2622 case Intrinsic::experimental_vector_histogram_umin: {
2623 IntrinsicCostAttributes UMin(Intrinsic::umin, EltTy, {EltTy});
2624 Cost += thisT()->getIntrinsicInstrCost(UMin, CostKind);
2625 break;
2626 }
2627 }
2628 Cost += thisT()->getMemoryOpCost(Instruction::Store, EltTy, Alignment, 0,
2629 CostKind);
2630 Cost *= PtrsTy->getNumElements();
2631 return Cost;
2632 }
2633 case Intrinsic::get_active_lane_mask: {
2634 Type *ArgTy = ICA.getArgTypes()[0];
2635 EVT ResVT = getTLI()->getValueType(DL, RetTy, true);
2636 EVT ArgVT = getTLI()->getValueType(DL, ArgTy, true);
2637
2638 // If we're not expanding the intrinsic then we assume this is cheap
2639 // to implement.
2640 if (!getTLI()->shouldExpandGetActiveLaneMask(ResVT, ArgVT))
2641 return getTypeLegalizationCost(RetTy).first;
2642
2643 // Create the expanded types that will be used to calculate the uadd_sat
2644 // operation.
2645 Type *ExpRetTy =
2646 VectorType::get(ArgTy, cast<VectorType>(RetTy)->getElementCount());
2647 IntrinsicCostAttributes Attrs(Intrinsic::uadd_sat, ExpRetTy, {}, FMF);
2649 thisT()->getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
2650 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, ExpRetTy, RetTy,
2652 return Cost;
2653 }
2654 case Intrinsic::experimental_memset_pattern:
2655 // This cost is set to match the cost of the memset_pattern16 libcall.
2656 // It should likely be re-evaluated after migration to this intrinsic
2657 // is complete.
2658 return TTI::TCC_Basic * 4;
2659 case Intrinsic::abs:
2660 ISD = ISD::ABS;
2661 break;
2662 case Intrinsic::fshl:
2663 ISD = ISD::FSHL;
2664 break;
2665 case Intrinsic::fshr:
2666 ISD = ISD::FSHR;
2667 break;
2668 case Intrinsic::smax:
2669 ISD = ISD::SMAX;
2670 break;
2671 case Intrinsic::smin:
2672 ISD = ISD::SMIN;
2673 break;
2674 case Intrinsic::umax:
2675 ISD = ISD::UMAX;
2676 break;
2677 case Intrinsic::umin:
2678 ISD = ISD::UMIN;
2679 break;
2680 case Intrinsic::sadd_sat:
2681 ISD = ISD::SADDSAT;
2682 break;
2683 case Intrinsic::ssub_sat:
2684 ISD = ISD::SSUBSAT;
2685 break;
2686 case Intrinsic::uadd_sat:
2687 ISD = ISD::UADDSAT;
2688 break;
2689 case Intrinsic::usub_sat:
2690 ISD = ISD::USUBSAT;
2691 break;
2692 case Intrinsic::smul_fix:
2693 ISD = ISD::SMULFIX;
2694 break;
2695 case Intrinsic::umul_fix:
2696 ISD = ISD::UMULFIX;
2697 break;
2698 case Intrinsic::sadd_with_overflow:
2699 ISD = ISD::SADDO;
2700 break;
2701 case Intrinsic::ssub_with_overflow:
2702 ISD = ISD::SSUBO;
2703 break;
2704 case Intrinsic::uadd_with_overflow:
2705 ISD = ISD::UADDO;
2706 break;
2707 case Intrinsic::usub_with_overflow:
2708 ISD = ISD::USUBO;
2709 break;
2710 case Intrinsic::smul_with_overflow:
2711 ISD = ISD::SMULO;
2712 break;
2713 case Intrinsic::umul_with_overflow:
2714 ISD = ISD::UMULO;
2715 break;
2716 case Intrinsic::fptosi_sat:
2717 case Intrinsic::fptoui_sat: {
2718 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(Tys[0]);
2719 std::pair<InstructionCost, MVT> RetLT = getTypeLegalizationCost(RetTy);
2720
2721 // For cast instructions, types are different between source and
2722 // destination. Also need to check if the source type can be legalize.
2723 if (!SrcLT.first.isValid() || !RetLT.first.isValid())
2725 ISD = IID == Intrinsic::fptosi_sat ? ISD::FP_TO_SINT_SAT
2727 break;
2728 }
2729 case Intrinsic::ctpop:
2730 ISD = ISD::CTPOP;
2731 // In case of legalization use TCC_Expensive. This is cheaper than a
2732 // library call but still not a cheap instruction.
2733 SingleCallCost = TargetTransformInfo::TCC_Expensive;
2734 break;
2735 case Intrinsic::ctlz:
2736 ISD = ISD::CTLZ;
2737 break;
2738 case Intrinsic::cttz:
2739 ISD = ISD::CTTZ;
2740 break;
2741 case Intrinsic::bswap:
2742 ISD = ISD::BSWAP;
2743 break;
2744 case Intrinsic::bitreverse:
2746 break;
2747 case Intrinsic::ucmp:
2748 ISD = ISD::UCMP;
2749 break;
2750 case Intrinsic::scmp:
2751 ISD = ISD::SCMP;
2752 break;
2753 case Intrinsic::clmul:
2754 ISD = ISD::CLMUL;
2755 break;
2756 case Intrinsic::smulh:
2757 ISD = ISD::MULHS;
2758 break;
2759 case Intrinsic::umulh:
2760 ISD = ISD::MULHU;
2761 break;
2762 case Intrinsic::masked_udiv:
2763 case Intrinsic::masked_sdiv:
2764 case Intrinsic::masked_urem:
2765 case Intrinsic::masked_srem: {
2766 unsigned UnmaskedOpc;
2767 switch (IID) {
2768 case Intrinsic::masked_udiv:
2770 UnmaskedOpc = Instruction::UDiv;
2771 break;
2772 case Intrinsic::masked_sdiv:
2774 UnmaskedOpc = Instruction::SDiv;
2775 break;
2776 case Intrinsic::masked_urem:
2778 UnmaskedOpc = Instruction::URem;
2779 break;
2780 case Intrinsic::masked_srem:
2782 UnmaskedOpc = Instruction::SRem;
2783 break;
2784 default:
2785 llvm_unreachable("Unexpected intrinsic ID");
2786 }
2788 thisT()->getArithmeticInstrCost(UnmaskedOpc, RetTy, CostKind);
2789
2790 // Expansion generates a (select %mask, %rhs, 1) for the divisor.
2791 MVT LT = getTypeLegalizationCost(RetTy).second;
2792 if (!getTLI()->isOperationLegalOrCustom(ISD, LT)) {
2793 Type *CondTy = cast<VectorType>(RetTy)->getWithNewType(
2795 Cost += thisT()->getCmpSelInstrCost(
2796 BinaryOperator::Select, RetTy, CondTy, CmpInst::BAD_ICMP_PREDICATE,
2798 }
2799
2800 return Cost;
2801 }
2802 }
2803
2804 auto *ST = dyn_cast<StructType>(RetTy);
2805 Type *LegalizeTy = ST ? ST->getContainedType(0) : RetTy;
2806 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(LegalizeTy);
2807
2808 const TargetLoweringBase *TLI = getTLI();
2809
2810 if (TLI->isOperationLegalOrPromote(ISD, LT.second)) {
2811 if (IID == Intrinsic::fabs && LT.second.isFloatingPoint() &&
2812 TLI->isFAbsFree(LT.second)) {
2813 return 0;
2814 }
2815
2816 // The operation is legal. Assume it costs 1.
2817 // If the type is split to multiple registers, assume that there is some
2818 // overhead to this.
2819 // TODO: Once we have extract/insert subvector cost we need to use them.
2820 if (LT.first > 1)
2821 return (LT.first * 2);
2822 else
2823 return (LT.first * 1);
2824 } else if (TLI->isOperationCustom(ISD, LT.second)) {
2825 // If the operation is custom lowered then assume
2826 // that the code is twice as expensive.
2827 return (LT.first * 2);
2828 }
2829
2830 switch (IID) {
2831 case Intrinsic::fmuladd: {
2832 // If we can't lower fmuladd into an FMA estimate the cost as a floating
2833 // point mul followed by an add.
2834
2835 return thisT()->getArithmeticInstrCost(BinaryOperator::FMul, RetTy,
2836 CostKind) +
2837 thisT()->getArithmeticInstrCost(BinaryOperator::FAdd, RetTy,
2838 CostKind);
2839 }
2840 case Intrinsic::experimental_constrained_fmuladd: {
2841 IntrinsicCostAttributes FMulAttrs(
2842 Intrinsic::experimental_constrained_fmul, RetTy, Tys);
2843 IntrinsicCostAttributes FAddAttrs(
2844 Intrinsic::experimental_constrained_fadd, RetTy, Tys);
2845 return thisT()->getIntrinsicInstrCost(FMulAttrs, CostKind) +
2846 thisT()->getIntrinsicInstrCost(FAddAttrs, CostKind);
2847 }
2848 case Intrinsic::smin:
2849 case Intrinsic::smax:
2850 case Intrinsic::umin:
2851 case Intrinsic::umax: {
2852 // minmax(X,Y) = select(icmp(X,Y),X,Y)
2853 Type *CondTy = RetTy->getWithNewBitWidth(1);
2854 bool IsUnsigned = IID == Intrinsic::umax || IID == Intrinsic::umin;
2855 CmpInst::Predicate Pred =
2856 IsUnsigned ? CmpInst::ICMP_UGT : CmpInst::ICMP_SGT;
2858 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
2859 Pred, CostKind);
2860 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
2861 Pred, CostKind);
2862 return Cost;
2863 }
2864 case Intrinsic::sadd_with_overflow:
2865 case Intrinsic::ssub_with_overflow: {
2866 Type *SumTy = RetTy->getContainedType(0);
2867 Type *OverflowTy = RetTy->getContainedType(1);
2868 unsigned Opcode = IID == Intrinsic::sadd_with_overflow
2869 ? BinaryOperator::Add
2870 : BinaryOperator::Sub;
2871
2872 // Add:
2873 // Overflow -> (Result < LHS) ^ (RHS < 0)
2874 // Sub:
2875 // Overflow -> (Result < LHS) ^ (RHS > 0)
2877 Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
2878 Cost +=
2879 2 * thisT()->getCmpSelInstrCost(Instruction::ICmp, SumTy, OverflowTy,
2881 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::Xor, OverflowTy,
2882 CostKind);
2883 return Cost;
2884 }
2885 case Intrinsic::uadd_with_overflow:
2886 case Intrinsic::usub_with_overflow: {
2887 Type *SumTy = RetTy->getContainedType(0);
2888 Type *OverflowTy = RetTy->getContainedType(1);
2889 unsigned Opcode = IID == Intrinsic::uadd_with_overflow
2890 ? BinaryOperator::Add
2891 : BinaryOperator::Sub;
2892 CmpInst::Predicate Pred = IID == Intrinsic::uadd_with_overflow
2895
2897 Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
2898 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy,
2899 OverflowTy, Pred, CostKind);
2900 return Cost;
2901 }
2902 case Intrinsic::smul_with_overflow:
2903 case Intrinsic::umul_with_overflow: {
2904 Type *MulTy = RetTy->getContainedType(0);
2905 Type *OverflowTy = RetTy->getContainedType(1);
2906 unsigned ExtSize = MulTy->getScalarSizeInBits() * 2;
2907 Type *ExtTy = MulTy->getWithNewBitWidth(ExtSize);
2908 bool IsSigned = IID == Intrinsic::smul_with_overflow;
2909
2910 unsigned ExtOp = IsSigned ? Instruction::SExt : Instruction::ZExt;
2912
2914 Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, MulTy, CCH, CostKind);
2915 Cost +=
2916 thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
2917 Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, MulTy, ExtTy,
2918 CCH, CostKind);
2919 Cost += thisT()->getArithmeticInstrCost(
2920 Instruction::LShr, ExtTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
2922
2923 if (IsSigned)
2924 Cost += thisT()->getArithmeticInstrCost(
2925 Instruction::AShr, MulTy, CostKind,
2928
2929 Cost += thisT()->getCmpSelInstrCost(
2930 BinaryOperator::ICmp, MulTy, OverflowTy, CmpInst::ICMP_NE, CostKind);
2931 return Cost;
2932 }
2933 case Intrinsic::sadd_sat:
2934 case Intrinsic::ssub_sat: {
2935 // Assume a default expansion.
2936 Type *CondTy = RetTy->getWithNewBitWidth(1);
2937
2938 Type *OpTy = StructType::create({RetTy, CondTy});
2939 Intrinsic::ID OverflowOp = IID == Intrinsic::sadd_sat
2940 ? Intrinsic::sadd_with_overflow
2941 : Intrinsic::ssub_with_overflow;
2943
2944 // SatMax -> Overflow && SumDiff < 0
2945 // SatMin -> Overflow && SumDiff >= 0
2947 IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
2948 nullptr, ScalarizationCostPassed);
2949 Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
2950 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
2951 Pred, CostKind);
2952 Cost += 2 * thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
2953 CondTy, Pred, CostKind);
2954 return Cost;
2955 }
2956 case Intrinsic::uadd_sat:
2957 case Intrinsic::usub_sat: {
2958 Type *CondTy = RetTy->getWithNewBitWidth(1);
2959
2960 Type *OpTy = StructType::create({RetTy, CondTy});
2961 Intrinsic::ID OverflowOp = IID == Intrinsic::uadd_sat
2962 ? Intrinsic::uadd_with_overflow
2963 : Intrinsic::usub_with_overflow;
2964
2966 IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
2967 nullptr, ScalarizationCostPassed);
2968 Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
2969 Cost +=
2970 thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
2972 return Cost;
2973 }
2974 case Intrinsic::smul_fix:
2975 case Intrinsic::umul_fix: {
2976 unsigned ExtSize = RetTy->getScalarSizeInBits() * 2;
2977 Type *ExtTy = RetTy->getWithNewBitWidth(ExtSize);
2978
2979 unsigned ExtOp =
2980 IID == Intrinsic::smul_fix ? Instruction::SExt : Instruction::ZExt;
2982
2984 Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, RetTy, CCH, CostKind);
2985 Cost +=
2986 thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
2987 Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, RetTy, ExtTy,
2988 CCH, CostKind);
2989 Cost += thisT()->getArithmeticInstrCost(
2990 Instruction::LShr, RetTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
2992 Cost += thisT()->getArithmeticInstrCost(
2993 Instruction::Shl, RetTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
2995 Cost += thisT()->getArithmeticInstrCost(Instruction::Or, RetTy, CostKind);
2996 return Cost;
2997 }
2998 case Intrinsic::abs: {
2999 // abs(X) = select(icmp(X,0),X,sub(0,X))
3000 Type *CondTy = RetTy->getWithNewBitWidth(1);
3003 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
3004 Pred, CostKind);
3005 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
3006 Pred, CostKind);
3007 // TODO: Should we add an OperandValueProperties::OP_Zero property?
3008 Cost += thisT()->getArithmeticInstrCost(
3009 BinaryOperator::Sub, RetTy, CostKind,
3011 return Cost;
3012 }
3013 case Intrinsic::fshl:
3014 case Intrinsic::fshr: {
3015 // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
3016 // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
3017 Type *CondTy = RetTy->getWithNewBitWidth(1);
3019 Cost +=
3020 thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
3021 Cost +=
3022 thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
3023 Cost +=
3024 thisT()->getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
3025 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::LShr, RetTy,
3026 CostKind);
3027 // Non-constant shift amounts requires a modulo. If the typesize is a
3028 // power-2 then this will be converted to an and, otherwise it will use a
3029 // urem.
3030 Cost += thisT()->getArithmeticInstrCost(
3031 isPowerOf2_32(RetTy->getScalarSizeInBits()) ? BinaryOperator::And
3032 : BinaryOperator::URem,
3033 RetTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3034 {TTI::OK_UniformConstantValue, TTI::OP_None});
3035 // Shift-by-zero handling.
3036 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
3038 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
3040 return Cost;
3041 }
3042 case Intrinsic::fptosi_sat:
3043 case Intrinsic::fptoui_sat: {
3044 if (Tys.empty())
3045 break;
3046 Type *FromTy = Tys[0];
3047 bool IsSigned = IID == Intrinsic::fptosi_sat;
3048
3050 IntrinsicCostAttributes Attrs1(Intrinsic::minnum, FromTy,
3051 {FromTy, FromTy});
3052 Cost += thisT()->getIntrinsicInstrCost(Attrs1, CostKind);
3053 IntrinsicCostAttributes Attrs2(Intrinsic::maxnum, FromTy,
3054 {FromTy, FromTy});
3055 Cost += thisT()->getIntrinsicInstrCost(Attrs2, CostKind);
3056 Cost += thisT()->getCastInstrCost(
3057 IsSigned ? Instruction::FPToSI : Instruction::FPToUI, RetTy, FromTy,
3059 if (IsSigned) {
3060 Type *CondTy = RetTy->getWithNewBitWidth(1);
3061 Cost += thisT()->getCmpSelInstrCost(
3062 BinaryOperator::FCmp, FromTy, CondTy, CmpInst::FCMP_UNO, CostKind);
3063 Cost += thisT()->getCmpSelInstrCost(
3064 BinaryOperator::Select, RetTy, CondTy, CmpInst::FCMP_UNO, CostKind);
3065 }
3066 return Cost;
3067 }
3068 case Intrinsic::ucmp:
3069 case Intrinsic::scmp: {
3070 Type *CmpTy = Tys[0];
3071 Type *CondTy = RetTy->getWithNewBitWidth(1);
3073 thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, CmpTy, CondTy,
3075 CostKind) +
3076 thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, CmpTy, CondTy,
3078 CostKind);
3079
3080 EVT VT = TLI->getValueType(DL, CmpTy, true);
3082 // x < y ? -1 : (x > y ? 1 : 0)
3083 Cost += 2 * thisT()->getCmpSelInstrCost(
3084 BinaryOperator::Select, RetTy, CondTy,
3086 } else {
3087 // zext(x > y) - zext(x < y)
3088 Cost +=
3089 2 * thisT()->getCastInstrCost(CastInst::ZExt, RetTy, CondTy,
3091 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy,
3092 CostKind);
3093 }
3094 return Cost;
3095 }
3096 case Intrinsic::maximumnum:
3097 case Intrinsic::minimumnum: {
3098 // On platform that support FMAXNUM_IEEE/FMINNUM_IEEE, we expand
3099 // maximumnum/minimumnum to
3100 // ARG0 = fcanonicalize ARG0, ARG0 // to quiet ARG0
3101 // ARG1 = fcanonicalize ARG1, ARG1 // to quiet ARG1
3102 // RESULT = MAXNUM_IEEE ARG0, ARG1 // or MINNUM_IEEE
3103 // FIXME: In LangRef, we claimed FMAXNUM has the same behaviour of
3104 // FMAXNUM_IEEE, while the backend hasn't migrated the code yet.
3105 // Finally, we will remove FMAXNUM_IEEE and FMINNUM_IEEE.
3106 int IeeeISD =
3107 IID == Intrinsic::maximumnum ? ISD::FMAXNUM_IEEE : ISD::FMINNUM_IEEE;
3108 if (TLI->isOperationLegal(IeeeISD, LT.second)) {
3109 IntrinsicCostAttributes FCanonicalizeAttrs(Intrinsic::canonicalize,
3110 RetTy, Tys[0]);
3111 InstructionCost FCanonicalizeCost =
3112 thisT()->getIntrinsicInstrCost(FCanonicalizeAttrs, CostKind);
3113 return LT.first + FCanonicalizeCost * 2;
3114 }
3115 break;
3116 }
3117 case Intrinsic::clmul: {
3118 // This cost model should match the expansion in
3119 // TargetLowering::expandCLMUL.
3120 unsigned BW = RetTy->getScalarSizeInBits();
3121 InstructionCost AndCost =
3122 thisT()->getArithmeticInstrCost(Instruction::And, RetTy, CostKind);
3123 InstructionCost OrCost =
3124 thisT()->getArithmeticInstrCost(Instruction::Or, RetTy, CostKind);
3125 InstructionCost XorCost =
3126 thisT()->getArithmeticInstrCost(Instruction::Xor, RetTy, CostKind);
3127 InstructionCost MulCost =
3128 thisT()->getArithmeticInstrCost(Instruction::Mul, RetTy, CostKind);
3129
3130 // When the multiplication with holes approach is used, it splits the
3131 // operands into S phases (the smallest stride with ceil(BW/S) <= 2^S) and
3132 // emits S*S MULs, 3*S ANDs, S*(S-1) XORs and S-1 ORs.
3133 //
3134 // * BW <= 8 uses S = 2
3135 // * BW <= 24 uses S = 3
3136 // * BW <= 64 uses S = 4
3137 // * BW <= 160 uses S = 5
3138 // * BW <= 384 uses S = 6
3139 unsigned S = 1;
3140 while (S < 32 && divideCeil(BW, S) > (1u << S))
3141 ++S;
3142
3143 // The naive algorithm usually uses AND+MUL+XOR per bit.
3144 unsigned NaiveCost = 3 * BW;
3145 unsigned HolesCost = S * S + 3 * S + S * (S - 1) + (S - 1);
3146
3147 if (HolesCost < NaiveCost &&
3149 TLI->getValueType(DL, RetTy))) {
3150 return S * S * MulCost + 3 * S * AndCost + S * (S - 1) * XorCost +
3151 (S - 1) * OrCost;
3152 }
3153
3154 InstructionCost PerBitCostMul = AndCost + MulCost + XorCost;
3155 InstructionCost PerBitCostBittest =
3156 AndCost +
3157 thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, RetTy,
3159 thisT()->getCmpSelInstrCost(Instruction::ICmp, RetTy, RetTy,
3161 InstructionCost PerBitCost = std::min(PerBitCostMul, PerBitCostBittest);
3162 return BW * PerBitCost;
3163 }
3164 case Intrinsic::smulh:
3165 case Intrinsic::umulh: {
3166 unsigned BW = RetTy->getScalarSizeInBits();
3167 Type *WideTy = RetTy->getWithNewBitWidth(BW * 2);
3168 bool IsSigned = IID == Intrinsic::smulh;
3169 unsigned ExtOp = IsSigned ? Instruction::SExt : Instruction::ZExt;
3171 Cost +=
3172 2 * thisT()->getCastInstrCost(ExtOp, WideTy, RetTy,
3174 Cost +=
3175 thisT()->getArithmeticInstrCost(Instruction::Mul, WideTy, CostKind);
3176 Cost += thisT()->getArithmeticInstrCost(
3177 Instruction::LShr, WideTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3179 Cost += thisT()->getCastInstrCost(Instruction::Trunc, RetTy, WideTy,
3181 return Cost;
3182 }
3183 default:
3184 break;
3185 }
3186
3187 // Else, assume that we need to scalarize this intrinsic. For math builtins
3188 // this will emit a costly libcall, adding call overhead and spills. Make it
3189 // very expensive.
3190 if (isVectorizedTy(RetTy)) {
3191 ArrayRef<Type *> RetVTys = getContainedTypes(RetTy);
3192
3193 // Scalable vectors cannot be scalarized, so return Invalid.
3194 if (any_of(concat<Type *const>(RetVTys, Tys),
3195 [](Type *Ty) { return isa<ScalableVectorType>(Ty); }))
3197
3198 InstructionCost ScalarizationCost = ScalarizationCostPassed;
3199 if (!SkipScalarizationCost) {
3200 ScalarizationCost = 0;
3201 for (Type *RetVTy : RetVTys) {
3202 ScalarizationCost += getScalarizationOverhead(
3203 cast<VectorType>(RetVTy), /*Insert=*/true,
3204 /*Extract=*/false, CostKind);
3205 }
3206 }
3207
3208 unsigned ScalarCalls = getVectorizedTypeVF(RetTy).getFixedValue();
3209 SmallVector<Type *, 4> ScalarTys;
3210 for (Type *Ty : Tys) {
3211 if (Ty->isVectorTy())
3212 Ty = Ty->getScalarType();
3213 ScalarTys.push_back(Ty);
3214 }
3215 IntrinsicCostAttributes Attrs(IID, toScalarizedTy(RetTy), ScalarTys, FMF);
3216 InstructionCost ScalarCost =
3217 thisT()->getIntrinsicInstrCost(Attrs, CostKind);
3218 for (Type *Ty : Tys) {
3219 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
3220 if (!ICA.skipScalarizationCost())
3221 ScalarizationCost += getScalarizationOverhead(
3222 VTy, /*Insert*/ false, /*Extract*/ true, CostKind);
3223 ScalarCalls = std::max(ScalarCalls,
3224 cast<FixedVectorType>(VTy)->getNumElements());
3225 }
3226 }
3227 return ScalarCalls * ScalarCost + ScalarizationCost;
3228 }
3229
3230 // This is going to be turned into a library call, make it expensive.
3231 return SingleCallCost;
3232 }
3233
3234 /// Get memory intrinsic cost based on arguments.
3237 TTI::TargetCostKind CostKind) const override {
3238 unsigned Id = MICA.getID();
3239 Type *DataTy = MICA.getDataType();
3240 bool VariableMask = MICA.getVariableMask();
3241 Align Alignment = MICA.getAlignment();
3242
3243 switch (Id) {
3244 case Intrinsic::experimental_vp_strided_load:
3245 case Intrinsic::experimental_vp_strided_store: {
3246 unsigned Opcode = Id == Intrinsic::experimental_vp_strided_load
3247 ? Instruction::Load
3248 : Instruction::Store;
3249 // For a target without strided memory operations (or for an illegal
3250 // operation type on one which does), assume we lower to a gather/scatter
3251 // operation. (Which may in turn be scalarized.)
3252 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment,
3253 VariableMask, true, CostKind);
3254 }
3255 case Intrinsic::masked_scatter:
3256 case Intrinsic::masked_gather:
3257 case Intrinsic::vp_scatter:
3258 case Intrinsic::vp_gather: {
3259 unsigned Opcode = (MICA.getID() == Intrinsic::masked_gather ||
3260 MICA.getID() == Intrinsic::vp_gather)
3261 ? Instruction::Load
3262 : Instruction::Store;
3263
3264 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment,
3265 VariableMask, true, CostKind);
3266 }
3267 case Intrinsic::vp_load:
3268 case Intrinsic::vp_store:
3270 case Intrinsic::masked_load:
3271 case Intrinsic::masked_store: {
3272 unsigned Opcode =
3273 Id == Intrinsic::masked_load ? Instruction::Load : Instruction::Store;
3274 // TODO: Pass on AddressSpace when we have test coverage.
3275 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment, true, false,
3276 CostKind);
3277 }
3278 case Intrinsic::masked_compressstore:
3279 case Intrinsic::masked_expandload: {
3280 unsigned Opcode = MICA.getID() == Intrinsic::masked_expandload
3281 ? Instruction::Load
3282 : Instruction::Store;
3283 // Treat expand load/compress store as gather/scatter operation.
3284 // TODO: implement more precise cost estimation for these intrinsics.
3285 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment,
3286 VariableMask,
3287 /*IsGatherScatter*/ true, CostKind);
3288 }
3289 case Intrinsic::vp_load_ff:
3291 case Intrinsic::speculative_load:
3292 // Speculative loads are lowered to regular loads of the full type.
3293 return thisT()->getMemoryOpCost(Instruction::Load, DataTy, Alignment,
3294 MICA.getAddressSpace(), CostKind);
3295 default:
3296 llvm_unreachable("unexpected intrinsic");
3297 }
3298 }
3299
3300 /// Compute a cost of the given call instruction.
3301 ///
3302 /// Compute the cost of calling function F with return type RetTy and
3303 /// argument types Tys. F might be nullptr, in this case the cost of an
3304 /// arbitrary call with the specified signature will be returned.
3305 /// This is used, for instance, when we estimate call of a vector
3306 /// counterpart of the given function.
3307 /// \param F Called function, might be nullptr.
3308 /// \param RetTy Return value types.
3309 /// \param Tys Argument types.
3310 /// \returns The cost of Call instruction.
3313 TTI::TargetCostKind CostKind) const override {
3314 return 10;
3315 }
3316
3317 unsigned getNumberOfParts(Type *Tp) const override {
3318 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Tp);
3319 if (!LT.first.isValid())
3320 return 0;
3321 // Try to find actual number of parts for non-power-of-2 elements as
3322 // ceil(num-of-elements/num-of-subtype-elements).
3323 if (auto *FTp = dyn_cast<FixedVectorType>(Tp);
3324 FTp && LT.second.isFixedLengthVector() &&
3325 !has_single_bit(FTp->getNumElements())) {
3326 if (auto *SubTp = dyn_cast_if_present<FixedVectorType>(
3327 EVT(LT.second).getTypeForEVT(Tp->getContext()));
3328 SubTp && SubTp->getElementType() == FTp->getElementType())
3329 return divideCeil(FTp->getNumElements(), SubTp->getNumElements());
3330 }
3331 return LT.first.getValue();
3332 }
3333
3336 TTI::TargetCostKind) const override {
3337 return 0;
3338 }
3339
3340 /// Try to calculate arithmetic and shuffle op costs for reduction intrinsics.
3341 /// We're assuming that reduction operation are performing the following way:
3342 ///
3343 /// %val1 = shufflevector<n x t> %val, <n x t> %undef,
3344 /// <n x i32> <i32 n/2, i32 n/2 + 1, ..., i32 n, i32 undef, ..., i32 undef>
3345 /// \----------------v-------------/ \----------v------------/
3346 /// n/2 elements n/2 elements
3347 /// %red1 = op <n x t> %val, <n x t> val1
3348 /// After this operation we have a vector %red1 where only the first n/2
3349 /// elements are meaningful, the second n/2 elements are undefined and can be
3350 /// dropped. All other operations are actually working with the vector of
3351 /// length n/2, not n, though the real vector length is still n.
3352 /// %val2 = shufflevector<n x t> %red1, <n x t> %undef,
3353 /// <n x i32> <i32 n/4, i32 n/4 + 1, ..., i32 n/2, i32 undef, ..., i32 undef>
3354 /// \----------------v-------------/ \----------v------------/
3355 /// n/4 elements 3*n/4 elements
3356 /// %red2 = op <n x t> %red1, <n x t> val2 - working with the vector of
3357 /// length n/2, the resulting vector has length n/4 etc.
3358 ///
3359 /// The cost model should take into account that the actual length of the
3360 /// vector is reduced on each iteration.
3363 // Targets must implement a default value for the scalable case, since
3364 // we don't know how many lanes the vector has.
3367
3368 Type *ScalarTy = Ty->getElementType();
3369 unsigned NumVecElts = cast<FixedVectorType>(Ty)->getNumElements();
3370 if ((Opcode == Instruction::Or || Opcode == Instruction::And) &&
3371 ScalarTy == IntegerType::getInt1Ty(Ty->getContext()) &&
3372 NumVecElts >= 2) {
3373 // Or reduction for i1 is represented as:
3374 // %val = bitcast <ReduxWidth x i1> to iReduxWidth
3375 // %res = cmp ne iReduxWidth %val, 0
3376 // And reduction for i1 is represented as:
3377 // %val = bitcast <ReduxWidth x i1> to iReduxWidth
3378 // %res = cmp eq iReduxWidth %val, 11111
3379 Type *ValTy = IntegerType::get(Ty->getContext(), NumVecElts);
3380 return thisT()->getCastInstrCost(Instruction::BitCast, ValTy, Ty,
3382 thisT()->getCmpSelInstrCost(Instruction::ICmp, ValTy,
3385 }
3386 unsigned NumReduxLevels = Log2_32(NumVecElts);
3387 InstructionCost ArithCost = 0;
3388 InstructionCost ShuffleCost = 0;
3389 std::pair<InstructionCost, MVT> LT = thisT()->getTypeLegalizationCost(Ty);
3390 unsigned LongVectorCount = 0;
3391 unsigned MVTLen =
3392 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
3393 while (NumVecElts > MVTLen) {
3394 NumVecElts /= 2;
3395 VectorType *SubTy = FixedVectorType::get(ScalarTy, NumVecElts);
3396 ShuffleCost += thisT()->getShuffleCost(
3397 TTI::SK_ExtractSubvector, SubTy, Ty, CostKind, {}, NumVecElts, SubTy);
3398 ArithCost += thisT()->getArithmeticInstrCost(Opcode, SubTy, CostKind);
3399 Ty = SubTy;
3400 ++LongVectorCount;
3401 }
3402
3403 NumReduxLevels -= LongVectorCount;
3404
3405 // The minimal length of the vector is limited by the real length of vector
3406 // operations performed on the current platform. That's why several final
3407 // reduction operations are performed on the vectors with the same
3408 // architecture-dependent length.
3409
3410 // By default reductions need one shuffle per reduction level.
3411 ShuffleCost +=
3412 NumReduxLevels * thisT()->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
3413 Ty, CostKind, {}, 0, Ty);
3414 ArithCost +=
3415 NumReduxLevels * thisT()->getArithmeticInstrCost(Opcode, Ty, CostKind);
3416 return ShuffleCost + ArithCost +
3417 thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty,
3418 CostKind, 0, nullptr, nullptr);
3419 }
3420
3421 /// Try to calculate the cost of performing strict (in-order) reductions,
3422 /// which involves doing a sequence of floating point additions in lane
3423 /// order, starting with an initial value. For example, consider a scalar
3424 /// initial value 'InitVal' of type float and a vector of type <4 x float>:
3425 ///
3426 /// Vector = <float %v0, float %v1, float %v2, float %v3>
3427 ///
3428 /// %add1 = %InitVal + %v0
3429 /// %add2 = %add1 + %v1
3430 /// %add3 = %add2 + %v2
3431 /// %add4 = %add3 + %v3
3432 ///
3433 /// As a simple estimate we can say the cost of such a reduction is 4 times
3434 /// the cost of a scalar FP addition. We can only estimate the costs for
3435 /// fixed-width vectors here because for scalable vectors we do not know the
3436 /// runtime number of operations.
3439 // Targets must implement a default value for the scalable case, since
3440 // we don't know how many lanes the vector has.
3443
3444 auto *VTy = cast<FixedVectorType>(Ty);
3446 VTy, /*Insert=*/false, /*Extract=*/true, CostKind);
3447 InstructionCost ArithCost = thisT()->getArithmeticInstrCost(
3448 Opcode, VTy->getElementType(), CostKind);
3449 ArithCost *= VTy->getNumElements();
3450
3451 return ExtractCost + ArithCost;
3452 }
3453
3456 std::optional<FastMathFlags> FMF,
3457 TTI::TargetCostKind CostKind) const override {
3458 assert(Ty && "Unknown reduction vector type");
3460 return getOrderedReductionCost(Opcode, Ty, CostKind);
3461 return getTreeReductionCost(Opcode, Ty, CostKind);
3462 }
3463
3464 /// Try to calculate op costs for min/max reduction operations.
3465 /// \param CondTy Conditional type for the Select instruction.
3468 TTI::TargetCostKind CostKind) const override {
3469 // Targets must implement a default value for the scalable case, since
3470 // we don't know how many lanes the vector has.
3473
3474 Type *ScalarTy = Ty->getElementType();
3475 unsigned NumVecElts = cast<FixedVectorType>(Ty)->getNumElements();
3476 unsigned NumReduxLevels = Log2_32(NumVecElts);
3477 InstructionCost MinMaxCost = 0;
3478 InstructionCost ShuffleCost = 0;
3479 std::pair<InstructionCost, MVT> LT = thisT()->getTypeLegalizationCost(Ty);
3480 unsigned LongVectorCount = 0;
3481 unsigned MVTLen =
3482 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
3483 while (NumVecElts > MVTLen) {
3484 NumVecElts /= 2;
3485 auto *SubTy = FixedVectorType::get(ScalarTy, NumVecElts);
3486
3487 ShuffleCost += thisT()->getShuffleCost(
3488 TTI::SK_ExtractSubvector, SubTy, Ty, CostKind, {}, NumVecElts, SubTy);
3489
3490 IntrinsicCostAttributes Attrs(IID, SubTy, {SubTy, SubTy}, FMF);
3491 MinMaxCost += getIntrinsicInstrCost(Attrs, CostKind);
3492 Ty = SubTy;
3493 ++LongVectorCount;
3494 }
3495
3496 NumReduxLevels -= LongVectorCount;
3497
3498 // The minimal length of the vector is limited by the real length of vector
3499 // operations performed on the current platform. That's why several final
3500 // reduction opertions are perfomed on the vectors with the same
3501 // architecture-dependent length.
3502 ShuffleCost +=
3503 NumReduxLevels * thisT()->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
3504 Ty, CostKind, {}, 0, Ty);
3505 IntrinsicCostAttributes Attrs(IID, Ty, {Ty, Ty}, FMF);
3506 MinMaxCost += NumReduxLevels * getIntrinsicInstrCost(Attrs, CostKind);
3507 // The last min/max should be in vector registers and we counted it above.
3508 // So just need a single extractelement.
3509 return ShuffleCost + MinMaxCost +
3510 thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty,
3511 CostKind, 0, nullptr, nullptr);
3512 }
3513
3515 getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy,
3516 VectorType *Ty, std::optional<FastMathFlags> FMF,
3517 TTI::TargetCostKind CostKind) const override {
3518 if (auto *FTy = dyn_cast<FixedVectorType>(Ty);
3519 FTy && IsUnsigned && Opcode == Instruction::Add &&
3520 FTy->getElementType() == IntegerType::getInt1Ty(Ty->getContext())) {
3521 // Represent vector_reduce_add(ZExt(<n x i1>)) as
3522 // ZExtOrTrunc(ctpop(bitcast <n x i1> to in)).
3523 auto *IntTy =
3524 IntegerType::get(ResTy->getContext(), FTy->getNumElements());
3525 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy},
3526 FMF ? *FMF : FastMathFlags());
3527 return thisT()->getCastInstrCost(Instruction::BitCast, IntTy, FTy,
3529 thisT()->getIntrinsicInstrCost(ICA, CostKind);
3530 }
3531 // Without any native support, this is equivalent to the cost of
3532 // vecreduce.opcode(ext(Ty A)).
3533 VectorType *ExtTy = VectorType::get(ResTy, Ty);
3534 InstructionCost RedCost =
3535 thisT()->getArithmeticReductionCost(Opcode, ExtTy, FMF, CostKind);
3536 InstructionCost ExtCost = thisT()->getCastInstrCost(
3537 IsUnsigned ? Instruction::ZExt : Instruction::SExt, ExtTy, Ty,
3539
3540 return RedCost + ExtCost;
3541 }
3542
3544 getMulAccReductionCost(bool IsUnsigned, unsigned RedOpcode, Type *ResTy,
3545 VectorType *Ty,
3546 TTI::TargetCostKind CostKind) const override {
3547 // Without any native support, this is equivalent to the cost of
3548 // vecreduce.add(mul(ext(Ty A), ext(Ty B))) or
3549 // vecreduce.add(mul(A, B)).
3550 assert((RedOpcode == Instruction::Add || RedOpcode == Instruction::Sub) &&
3551 "The reduction opcode is expected to be Add or Sub.");
3552 VectorType *ExtTy = VectorType::get(ResTy, Ty);
3553 InstructionCost RedCost = thisT()->getArithmeticReductionCost(
3554 RedOpcode, ExtTy, std::nullopt, CostKind);
3555 InstructionCost ExtCost = thisT()->getCastInstrCost(
3556 IsUnsigned ? Instruction::ZExt : Instruction::SExt, ExtTy, Ty,
3558
3559 InstructionCost MulCost =
3560 thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
3561
3562 return RedCost + MulCost + 2 * ExtCost;
3563 }
3564
3566 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
3568 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
3570 std::optional<FastMathFlags> FMF) const override {
3571 unsigned EltSizeAcc = AccumType->getScalarSizeInBits();
3572 unsigned EltSizeInA = InputTypeA->getScalarSizeInBits();
3573 unsigned Ratio = EltSizeAcc / EltSizeInA;
3574 if (VF.getKnownMinValue() <= Ratio || VF.getKnownMinValue() % Ratio != 0 ||
3575 EltSizeAcc % EltSizeInA != 0 || (BinOp && InputTypeA != InputTypeB))
3577
3578 Type *InputVectorType = VectorType::get(InputTypeA, VF);
3579 Type *ExtInputVectorType = VectorType::get(AccumType, VF);
3580 Type *AccumVectorType =
3581 VectorType::get(AccumType, VF.divideCoefficientBy(Ratio));
3582
3583 InstructionCost ExtendCostA = 0;
3585 ExtendCostA = getCastInstrCost(
3587 ExtInputVectorType, InputVectorType, TTI::CastContextHint::None,
3588 CostKind);
3589
3590 // TODO: add cost of extracting subvectors from the source vector that
3591 // is to be partially reduced.
3592 InstructionCost ReductionOpCost =
3593 Ratio * getArithmeticInstrCost(Opcode, AccumVectorType, CostKind);
3594
3595 if (!BinOp)
3596 return ExtendCostA + ReductionOpCost;
3597
3598 InstructionCost ExtendCostB = 0;
3600 ExtendCostB = getCastInstrCost(
3602 ExtInputVectorType, InputVectorType, TTI::CastContextHint::None,
3603 CostKind);
3604 return ExtendCostA + ExtendCostB + ReductionOpCost +
3605 getArithmeticInstrCost(*BinOp, ExtInputVectorType, CostKind);
3606 }
3607
3609
3610 /// @}
3611};
3612
3613/// Concrete BasicTTIImpl that can be used if no further customization
3614/// is needed.
3615class BasicTTIImpl : public BasicTTIImplBase<BasicTTIImpl> {
3616 using BaseT = BasicTTIImplBase<BasicTTIImpl>;
3617
3618 friend class BasicTTIImplBase<BasicTTIImpl>;
3619
3620 const TargetSubtargetInfo *ST;
3621 const TargetLoweringBase *TLI;
3622
3623 const TargetSubtargetInfo *getST() const { return ST; }
3624 const TargetLoweringBase *getTLI() const { return TLI; }
3625
3626public:
3627 LLVM_ABI explicit BasicTTIImpl(const TargetMachine *TM, const Function &F);
3628};
3629
3630} // end namespace llvm
3631
3632#endif // LLVM_CODEGEN_BASICTTIIMPL_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
unsigned uint64_t
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:857
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static const Function * getCalledFunction(const Value *V)
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
#define P(N)
SI Fold Operands
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This file describes how to lower LLVM code to machine code.
This file provides helpers for the implementation of a TargetTransformInfo-conforming class.
This pass exposes codegen information to IR-level passes.
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
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1350
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition APInt.h:1205
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
bool slt(const APInt &RHS) const
Signed less than comparison.
Definition APInt.h:1134
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:196
an instruction to allocate memory on the stack
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition ArrayRef.h:194
size_t size() const
Get the array size.
Definition ArrayRef.h:141
ArrayRef< T > drop_back(size_t N=1) const
Drop the last N elements of the array.
Definition ArrayRef.h:200
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
InstructionCost getFPOpCost(Type *Ty) const override
bool preferToKeepConstantsAttached(const Instruction &Inst, const Function &Fn) const override
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
Try to calculate op costs for min/max reduction operations.
bool isIndexedLoadLegal(TTI::MemIndexedMode M, Type *Ty) const override
unsigned getCallerAllocaCost(const CallBase *CB, const AllocaInst *AI) const override
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
bool shouldBuildLookupTables() const override
bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const override
bool isProfitableToHoist(Instruction *I) const override
unsigned getNumberOfParts(Type *Tp) const override
unsigned getMinPrefetchStride(unsigned NumMemAccesses, unsigned NumStridedMemAccesses, unsigned NumPrefetches, bool HasCall) const override
bool useAA() const override
unsigned getPrefetchDistance() const override
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
InstructionCost getOperandsScalarizationOverhead(ArrayRef< Type * > Tys, TTI::TargetCostKind CostKind, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
Estimate the overhead of scalarizing an instruction's operands.
bool isLegalAddScalableImmediate(int64_t Imm) const override
unsigned getAssumedAddrSpace(const Value *V) const override
std::optional< Value * > simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known, bool &KnownBitsComputed) const override
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, Instruction *I=nullptr, int64_t ScalableOffset=0) const override
bool addrspacesMayAlias(unsigned AS0, unsigned AS1) const override
bool areInlineCompatible(const Function *Caller, const Function *Callee) const override
bool isIndexedStoreLegal(TTI::MemIndexedMode M, Type *Ty) const override
bool haveFastSqrt(Type *Ty) const override
bool collectFlatAddressOperands(SmallVectorImpl< int > &OpIndexes, Intrinsic::ID IID) const override
unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, unsigned &JumpTableSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
Value * rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV, Value *NewV) const override
unsigned adjustInliningThreshold(const CallBase *CB) const override
unsigned getInliningThresholdMultiplier() const override
InstructionCost getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
Estimate the overhead of scalarizing an instruction.
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, Value *Scalar, ArrayRef< std::tuple< Value *, User *, int > > ScalarUserAndIdx, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
int64_t getPreferredLargeGEPBaseOffset(int64_t MinOffset, int64_t MaxOffset)
bool shouldBuildRelLookupTables() const override
bool isTargetIntrinsicWithStructReturnOverloadAtField(Intrinsic::ID ID, int RetIdx) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr) const override
InstructionCost getVectorInstrCost(const Instruction &I, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) const override
unsigned getEpilogueVectorizationMinVF() const override
InstructionCost getExtractWithExtendCost(unsigned Opcode, Type *Dst, VectorType *VecTy, unsigned Index, TTI::TargetCostKind CostKind) const override
InstructionCost getVectorSplitCost() const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
unsigned getFlatAddressSpace() const override
InstructionCost getCallInstrCost(Function *F, Type *RetTy, ArrayRef< Type * > Tys, TTI::TargetCostKind CostKind) const override
Compute a cost of the given call instruction.
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
InstructionCost getTreeReductionCost(unsigned Opcode, VectorType *Ty, TTI::TargetCostKind CostKind) const
Try to calculate arithmetic and shuffle op costs for reduction intrinsics.
~BasicTTIImplBase() override=default
std::pair< const Value *, unsigned > getPredicatedAddrSpace(const Value *V) const override
unsigned getMaxPrefetchIterationsAhead() const override
unsigned getMaxInterleaveFactor(ElementCount VF, bool HasUnorderedReductions) const override
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) const override
InstructionCost getTypeBasedIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const
Get intrinsic cost based on argument types.
bool hasBranchDivergence(const Function *F=nullptr) const override
InstructionCost getOrderedReductionCost(unsigned Opcode, VectorType *Ty, TTI::TargetCostKind CostKind) const
Try to calculate the cost of performing strict (in-order) reductions, which involves doing a sequence...
std::optional< unsigned > getCacheAssociativity(TargetTransformInfo::CacheLevel Level) const override
bool shouldPrefetchAddressSpace(unsigned AS) const override
bool allowsMisalignedMemoryAccesses(LLVMContext &Context, unsigned BitWidth, unsigned AddressSpace, Align Alignment, unsigned *Fast) const override
unsigned getCacheLineSize() const override
std::optional< Instruction * > instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override
bool shouldDropLSRSolutionIfLessProfitable() const override
int getInlinerVectorBonusPercent() const override
InstructionCost getMulAccReductionCost(bool IsUnsigned, unsigned RedOpcode, Type *ResTy, VectorType *Ty, TTI::TargetCostKind CostKind) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getIndexedVectorInstrCostFromEnd(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
Estimate the cost of type-legalization and the legalized type.
InstructionCost getPartialReductionCost(unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType, ElementCount VF, TTI::PartialReductionExtendKind OpAExtend, TTI::PartialReductionExtendKind OpBExtend, std::optional< unsigned > BinOp, TTI::TargetCostKind CostKind, std::optional< FastMathFlags > FMF) const override
bool isLegalAddImmediate(int64_t imm) const override
InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts, TTI::TargetCostKind CostKind) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool isProfitableLSRChainElement(Instruction *I) const override
bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const override
bool isTargetIntrinsicWithOverloadTypeAtArg(Intrinsic::ID ID, int OpdIdx) const override
bool isTargetIntrinsicWithScalarOpAtArg(Intrinsic::ID ID, unsigned ScalarOpdIdx) const override
std::optional< unsigned > getVScaleForTuning() const override
InstructionCost getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
Get intrinsic cost based on arguments.
bool preferTailFoldingOverEpilogue(TailFoldingInfo *TFI) const override
std::optional< Value * > simplifyDemandedVectorEltsIntrinsic(InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2, APInt &UndefElts3, std::function< void(Instruction *, unsigned, APInt, APInt &)> SimplifyAndSetOp) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *, const SCEV *, TTI::TargetCostKind) const override
bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override
InstructionCost getScalarizationOverhead(VectorType *RetTy, ArrayRef< const Value * > Args, ArrayRef< Type * > Tys, TTI::TargetCostKind CostKind) const
Estimate the overhead of scalarizing the inputs and outputs of an instruction, with return type RetTy...
TailFoldingStyle getPreferredTailFoldingStyle() const override
std::optional< unsigned > getCacheSize(TargetTransformInfo::CacheLevel Level) const override
bool isLegalICmpImmediate(int64_t imm) const override
InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, TTI::TargetCostKind CostKind, Type *AccessType) const override
bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE, AssumptionCache &AC, TargetLibraryInfo *LibInfo, HardwareLoopInfo &HWLoopInfo) const override
unsigned getRegUsageForType(Type *Ty) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
Get memory intrinsic cost based on arguments.
BasicTTIImplBase(const TargetMachine *TM, const DataLayout &DL)
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
bool isTypeLegal(Type *Ty) const override
bool enableWritePrefetching() const override
bool isLSRCostLess(const TTI::LSRCost &C1, const TTI::LSRCost &C2) const override
InstructionCost getScalarizationOverhead(VectorType *InTy, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
Helper wrapper for the DemandedElts variant of getScalarizationOverhead.
InstructionCost getBranchMispredictPenalty() const override
bool isNumRegsMajorCostOfLSR() const override
LLVM_ABI BasicTTIImpl(const TargetMachine *TM, const Function &F)
size_type count() const
Returns the number of bits which are set.
Definition BitVector.h:181
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
static CmpInst::Predicate getGTPredicate(Intrinsic::ID ID)
static CmpInst::Predicate getLTPredicate(Intrinsic::ID ID)
This class represents a range of values.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
constexpr bool isVector() const
One or more elements.
Definition TypeSize.h:320
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:305
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:316
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Container class for subtarget features.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:329
The core instruction combiner logic.
static InstructionCost getInvalid(CostType Val=0)
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
const SmallVectorImpl< Type * > & getArgTypes() const
const SmallVectorImpl< const Value * > & getArgs() const
InstructionCost getScalarizationCost() const
const IntrinsicInst * getInst() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
const FeatureBitset & getFeatureBits() const
Machine Value Type.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Information for memory intrinsic cost model.
The optimization diagnostic interface.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Diagnostic information for applied optimization remarks.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
Analysis providing profile information.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
static LLVM_ABI bool isZeroEltSplatMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses all elements with the same value as the first element of exa...
static LLVM_ABI bool isSpliceMask(ArrayRef< int > Mask, int NumSrcElts, int &Index)
Return true if this shuffle mask is a splice mask, concatenating the two inputs together and then ext...
static LLVM_ABI bool isSelectMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from its source vectors without lane crossings.
static LLVM_ABI bool isExtractSubvectorMask(ArrayRef< int > Mask, int NumSrcElts, int &Index)
Return true if this shuffle mask is an extract subvector mask.
static LLVM_ABI bool isReverseMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask swaps the order of elements from exactly one source vector.
static LLVM_ABI bool isTransposeMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask is a transpose mask.
static LLVM_ABI bool isInsertSubvectorMask(ArrayRef< int > Mask, int NumSrcElts, int &NumSubElts, int &Index)
Return true if this shuffle mask is an insert subvector mask.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:40
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition Type.cpp:662
Multiway switch.
Provides information about what library functions are available for the current target.
This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...
bool isOperationExpand(unsigned Op, EVT VT) const
Return true if the specified operation is illegal on this target or unlikely to be made legal with cu...
int InstructionOpcodeToISD(unsigned Opcode) const
Get the ISD node that corresponds to the Instruction class opcode.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
virtual bool preferSelectsOverBooleanArithmetic(EVT VT) const
Should we prefer selects to doing arithmetic on boolean types.
virtual bool isFreeAddrSpaceCast(const DataLayout &DL, unsigned SrcAS, unsigned DestAS) const
Returns true if a cast from SrcAS to DestAS is "cheap", such that e.g.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual bool isSuitableForJumpTable(const SwitchInst *SI, uint64_t NumCases, uint64_t Range, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) const
Return true if lowering to a jump table is suitable for a set of case clusters which may contain NumC...
virtual bool areJTsAllowed(const Function *Fn) const
Return true if lowering to a jump table is allowed.
bool isOperationLegalOrPromote(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal using promotion.
LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace) const
Return how this store with truncation should be treated: either it is legal, needs to be promoted to ...
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
bool isSuitableForBitTests(const DenseMap< const BasicBlock *, unsigned int > &DestCmps, const APInt &Low, const APInt &High, const DataLayout &DL) const
Return true if lowering to a bit test is suitable for a set of case clusters which contains NumDests ...
virtual bool isTruncateFree(Type *FromTy, Type *ToTy) const
Return true if it's free to truncate a value of type FromTy to type ToTy.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
LegalizeAction getLoadAction(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace, unsigned ExtType, bool Atomic) const
Return how this load with extension should be treated: either it is legal, needs to be promoted to a ...
LegalizeKind getTypeConversion(LLVMContext &Context, EVT VT) const
Return pair that represents the legalization kind (first) that needs to happen to EVT (second) in ord...
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
bool isLoadLegal(EVT ValVT, EVT MemVT, Align Alignment, unsigned AddrSpace, unsigned ExtType, bool Atomic) const
Return true if the specified load with extension is legal on this target.
virtual bool isFAbsFree(EVT VT) const
Return true if an fabs operation is free to the point where it is never worthwhile to replace it with...
bool isOperationLegalOrCustomOrPromote(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
std::pair< LegalizeTypeAction, EVT > LegalizeKind
LegalizeKind holds the legalization kind that needs to happen to EVT in order to type-legalize it.
Primary interface to the complete machine description for the target machine.
bool isPositionIndependent() const
const Triple & getTargetTriple() const
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
CodeModel::Model getCodeModel() const
Returns the code model.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const FeatureBitset & getInlineMustMatchFeatures() const =0
Target features where all mismatches prevent inlining.
virtual const FeatureBitset & getInlineInverseFeatures() const =0
Target features where the callee may have an additional feature, instead of the caller.
virtual const FeatureBitset & getInlineIgnoreFeatures() const =0
Target features to ignore for inline compatibility check.
virtual bool isProfitableLSRChainElement(Instruction *I) const
virtual TailFoldingStyle getPreferredTailFoldingStyle() const
virtual const DataLayout & getDataLayout() const
virtual std::optional< unsigned > getCacheAssociativity(TargetTransformInfo::CacheLevel Level) const
virtual InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info, TTI::OperandValueInfo Opd2Info, ArrayRef< const Value * > Args, const Instruction *CtxI=nullptr) const
virtual std::optional< Value * > simplifyDemandedVectorEltsIntrinsic(InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2, APInt &UndefElts3, std::function< void(Instruction *, unsigned, APInt, APInt &)> SimplifyAndSetOp) const
virtual bool shouldDropLSRSolutionIfLessProfitable() const
virtual bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE, AssumptionCache &AC, TargetLibraryInfo *LibInfo, HardwareLoopInfo &HWLoopInfo) const
virtual std::optional< Value * > simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known, bool &KnownBitsComputed) const
virtual bool preferTailFoldingOverEpilogue(TailFoldingInfo *TFI) const
virtual std::optional< Instruction * > instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const
virtual unsigned getEpilogueVectorizationMinVF() const
virtual InstructionCost getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const
virtual bool isLoweredToCall(const Function *F) const
virtual InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const
virtual bool isLSRCostLess(const TTI::LSRCost &C1, const TTI::LSRCost &C2) const
virtual InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I) const
virtual InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const
virtual InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info, TTI::OperandValueInfo Op2Info, const Instruction *I) const
InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, TTI::TargetCostKind CostKind, Type *AccessType) const override
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
static LLVM_ABI OperandValueInfo getOperandInfo(const Value *V)
Collect properties of V used in cost analysis, e.g. OP_PowerOf2.
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
@ TCK_Latency
The latency of instruction.
static bool requiresOrderedReduction(std::optional< FastMathFlags > FMF)
A helper function to determine the type of reduction algorithm used for a given Opcode and set of Fas...
llvm::VectorInstrContext VectorInstrContext
@ TCC_Expensive
The cost of a 'div' instruction on x86.
@ TCC_Basic
The cost of a typical 'add' instruction.
static LLVM_ABI Instruction::CastOps getOpcodeForPartialReductionExtendKind(PartialReductionExtendKind Kind)
Get the cast opcode for an extension kind.
MemIndexedMode
The type of load/store indexing.
static LLVM_ABI VectorInstrContext getVectorInstrContextHint(const Instruction *I)
Calculates a VectorInstrContext from I.
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_InsertSubvector
InsertSubvector. Index indicates start offset.
@ 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_Transpose
Transpose two vectors.
@ SK_Splice
Concatenates elements from the first input vector with elements of the second input vector.
@ SK_Broadcast
Broadcast element 0 to all other elements.
@ SK_PermuteTwoSrc
Merge elements from two source vectors into one with any shuffle mask.
@ SK_Reverse
Reverse the order of the vector.
@ SK_ExtractSubvector
ExtractSubvector Index indicates start offset.
CastContextHint
Represents a hint about the context in which a cast is used.
@ Normal
The cast is used with a normal load/store.
CacheLevel
The possible cache levels.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:515
LLVM_ABI bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition Triple.cpp:1829
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, DriverKit, XROS, or bridgeOS).
Definition Triple.h:724
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:339
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI Type * getWithNewType(Type *EltTy) const
Given vector type, change the element type, whilst keeping the old number of elements.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
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
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:303
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
Definition Type.h:392
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
Value * getOperand(unsigned i) const
Definition User.h:207
static LLVM_ABI std::optional< unsigned > getFunctionalOpcodeForVP(Intrinsic::ID ID)
static LLVM_ABI std::optional< Intrinsic::ID > getFunctionalIntrinsicIDForVP(Intrinsic::ID ID)
static LLVM_ABI bool isVPIntrinsic(Intrinsic::ID)
static LLVM_ABI bool isVPReduction(Intrinsic::ID ID)
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
Base class of all SIMD vector types.
static VectorType * getHalfElementsVectorType(VectorType *VTy)
This static method returns a VectorType with half as many elements as the input type and the same ele...
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Type * getElementType() const
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:216
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
Definition TypeSize.h:252
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
LLVM_ABI APInt ScaleBitMask(const APInt &A, unsigned NewBitWidth, bool MatchAllBits=false)
Splat/Merge neighboring bits to widen/narrow the bitmask represented by.
Definition APInt.cpp:3043
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:26
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:797
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
Definition ISDOpcodes.h:397
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:523
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:420
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:757
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ CLMUL
Carry-less multiplication operations.
Definition ISDOpcodes.h:788
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ SSUBO
Same for subtraction.
Definition ISDOpcodes.h:355
@ BRIND
BRIND - Indirect branch.
@ BR_JT
BR_JT - Jumptable branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
Definition ISDOpcodes.h:546
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition ISDOpcodes.h:377
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:814
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:351
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:359
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:737
@ MASKED_UDIV
Masked vector arithmetic that returns poison on disabled lanes.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition ISDOpcodes.h:823
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
Definition ISDOpcodes.h:745
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
Definition ISDOpcodes.h:963
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:539
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:368
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
LLVM_ABI bool isTargetIntrinsic(ID IID)
isTargetIntrinsic - Returns true if IID is an intrinsic specific to a certain target.
DiagnosticInfoOptimizationBase::Argument NV
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID)
Returns the min/max intrinsic used when expanding a min/max reduction.
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:856
InstructionCost Cost
@ Known
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
Type * toScalarizedTy(Type *Ty)
A helper for converting vectorized types to scalarized (non-vector) types.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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
LLVM_ABI unsigned getArithmeticReductionInstruction(Intrinsic::ID RdxID)
Returns the arithmetic instruction opcode used when expanding a reduction.
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...
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition STLExtras.h:1167
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ABI std::optional< unsigned > getPartialUnrollingThreshold()
Returns -partial-unrolling-threshold if specified.
constexpr bool has_single_bit(T Value) noexcept
Definition bit.h:149
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
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
ElementCount getVectorizedTypeVF(Type *Ty)
Returns the number of vector elements for a vectorized type.
LLVM_ABI ConstantRange getVScaleRange(const Function *F, unsigned BitWidth)
Determine the possible constant range of vscale with the given bit width, based on the vscale_range f...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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
constexpr int PoisonMaskElem
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:389
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
@ Fast
Assign the register banks as fast as possible (default).
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
ArrayRef< Type * > getContainedTypes(Type *const &Ty)
Returns the types contained in Ty.
LLVM_ABI bool isVectorizedStructTy(StructType *StructTy)
Returns true if StructTy is an unpacked literal struct where all elements are vectors of matching ele...
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
ElementCount getVectorElementCount() const
Definition ValueTypes.h:373
static LLVM_ABI EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
Definition ValueTypes.h:61
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Attributes of a target dependent hardware loop.
static LLVM_ABI bool hasVectorMaskArgument(RTLIB::LibcallImpl Impl)
Returns true if the function has a vector mask argument, which is assumed to be the last argument.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
bool AllowPeeling
Allow peeling off loop iterations.
bool AllowLoopNestsPeeling
Allow peeling off loop iterations for loop nests.
bool PeelProfiledIterations
Allow peeling basing on profile.
unsigned PeelCount
A forced peeling factor (the number of bodied of the original loop that should be peeled off before t...
Parameters that control the generic loop unrolling transformation.
bool UpperBound
Allow using trip count upper bound to unroll loops.
unsigned PartialOptSizeThreshold
The cost threshold for the unrolled loop when optimizing for size, like OptSizeThreshold,...
unsigned PartialThreshold
The cost threshold for the unrolled loop, like Threshold, but used for partial/runtime unrolling (set...
bool Runtime
Allow runtime unrolling (unrolling of loops to expand the size of the loop body even when the number ...
bool Partial
Allow partial unrolling (unrolling of loops to expand the size of the loop body, not only to eliminat...
unsigned OptSizeThreshold
The cost threshold for the unrolled loop when optimizing for size (set to UINT_MAX to disable).