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 =
335 getTLI()->getLibcallLoweringInfo().getVectorLibcallImplOrMasked(LC);
336 if (LibcallImpl == RTLIB::Unsupported)
337 return std::nullopt;
338
339 LLVMContext &Ctx = RetTy->getContext();
340
341 // Cost the call + mask.
342 auto Cost =
343 thisT()->getCallInstrCost(nullptr, RetTy, ICA.getArgTypes(), CostKind);
344
347 auto VecTy = VectorType::get(IntegerType::getInt1Ty(Ctx), VF);
348 Cost += thisT()->getShuffleCost(TargetTransformInfo::SK_Broadcast, VecTy,
349 VecTy, CostKind, {}, 0, nullptr, {});
350 }
351
352 // Lowering to a library call (with output pointers) may require us to emit
353 // reloads for the results.
354 for (auto [Idx, VectorTy] : enumerate(getContainedTypes(RetTy))) {
355 if (Idx == CallRetElementIndex)
356 continue;
357 Cost += thisT()->getMemoryOpCost(
358 Instruction::Load, VectorTy,
359 thisT()->getDataLayout().getABITypeAlign(VectorTy), 0, CostKind);
360 }
361 return Cost;
362 }
363
364 /// Filter out constant and duplicated entries in \p Ops and return a vector
365 /// containing the types from \p Tys corresponding to the remaining operands.
367 filterConstantAndDuplicatedOperands(ArrayRef<const Value *> Ops,
368 ArrayRef<Type *> Tys) {
369 SmallPtrSet<const Value *, 4> UniqueOperands;
370 SmallVector<Type *, 4> FilteredTys;
371 for (const auto &[Op, Ty] : zip_equal(Ops, Tys)) {
372 if (isa<Constant>(Op) || !UniqueOperands.insert(Op).second)
373 continue;
374 FilteredTys.push_back(Ty);
375 }
376 return FilteredTys;
377 }
378
379protected:
380 explicit BasicTTIImplBase(const TargetMachine *TM, const DataLayout &DL)
381 : BaseT(DL) {}
382 ~BasicTTIImplBase() override = default;
383
386
387public:
388 /// \name Scalar TTI Implementations
389 /// @{
391 unsigned AddressSpace, Align Alignment,
392 unsigned *Fast) const override {
393 EVT E = EVT::getIntegerVT(Context, BitWidth);
394 return getTLI()->allowsMisalignedMemoryAccesses(
396 }
397
398 bool areInlineCompatible(const Function *Caller,
399 const Function *Callee) const override {
400 const TargetMachine &TM = getTLI()->getTargetMachine();
401
402 const TargetSubtargetInfo *CallerSTI = TM.getSubtargetImpl(*Caller);
403 const TargetSubtargetInfo *CalleeSTI = TM.getSubtargetImpl(*Callee);
404 FeatureBitset InlineIgnoreFeatures = CallerSTI->getInlineIgnoreFeatures();
405 FeatureBitset InlineInverseFeatures = CallerSTI->getInlineInverseFeatures();
406 FeatureBitset InlineMustMatchFeatures =
407 CallerSTI->getInlineMustMatchFeatures();
408
409 FeatureBitset CallerBits =
410 (CallerSTI->getFeatureBits() ^ InlineInverseFeatures) &
411 ~InlineIgnoreFeatures;
412 FeatureBitset CalleeBits =
413 (CalleeSTI->getFeatureBits() ^ InlineInverseFeatures) &
414 ~InlineIgnoreFeatures;
415
416 if ((CallerBits & InlineMustMatchFeatures) !=
417 (CalleeBits & InlineMustMatchFeatures))
418 return false;
419
420 // Inline a callee if its target-features are a subset of the callers
421 // target-features.
422 return (CallerBits & CalleeBits) == CalleeBits;
423 }
424
425 bool hasBranchDivergence(const Function *F = nullptr) const override {
426 return false;
427 }
428
429 bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const override {
430 return false;
431 }
432
433 bool addrspacesMayAlias(unsigned AS0, unsigned AS1) const override {
434 return true;
435 }
436
437 unsigned getFlatAddressSpace() const override {
438 // Return an invalid address space.
439 return -1;
440 }
441
443 Intrinsic::ID IID) const override {
444 return false;
445 }
446
447 bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const override {
448 return getTLI()->getTargetMachine().isNoopAddrSpaceCast(DL, FromAS, ToAS);
449 }
450
451 unsigned getAssumedAddrSpace(const Value *V) const override {
452 return getTLI()->getTargetMachine().getAssumedAddrSpace(V);
453 }
454
455 std::pair<const Value *, unsigned>
456 getPredicatedAddrSpace(const Value *V) const override {
457 return getTLI()->getTargetMachine().getPredicatedAddrSpace(V);
458 }
459
461 Value *NewV) const override {
462 return nullptr;
463 }
464
465 bool isLegalAddImmediate(int64_t imm) const override {
466 return getTLI()->isLegalAddImmediate(imm);
467 }
468
469 bool isLegalAddScalableImmediate(int64_t Imm) const override {
470 return getTLI()->isLegalAddScalableImmediate(Imm);
471 }
472
473 bool isLegalICmpImmediate(int64_t imm) const override {
474 return getTLI()->isLegalICmpImmediate(imm);
475 }
476
477 bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
478 bool HasBaseReg, int64_t Scale, unsigned AddrSpace,
479 Instruction *I = nullptr,
480 int64_t ScalableOffset = 0) const override {
482 AM.BaseGV = BaseGV;
483 AM.BaseOffs = BaseOffset;
484 AM.HasBaseReg = HasBaseReg;
485 AM.Scale = Scale;
486 AM.ScalableOffset = ScalableOffset;
487 return getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace, I);
488 }
489
490 int64_t getPreferredLargeGEPBaseOffset(int64_t MinOffset, int64_t MaxOffset) {
491 return getTLI()->getPreferredLargeGEPBaseOffset(MinOffset, MaxOffset);
492 }
493
494 unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy,
495 Align Alignment,
496 unsigned AddrSpace) const override {
497 auto &&IsSupportedByTarget = [this, ScalarMemTy, ScalarValTy, Alignment,
498 AddrSpace](unsigned VF) {
499 auto *SrcTy = FixedVectorType::get(ScalarMemTy, VF / 2);
500 EVT VT = getTLI()->getValueType(DL, SrcTy);
501 if (getTLI()->isOperationLegal(ISD::STORE, VT) ||
502 getTLI()->isOperationCustom(ISD::STORE, VT))
503 return true;
504
505 EVT ValVT =
506 getTLI()->getValueType(DL, FixedVectorType::get(ScalarValTy, VF / 2));
507 EVT LegalizedVT =
508 getTLI()->getTypeToTransformTo(ScalarMemTy->getContext(), VT);
509 return getTLI()->isTruncStoreLegal(LegalizedVT, ValVT, Alignment,
510 AddrSpace);
511 };
512 while (VF > 2 && IsSupportedByTarget(VF))
513 VF /= 2;
514 return VF;
515 }
516
517 bool isIndexedLoadLegal(TTI::MemIndexedMode M, Type *Ty) const override {
518 EVT VT = getTLI()->getValueType(DL, Ty, /*AllowUnknown=*/true);
519 return getTLI()->isIndexedLoadLegal(getISDIndexedMode(M), VT);
520 }
521
522 bool isIndexedStoreLegal(TTI::MemIndexedMode M, Type *Ty) const override {
523 EVT VT = getTLI()->getValueType(DL, Ty, /*AllowUnknown=*/true);
524 return getTLI()->isIndexedStoreLegal(getISDIndexedMode(M), VT);
525 }
526
528 const TTI::LSRCost &C2) const override {
530 }
531
535
539
543
545 StackOffset BaseOffset, bool HasBaseReg,
546 int64_t Scale,
547 unsigned AddrSpace) const override {
549 AM.BaseGV = BaseGV;
550 AM.BaseOffs = BaseOffset.getFixed();
551 AM.HasBaseReg = HasBaseReg;
552 AM.Scale = Scale;
553 AM.ScalableOffset = BaseOffset.getScalable();
554 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
555 return 0;
557 }
558
559 bool isTruncateFree(Type *Ty1, Type *Ty2) const override {
560 return getTLI()->isTruncateFree(Ty1, Ty2);
561 }
562
563 bool isProfitableToHoist(Instruction *I) const override {
564 return getTLI()->isProfitableToHoist(I);
565 }
566
567 bool useAA() const override { return getST()->useAA(); }
568
569 bool isTypeLegal(Type *Ty) const override {
570 EVT VT = getTLI()->getValueType(DL, Ty, /*AllowUnknown=*/true);
571 return getTLI()->isTypeLegal(VT);
572 }
573
574 unsigned getRegUsageForType(Type *Ty) const override {
575 EVT ETy = getTLI()->getValueType(DL, Ty);
576 return getTLI()->getNumRegisters(Ty->getContext(), ETy);
577 }
578
579 InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr,
582 Type *AccessType) const override {
583 return BaseT::getGEPCost(PointeeType, Ptr, Operands, CostKind, AccessType);
584 }
585
587 const SwitchInst &SI, unsigned &JumpTableSize, ProfileSummaryInfo *PSI,
588 BlockFrequencyInfo *BFI) const override {
589 /// Try to find the estimated number of clusters. Note that the number of
590 /// clusters identified in this function could be different from the actual
591 /// numbers found in lowering. This function ignore switches that are
592 /// lowered with a mix of jump table / bit test / BTree. This function was
593 /// initially intended to be used when estimating the cost of switch in
594 /// inline cost heuristic, but it's a generic cost model to be used in other
595 /// places (e.g., in loop unrolling).
596 unsigned N = SI.getNumCases();
597 const TargetLoweringBase *TLI = getTLI();
598 const DataLayout &DL = this->getDataLayout();
599
600 JumpTableSize = 0;
601 bool IsJTAllowed = TLI->areJTsAllowed(SI.getParent()->getParent());
602
603 // Early exit if both a jump table and bit test are not allowed.
604 if (N < 1 || (!IsJTAllowed && DL.getIndexSizeInBits(0u) < N))
605 return N;
606
607 APInt MaxCaseVal = SI.case_begin()->getCaseValue()->getValue();
608 APInt MinCaseVal = MaxCaseVal;
609 for (auto CI : SI.cases()) {
610 const APInt &CaseVal = CI.getCaseValue()->getValue();
611 if (CaseVal.sgt(MaxCaseVal))
612 MaxCaseVal = CaseVal;
613 if (CaseVal.slt(MinCaseVal))
614 MinCaseVal = CaseVal;
615 }
616
617 // Check if suitable for a bit test
618 if (N <= DL.getIndexSizeInBits(0u)) {
620 for (auto I : SI.cases()) {
621 const BasicBlock *BB = I.getCaseSuccessor();
622 ++DestMap[BB];
623 }
624
625 if (TLI->isSuitableForBitTests(DestMap, MinCaseVal, MaxCaseVal, DL))
626 return 1;
627 }
628
629 // Check if suitable for a jump table.
630 if (IsJTAllowed) {
631 if (N < 2 || N < TLI->getMinimumJumpTableEntries())
632 return N;
634 (MaxCaseVal - MinCaseVal)
635 .getLimitedValue(std::numeric_limits<uint64_t>::max() - 1) + 1;
636 // Check whether a range of clusters is dense enough for a jump table
637 if (TLI->isSuitableForJumpTable(&SI, N, Range, PSI, BFI)) {
638 JumpTableSize = Range;
639 return 1;
640 }
641 }
642 return N;
643 }
644
645 bool shouldBuildLookupTables() const override {
646 const TargetLoweringBase *TLI = getTLI();
647 return TLI->isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) ||
648 TLI->isOperationLegalOrCustom(ISD::BRIND, MVT::Other);
649 }
650
651 bool shouldBuildRelLookupTables() const override {
652 const TargetMachine &TM = getTLI()->getTargetMachine();
653 // If non-PIC mode, do not generate a relative lookup table.
654 if (!TM.isPositionIndependent())
655 return false;
656
657 /// Relative lookup table entries consist of 32-bit offsets.
658 /// Do not generate relative lookup tables for large code models
659 /// in 64-bit achitectures where 32-bit offsets might not be enough.
660 if (TM.getCodeModel() == CodeModel::Medium ||
662 return false;
663
664 const Triple &TargetTriple = TM.getTargetTriple();
665 if (!TargetTriple.isArch64Bit())
666 return false;
667
668 // TODO: Triggers issues on aarch64 on darwin, so temporarily disable it
669 // there.
670 if (TargetTriple.getArch() == Triple::aarch64 && TargetTriple.isOSDarwin())
671 return false;
672
673 return true;
674 }
675
676 bool haveFastSqrt(Type *Ty) const override {
677 const TargetLoweringBase *TLI = getTLI();
678 EVT VT = TLI->getValueType(DL, Ty);
679 return TLI->isTypeLegal(VT) &&
681 }
682
683 bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override { return true; }
684
685 InstructionCost getFPOpCost(Type *Ty) const override {
686 // Check whether FADD is available, as a proxy for floating-point in
687 // general.
688 const TargetLoweringBase *TLI = getTLI();
689 EVT VT = TLI->getValueType(DL, Ty);
693 }
694
696 const Function &Fn) const override {
697 switch (Inst.getOpcode()) {
698 default:
699 break;
700 case Instruction::SDiv:
701 case Instruction::SRem:
702 case Instruction::UDiv:
703 case Instruction::URem: {
704 if (!isa<ConstantInt>(Inst.getOperand(1)))
705 return false;
706 EVT VT = getTLI()->getValueType(DL, Inst.getType());
707 return !getTLI()->isIntDivCheap(VT, Fn.getAttributes());
708 }
709 };
710
711 return false;
712 }
713
714 unsigned getInliningThresholdMultiplier() const override { return 1; }
715 unsigned adjustInliningThreshold(const CallBase *CB) const override {
716 return 0;
717 }
718 unsigned getCallerAllocaCost(const CallBase *CB,
719 const AllocaInst *AI) const override {
720 return 0;
721 }
722
723 int getInlinerVectorBonusPercent() const override { return 150; }
724
727 OptimizationRemarkEmitter *ORE) const override {
728 // This unrolling functionality is target independent, but to provide some
729 // motivation for its intended use, for x86:
730
731 // According to the Intel 64 and IA-32 Architectures Optimization Reference
732 // Manual, Intel Core models and later have a loop stream detector (and
733 // associated uop queue) that can benefit from partial unrolling.
734 // The relevant requirements are:
735 // - The loop must have no more than 4 (8 for Nehalem and later) branches
736 // taken, and none of them may be calls.
737 // - The loop can have no more than 18 (28 for Nehalem and later) uops.
738
739 // According to the Software Optimization Guide for AMD Family 15h
740 // Processors, models 30h-4fh (Steamroller and later) have a loop predictor
741 // and loop buffer which can benefit from partial unrolling.
742 // The relevant requirements are:
743 // - The loop must have fewer than 16 branches
744 // - The loop must have less than 40 uops in all executed loop branches
745
746 // The number of taken branches in a loop is hard to estimate here, and
747 // benchmarking has revealed that it is better not to be conservative when
748 // estimating the branch count. As a result, we'll ignore the branch limits
749 // until someone finds a case where it matters in practice.
750
751 unsigned MaxOps;
752 const TargetSubtargetInfo *ST = getST();
753 if (std::optional<unsigned> Threshold = getPartialUnrollingThreshold())
754 MaxOps = *Threshold;
755 else if (ST->getSchedModel().LoopMicroOpBufferSize > 0)
756 MaxOps = ST->getSchedModel().LoopMicroOpBufferSize;
757 else
758 return;
759
760 // Scan the loop: don't unroll loops with calls.
761 for (BasicBlock *BB : L->blocks()) {
762 for (Instruction &I : *BB) {
763 if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
764 if (const Function *F = cast<CallBase>(I).getCalledFunction()) {
765 if (!thisT()->isLoweredToCall(F))
766 continue;
767 }
768
769 if (ORE) {
770 ORE->emit([&]() {
771 return OptimizationRemark("TTI", "DontUnroll", L->getStartLoc(),
772 L->getHeader())
773 << "advising against unrolling the loop because it "
774 "contains a "
775 << ore::NV("Call", &I);
776 });
777 }
778 return;
779 }
780 }
781 }
782
783 // Enable runtime and partial unrolling up to the specified size.
784 // Enable using trip count upper bound to unroll loops.
785 UP.Partial = UP.Runtime = UP.UpperBound = true;
786 UP.PartialThreshold = MaxOps;
787
788 // Avoid unrolling when optimizing for size.
789 UP.OptSizeThreshold = 0;
791
792 // Set number of instructions optimized when "back edge"
793 // becomes "fall through" to default value of 2.
794 UP.BEInsns = 2;
795 }
796
798 TTI::PeelingPreferences &PP) const override {
799 PP.PeelCount = 0;
800 PP.AllowPeeling = true;
801 PP.AllowLoopNestsPeeling = false;
802 PP.PeelProfiledIterations = true;
803 }
804
807 HardwareLoopInfo &HWLoopInfo) const override {
808 return BaseT::isHardwareLoopProfitable(L, SE, AC, LibInfo, HWLoopInfo);
809 }
810
811 unsigned getEpilogueVectorizationMinVF() const override {
813 }
814
818
822
823 std::optional<Instruction *>
826 }
827
828 std::optional<Value *>
830 APInt DemandedMask, KnownBits &Known,
831 bool &KnownBitsComputed) const override {
832 return BaseT::simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
833 KnownBitsComputed);
834 }
835
837 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
838 APInt &UndefElts2, APInt &UndefElts3,
839 std::function<void(Instruction *, unsigned, APInt, APInt &)>
840 SimplifyAndSetOp) const override {
842 IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
843 SimplifyAndSetOp);
844 }
845
847 return getST()->getMispredictionPenalty();
848 }
849
850 std::optional<unsigned>
852 return std::optional<unsigned>(
853 getST()->getCacheSize(static_cast<unsigned>(Level)));
854 }
855
856 std::optional<unsigned>
858 std::optional<unsigned> TargetResult =
859 getST()->getCacheAssociativity(static_cast<unsigned>(Level));
860
861 if (TargetResult)
862 return TargetResult;
863
864 return BaseT::getCacheAssociativity(Level);
865 }
866
867 unsigned getCacheLineSize() const override {
868 return getST()->getCacheLineSize();
869 }
870
871 unsigned getPrefetchDistance() const override {
872 return getST()->getPrefetchDistance();
873 }
874
875 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
876 unsigned NumStridedMemAccesses,
877 unsigned NumPrefetches,
878 bool HasCall) const override {
879 return getST()->getMinPrefetchStride(NumMemAccesses, NumStridedMemAccesses,
880 NumPrefetches, HasCall);
881 }
882
883 unsigned getMaxPrefetchIterationsAhead() const override {
884 return getST()->getMaxPrefetchIterationsAhead();
885 }
886
887 bool enableWritePrefetching() const override {
888 return getST()->enableWritePrefetching();
889 }
890
891 bool shouldPrefetchAddressSpace(unsigned AS) const override {
892 return getST()->shouldPrefetchAddressSpace(AS);
893 }
894
895 /// @}
896
897 /// \name Vector TTI Implementations
898 /// @{
899
904
905 std::optional<unsigned> getVScaleForTuning() const override {
906 return std::nullopt;
907 }
908
909 /// Estimate the overhead of scalarizing an instruction. Insert and Extract
910 /// are set if the demanded result elements need to be inserted and/or
911 /// extracted from vectors.
913 getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts,
914 bool Insert, bool Extract,
916 bool ForPoisonSrc = true, ArrayRef<Value *> VL = {},
918 TTI::VectorInstrContext::None) const override {
919 /// FIXME: a bitfield is not a reasonable abstraction for talking about
920 /// which elements are needed from a scalable vector
921 if (isa<ScalableVectorType>(InTy))
923 auto *Ty = cast<FixedVectorType>(InTy);
924
925 assert(DemandedElts.getBitWidth() == Ty->getNumElements() &&
926 (VL.empty() || VL.size() == Ty->getNumElements()) &&
927 "Vector size mismatch");
928
930
931 for (int i = 0, e = Ty->getNumElements(); i < e; ++i) {
932 if (!DemandedElts[i])
933 continue;
934 if (Insert) {
935 Value *InsertedVal = VL.empty() ? nullptr : VL[i];
936 Cost +=
937 thisT()->getVectorInstrCost(Instruction::InsertElement, Ty,
938 CostKind, i, nullptr, InsertedVal, VIC);
939 }
940 if (Extract)
941 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty,
942 CostKind, i, nullptr, nullptr, VIC);
943 }
944
945 return Cost;
946 }
947
948 bool
950 unsigned ScalarOpdIdx) const override {
951 return false;
952 }
953
955 int OpdIdx) const override {
956 return OpdIdx == -1;
957 }
958
959 bool
961 int RetIdx) const override {
962 return RetIdx == 0;
963 }
964
965 /// Helper wrapper for the DemandedElts variant of getScalarizationOverhead.
967 VectorType *InTy, bool Insert, bool Extract, TTI::TargetCostKind CostKind,
968 bool ForPoisonSrc = true, ArrayRef<Value *> VL = {},
970 if (isa<ScalableVectorType>(InTy))
972 auto *Ty = cast<FixedVectorType>(InTy);
973
974 APInt DemandedElts = APInt::getAllOnes(Ty->getNumElements());
975 // Use CRTP to allow target overrides
976 return thisT()->getScalarizationOverhead(Ty, DemandedElts, Insert, Extract,
977 CostKind, ForPoisonSrc, VL, VIC);
978 }
979
980 /// Estimate the overhead of scalarizing an instruction's
981 /// operands. The (potentially vector) types to use for each of
982 /// argument are passes via Tys.
986 TTI::VectorInstrContext::None) const override {
988 for (Type *Ty : Tys) {
989 // Disregard things like metadata arguments.
990 if (!Ty->isIntOrIntVectorTy() && !Ty->isFPOrFPVectorTy() &&
991 !Ty->isPtrOrPtrVectorTy())
992 continue;
993
994 if (auto *VecTy = dyn_cast<VectorType>(Ty))
995 Cost += getScalarizationOverhead(VecTy, /*Insert*/ false,
996 /*Extract*/ true, CostKind,
997 /*ForPoisonSrc=*/true, {}, VIC);
998 }
999
1000 return Cost;
1001 }
1002
1003 /// Estimate the overhead of scalarizing the inputs and outputs of an
1004 /// instruction, with return type RetTy and arguments Args of type Tys. If
1005 /// Args are unknown (empty), then the cost associated with one argument is
1006 /// added as a heuristic.
1009 ArrayRef<Type *> Tys,
1012 RetTy, /*Insert*/ true, /*Extract*/ false, CostKind);
1013 if (!Args.empty())
1015 filterConstantAndDuplicatedOperands(Args, Tys), CostKind);
1016 else
1017 // When no information on arguments is provided, we add the cost
1018 // associated with one argument as a heuristic.
1019 Cost += getScalarizationOverhead(RetTy, /*Insert*/ false,
1020 /*Extract*/ true, CostKind);
1021
1022 return Cost;
1023 }
1024
1025 /// Estimate the cost of type-legalization and the legalized type.
1026 std::pair<InstructionCost, MVT> getTypeLegalizationCost(Type *Ty) const {
1027 auto [It, Inserted] = TypeLegalizationCostCache.try_emplace(Ty);
1028 if (Inserted)
1029 It->second = computeTypeLegalizationCost(Ty);
1030 return It->second;
1031 }
1032
1033private:
1034 std::pair<InstructionCost, MVT> computeTypeLegalizationCost(Type *Ty) const {
1035 LLVMContext &C = Ty->getContext();
1036 EVT MTy = getTLI()->getValueType(DL, Ty);
1037
1039 // We keep legalizing the type until we find a legal kind. We assume that
1040 // the only operation that costs anything is the split. After splitting
1041 // we need to handle two types.
1042 while (true) {
1044
1046 // Ensure we return a sensible simple VT here, since many callers of
1047 // this function require it.
1048 MVT VT = MTy.isSimple() ? MTy.getSimpleVT() : MVT::i64;
1049 return std::make_pair(InstructionCost::getInvalid(), VT);
1050 }
1051
1052 if (LK.first == TargetLoweringBase::TypeLegal)
1053 return std::make_pair(Cost, MTy.getSimpleVT());
1054
1055 if (LK.first == TargetLoweringBase::TypeSplitVector ||
1057 Cost *= 2;
1058
1059 // Do not loop with f128 type.
1060 if (MTy == LK.second)
1061 return std::make_pair(Cost, MTy.getSimpleVT());
1062
1063 // Keep legalizing the type.
1064 MTy = LK.second;
1065 }
1066 }
1067
1068 /// Memoizes type legalization cost. The mapping does not depend on the IR, so
1069 /// entries stay valid for the lifetime of this object.
1070 mutable DenseMap<Type *, std::pair<InstructionCost, MVT>>
1071 TypeLegalizationCostCache;
1072
1073public:
1075 bool HasUnorderedReductions) const override {
1076 return 1;
1077 }
1078
1080 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
1083 ArrayRef<const Value *> Args = {},
1084 const Instruction *CtxI = nullptr) const override {
1085 // Check if any of the operands are vector operands.
1086 const TargetLoweringBase *TLI = getTLI();
1087 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1088 assert(ISD && "Invalid opcode");
1089
1090 // TODO: Handle more cost kinds.
1092 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind,
1093 Opd1Info, Opd2Info,
1094 Args, CtxI);
1095
1096 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
1097
1098 bool IsFloat = Ty->isFPOrFPVectorTy();
1099 // Assume that floating point arithmetic operations cost twice as much as
1100 // integer operations.
1101 InstructionCost OpCost = (IsFloat ? 2 : 1);
1102
1103 if (TLI->isOperationLegalOrPromote(ISD, LT.second)) {
1104 // The operation is legal. Assume it costs 1.
1105 // TODO: Once we have extract/insert subvector cost we need to use them.
1106 return LT.first * OpCost;
1107 }
1108
1109 if (!TLI->isOperationExpand(ISD, LT.second)) {
1110 // If the operation is custom lowered, then assume that the code is twice
1111 // as expensive.
1112 return LT.first * 2 * OpCost;
1113 }
1114
1115 // An 'Expand' of URem and SRem is special because it may default
1116 // to expanding the operation into a sequence of sub-operations
1117 // i.e. X % Y -> X-(X/Y)*Y.
1118 if (ISD == ISD::UREM || ISD == ISD::SREM) {
1119 bool IsSigned = ISD == ISD::SREM;
1120 if (TLI->isOperationLegalOrCustom(IsSigned ? ISD::SDIVREM : ISD::UDIVREM,
1121 LT.second) ||
1122 TLI->isOperationLegalOrCustom(IsSigned ? ISD::SDIV : ISD::UDIV,
1123 LT.second)) {
1124 unsigned DivOpc = IsSigned ? Instruction::SDiv : Instruction::UDiv;
1125 InstructionCost DivCost = thisT()->getArithmeticInstrCost(
1126 DivOpc, Ty, CostKind, Opd1Info, Opd2Info);
1127 InstructionCost MulCost =
1128 thisT()->getArithmeticInstrCost(Instruction::Mul, Ty, CostKind);
1129 InstructionCost SubCost =
1130 thisT()->getArithmeticInstrCost(Instruction::Sub, Ty, CostKind);
1131 return DivCost + MulCost + SubCost;
1132 }
1133 }
1134
1135 // We cannot scalarize scalable vectors, so return Invalid.
1138
1139 // Else, assume that we need to scalarize this op.
1140 // TODO: If one of the types get legalized by splitting, handle this
1141 // similarly to what getCastInstrCost() does.
1142 if (auto *VTy = dyn_cast<FixedVectorType>(Ty)) {
1143 InstructionCost Cost = thisT()->getArithmeticInstrCost(
1144 Opcode, VTy->getScalarType(), CostKind, Opd1Info, Opd2Info,
1145 Args, CtxI);
1146 // Return the cost of multiple scalar invocation plus the cost of
1147 // inserting and extracting the values.
1148 SmallVector<Type *> Tys(Args.size(), Ty);
1149 return getScalarizationOverhead(VTy, Args, Tys, CostKind) +
1150 VTy->getNumElements() * Cost;
1151 }
1152
1153 // We don't know anything about this scalar instruction.
1154 return OpCost;
1155 }
1156
1158 ArrayRef<int> Mask,
1159 VectorType *SrcTy, int &Index,
1160 VectorType *&SubTy) const {
1161 if (Mask.empty())
1162 return Kind;
1163 int NumDstElts = Mask.size();
1164 int NumSrcElts = SrcTy->getElementCount().getKnownMinValue();
1165 switch (Kind) {
1167 if (ShuffleVectorInst::isReverseMask(Mask, NumSrcElts))
1168 return TTI::SK_Reverse;
1169 if (ShuffleVectorInst::isZeroEltSplatMask(Mask, NumSrcElts))
1170 return TTI::SK_Broadcast;
1171 if (isSplatMask(Mask, NumSrcElts, Index))
1172 return TTI::SK_Broadcast;
1173 if (ShuffleVectorInst::isExtractSubvectorMask(Mask, NumSrcElts, Index) &&
1174 (Index + NumDstElts) <= NumSrcElts) {
1175 SubTy = FixedVectorType::get(SrcTy->getElementType(), NumDstElts);
1177 }
1178 break;
1179 }
1180 case TTI::SK_PermuteTwoSrc: {
1181 if (all_of(Mask, [NumSrcElts](int M) { return M < NumSrcElts; }))
1183 Index, SubTy);
1184 int NumSubElts;
1185 if (NumDstElts > 2 && ShuffleVectorInst::isInsertSubvectorMask(
1186 Mask, NumSrcElts, NumSubElts, Index)) {
1187 if (Index + NumSubElts > NumSrcElts)
1188 return Kind;
1189 SubTy = FixedVectorType::get(SrcTy->getElementType(), NumSubElts);
1191 }
1192 if (ShuffleVectorInst::isSelectMask(Mask, NumSrcElts))
1193 return TTI::SK_Select;
1194 if (ShuffleVectorInst::isTransposeMask(Mask, NumSrcElts))
1195 return TTI::SK_Transpose;
1196 if (ShuffleVectorInst::isSpliceMask(Mask, NumSrcElts, Index))
1197 return TTI::SK_Splice;
1198 break;
1199 }
1200 case TTI::SK_Select:
1201 case TTI::SK_Reverse:
1202 case TTI::SK_Broadcast:
1203 case TTI::SK_Transpose:
1206 case TTI::SK_Splice:
1207 break;
1208 }
1209 return Kind;
1210 }
1211
1215 VectorType *SubTp, ArrayRef<const Value *> Args = {},
1216 const Instruction *CtxI = nullptr,
1218 TTI::VectorInstrContext::None) const override {
1219 switch (improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp)) {
1220 case TTI::SK_Broadcast:
1221 if (auto *FVT = dyn_cast<FixedVectorType>(SrcTy))
1222 return getBroadcastShuffleOverhead(FVT, CostKind);
1224 case TTI::SK_Select:
1225 case TTI::SK_Splice:
1226 case TTI::SK_Reverse:
1227 case TTI::SK_Transpose:
1230 if (auto *FVT = dyn_cast<FixedVectorType>(SrcTy))
1231 return getPermuteShuffleOverhead(FVT, CostKind);
1234 return getExtractSubvectorOverhead(SrcTy, CostKind, Index,
1235 cast<FixedVectorType>(SubTp));
1237 return getInsertSubvectorOverhead(DstTy, CostKind, Index,
1238 cast<FixedVectorType>(SubTp));
1239 }
1240 llvm_unreachable("Unknown TTI::ShuffleKind");
1241 }
1242
1244 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
1246 const Instruction *I = nullptr) const override {
1247 if (BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I) == 0)
1248 return 0;
1249
1250 const TargetLoweringBase *TLI = getTLI();
1251 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1252 assert(ISD && "Invalid opcode");
1253 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(Src);
1254 std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(Dst);
1255
1256 TypeSize SrcSize = SrcLT.second.getSizeInBits();
1257 TypeSize DstSize = DstLT.second.getSizeInBits();
1258 bool IntOrPtrSrc = Src->isIntegerTy() || Src->isPointerTy();
1259 bool IntOrPtrDst = Dst->isIntegerTy() || Dst->isPointerTy();
1260
1261 switch (Opcode) {
1262 default:
1263 break;
1264 case Instruction::Trunc:
1265 // Check for NOOP conversions.
1266 if (TLI->isTruncateFree(SrcLT.second, DstLT.second))
1267 return 0;
1268 [[fallthrough]];
1269 case Instruction::BitCast:
1270 // Bitcast between types that are legalized to the same type are free and
1271 // assume int to/from ptr of the same size is also free.
1272 if (SrcLT.first == DstLT.first && IntOrPtrSrc == IntOrPtrDst &&
1273 SrcSize == DstSize)
1274 return 0;
1275 break;
1276 case Instruction::FPExt:
1277 if (I && getTLI()->isExtFree(I))
1278 return 0;
1279 break;
1280 case Instruction::ZExt:
1281 if (TLI->isZExtFree(SrcLT.second, DstLT.second))
1282 return 0;
1283 [[fallthrough]];
1284 case Instruction::SExt:
1285 if (I && getTLI()->isExtFree(I))
1286 return 0;
1287
1288 // If this is a zext/sext of a load, return 0 if the corresponding
1289 // extending load exists on target and the result type is legal.
1290 if (CCH == TTI::CastContextHint::Normal) {
1291 EVT ExtVT = EVT::getEVT(Dst);
1292 EVT LoadVT = EVT::getEVT(Src);
1293 unsigned LType =
1294 Opcode == Instruction::ZExt ? ISD::ZEXTLOAD : ISD::SEXTLOAD;
1295 if (I) {
1296 if (auto *LI = dyn_cast<LoadInst>(I->getOperand(0))) {
1297 if (DstLT.first == SrcLT.first &&
1298 TLI->isLoadLegal(ExtVT, LoadVT, LI->getAlign(),
1299 LI->getPointerAddressSpace(), LType, false))
1300 return 0;
1301 } else if (auto *II = dyn_cast<IntrinsicInst>(I->getOperand(0))) {
1302 switch (II->getIntrinsicID()) {
1303 case Intrinsic::masked_load: {
1304 Type *PtrType = II->getArgOperand(0)->getType();
1305 assert(PtrType->isPointerTy());
1306
1307 if (DstLT.first == SrcLT.first &&
1308 TLI->isLoadLegal(
1309 ExtVT, LoadVT, II->getParamAlign(0).valueOrOne(),
1310 PtrType->getPointerAddressSpace(), LType, false))
1311 return 0;
1312
1313 break;
1314 }
1315 default:
1316 break;
1317 }
1318 }
1319 }
1320 }
1321 break;
1322 case Instruction::AddrSpaceCast:
1323 if (TLI->isFreeAddrSpaceCast(DL, Src->getPointerAddressSpace(),
1324 Dst->getPointerAddressSpace()))
1325 return 0;
1326 break;
1327 }
1328
1329 auto *SrcVTy = dyn_cast<VectorType>(Src);
1330 auto *DstVTy = dyn_cast<VectorType>(Dst);
1331
1332 // If the cast is marked as legal (or promote) then assume low cost.
1333 if (SrcLT.first == DstLT.first &&
1334 TLI->isOperationLegalOrPromote(ISD, DstLT.second))
1335 return SrcLT.first;
1336
1337 // Handle scalar conversions.
1338 if (!SrcVTy && !DstVTy) {
1339 // Just check the op cost. If the operation is legal then assume it costs
1340 // 1.
1341 if (!TLI->isOperationExpand(ISD, DstLT.second))
1342 return 1;
1343
1344 // Assume that illegal scalar instruction are expensive.
1345 return 4;
1346 }
1347
1348 // Check vector-to-vector casts.
1349 if (DstVTy && SrcVTy) {
1350 // If the cast is between same-sized registers, then the check is simple.
1351 if (SrcLT.first == DstLT.first && SrcSize == DstSize) {
1352
1353 // Assume that Zext is done using AND.
1354 if (Opcode == Instruction::ZExt)
1355 return SrcLT.first;
1356
1357 // Assume that sext is done using SHL and SRA.
1358 if (Opcode == Instruction::SExt)
1359 return SrcLT.first * 2;
1360
1361 // Just check the op cost. If the operation is legal then assume it
1362 // costs
1363 // 1 and multiply by the type-legalization overhead.
1364 if (!TLI->isOperationExpand(ISD, DstLT.second))
1365 return SrcLT.first * 1;
1366 }
1367
1368 // If we are legalizing by splitting, query the concrete TTI for the cost
1369 // of casting the original vector twice. We also need to factor in the
1370 // cost of the split itself. Count that as 1, to be consistent with
1371 // getTypeLegalizationCost().
1372 bool SplitSrc =
1373 TLI->getTypeAction(Src->getContext(), TLI->getValueType(DL, Src)) ==
1375 bool SplitDst =
1376 TLI->getTypeAction(Dst->getContext(), TLI->getValueType(DL, Dst)) ==
1378 if ((SplitSrc || SplitDst) && SrcVTy->getElementCount().isKnownEven() &&
1379 DstVTy->getElementCount().isKnownEven()) {
1380 Type *SplitDstTy = VectorType::getHalfElementsVectorType(DstVTy);
1381 Type *SplitSrcTy = VectorType::getHalfElementsVectorType(SrcVTy);
1382 const T *TTI = thisT();
1383 // If both types need to be split then the split is free.
1384 InstructionCost SplitCost =
1385 (!SplitSrc || !SplitDst) ? TTI->getVectorSplitCost() : 0;
1386 return SplitCost +
1387 (2 * TTI->getCastInstrCost(Opcode, SplitDstTy, SplitSrcTy, CCH,
1388 CostKind, I));
1389 }
1390
1391 // Scalarization cost is Invalid, can't assume any num elements.
1392 if (isa<ScalableVectorType>(DstVTy))
1394
1395 // In other cases where the source or destination are illegal, assume
1396 // the operation will get scalarized.
1397 unsigned Num = cast<FixedVectorType>(DstVTy)->getNumElements();
1398 InstructionCost Cost = thisT()->getCastInstrCost(
1399 Opcode, Dst->getScalarType(), Src->getScalarType(), CCH, CostKind, I);
1400
1401 // Return the cost of multiple scalar invocation plus the cost of
1402 // inserting and extracting the values.
1403 return getScalarizationOverhead(DstVTy, /*Insert*/ true, /*Extract*/ true,
1404 CostKind) +
1405 Num * Cost;
1406 }
1407
1408 // We already handled vector-to-vector and scalar-to-scalar conversions.
1409 // This
1410 // is where we handle bitcast between vectors and scalars. We need to assume
1411 // that the conversion is scalarized in one way or another.
1412 if (Opcode == Instruction::BitCast) {
1413 // Illegal bitcasts are done by storing and loading from a stack slot.
1414 return (SrcVTy ? getScalarizationOverhead(SrcVTy, /*Insert*/ false,
1415 /*Extract*/ true, CostKind)
1416 : 0) +
1417 (DstVTy ? getScalarizationOverhead(DstVTy, /*Insert*/ true,
1418 /*Extract*/ false, CostKind)
1419 : 0);
1420 }
1421
1422 llvm_unreachable("Unhandled cast");
1423 }
1424
1426 getExtractWithExtendCost(unsigned Opcode, Type *Dst, VectorType *VecTy,
1427 unsigned Index,
1428 TTI::TargetCostKind CostKind) const override {
1429 return thisT()->getVectorInstrCost(Instruction::ExtractElement, VecTy,
1430 CostKind, Index, nullptr, nullptr) +
1431 thisT()->getCastInstrCost(Opcode, Dst, VecTy->getElementType(),
1433 }
1434
1437 const Instruction *I = nullptr) const override {
1438 return BaseT::getCFInstrCost(Opcode, CostKind, I);
1439 }
1440
1442 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
1446 const Instruction *I = nullptr) const override {
1447 const TargetLoweringBase *TLI = getTLI();
1448 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1449 assert(ISD && "Invalid opcode");
1450
1451 if (getTLI()->getValueType(DL, ValTy, true) == MVT::Other)
1452 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
1453 Op1Info, Op2Info, I);
1454
1455 // Selects on vectors are actually vector selects.
1456 if (ISD == ISD::SELECT) {
1457 assert(CondTy && "CondTy must exist");
1458 if (CondTy->isVectorTy())
1459 ISD = ISD::VSELECT;
1460 }
1461 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
1462
1463 if (!(ValTy->isVectorTy() && !LT.second.isVector()) &&
1464 !TLI->isOperationExpand(ISD, LT.second)) {
1465 // The operation is legal. Assume it costs 1. Multiply
1466 // by the type-legalization overhead.
1467 return LT.first * 1;
1468 }
1469
1470 // Otherwise, assume that the cast is scalarized.
1471 // TODO: If one of the types get legalized by splitting, handle this
1472 // similarly to what getCastInstrCost() does.
1473 if (auto *ValVTy = dyn_cast<VectorType>(ValTy)) {
1474 if (isa<ScalableVectorType>(ValTy))
1476
1477 unsigned Num = cast<FixedVectorType>(ValVTy)->getNumElements();
1478 InstructionCost Cost = thisT()->getCmpSelInstrCost(
1479 Opcode, ValVTy->getScalarType(), CondTy->getScalarType(), VecPred,
1480 CostKind, Op1Info, Op2Info, I);
1481
1482 // Return the cost of multiple scalar invocation plus the cost of
1483 // inserting and extracting the values.
1484 return getScalarizationOverhead(ValVTy, /*Insert*/ true,
1485 /*Extract*/ false, CostKind) +
1486 Num * Cost;
1487 }
1488
1489 // Unknown scalar opcode.
1490 return 1;
1491 }
1492
1495 unsigned Index, const Value *Op0, const Value *Op1,
1497 TTI::VectorInstrContext::None) const override {
1498 return getRegUsageForType(Val->getScalarType());
1499 }
1500
1501 /// \param ScalarUserAndIdx encodes the information about extracts from a
1502 /// vector with 'Scalar' being the value being extracted,'User' being the user
1503 /// of the extract(nullptr if user is not known before vectorization) and
1504 /// 'Idx' being the extract lane.
1506 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
1507 Value *Scalar,
1508 ArrayRef<std::tuple<Value *, User *, int>> ScalarUserAndIdx,
1510 TTI::VectorInstrContext::None) const override {
1511 return getVectorInstrCost(Opcode, Val, CostKind, Index, nullptr, nullptr,
1512 VIC);
1513 }
1514
1517 TTI::TargetCostKind CostKind, unsigned Index,
1519 TTI::VectorInstrContext::None) const override {
1520 Value *Op0 = nullptr;
1521 Value *Op1 = nullptr;
1522 if (auto *IE = dyn_cast<InsertElementInst>(&I)) {
1523 Op0 = IE->getOperand(0);
1524 Op1 = IE->getOperand(1);
1525 }
1526 // If VIC is None, compute it from the instruction
1529 return thisT()->getVectorInstrCost(I.getOpcode(), Val, CostKind, Index, Op0,
1530 Op1, VIC);
1531 }
1532
1536 unsigned Index) const override {
1537 unsigned NewIndex = -1;
1538 if (auto *FVTy = dyn_cast<FixedVectorType>(Val)) {
1539 assert(Index < FVTy->getNumElements() &&
1540 "Unexpected index from end of vector");
1541 NewIndex = FVTy->getNumElements() - 1 - Index;
1542 }
1543 return thisT()->getVectorInstrCost(Opcode, Val, CostKind, NewIndex, nullptr,
1544 nullptr);
1545 }
1546
1548 getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF,
1549 const APInt &DemandedDstElts,
1550 TTI::TargetCostKind CostKind) const override {
1551 assert(DemandedDstElts.getBitWidth() == (unsigned)VF * ReplicationFactor &&
1552 "Unexpected size of DemandedDstElts.");
1553
1555
1556 auto *SrcVT = FixedVectorType::get(EltTy, VF);
1557 auto *ReplicatedVT = FixedVectorType::get(EltTy, VF * ReplicationFactor);
1558
1559 // The Mask shuffling cost is extract all the elements of the Mask
1560 // and insert each of them Factor times into the wide vector:
1561 //
1562 // E.g. an interleaved group with factor 3:
1563 // %mask = icmp ult <8 x i32> %vec1, %vec2
1564 // %interleaved.mask = shufflevector <8 x i1> %mask, <8 x i1> undef,
1565 // <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>
1566 // The cost is estimated as extract all mask elements from the <8xi1> mask
1567 // vector and insert them factor times into the <24xi1> shuffled mask
1568 // vector.
1569 APInt DemandedSrcElts = APIntOps::ScaleBitMask(DemandedDstElts, VF);
1570 Cost += thisT()->getScalarizationOverhead(SrcVT, DemandedSrcElts,
1571 /*Insert*/ false,
1572 /*Extract*/ true, CostKind);
1573 Cost += thisT()->getScalarizationOverhead(ReplicatedVT, DemandedDstElts,
1574 /*Insert*/ true,
1575 /*Extract*/ false, CostKind);
1576
1577 return Cost;
1578 }
1579
1581 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
1584 const Instruction *I = nullptr) const override {
1585 assert(!Src->isVoidTy() && "Invalid type");
1586 // Assume types, such as structs, are expensive.
1587 if (getTLI()->getValueType(DL, Src, true) == MVT::Other)
1588 return 4;
1589 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
1590
1591 // FIXME: Arbitrary cost
1592 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
1593 return 4;
1594
1595 // Assuming that all loads of legal types cost 1.
1596 InstructionCost Cost = LT.first;
1598 return Cost;
1599
1600 const DataLayout &DL = this->getDataLayout();
1601 if (Src->isVectorTy() &&
1602 // In practice it's not currently possible to have a change in lane
1603 // length for extending loads or truncating stores so both types should
1604 // have the same scalable property.
1605 TypeSize::isKnownLT(DL.getTypeStoreSizeInBits(Src),
1606 LT.second.getSizeInBits())) {
1607 // This is a vector load that legalizes to a larger type than the vector
1608 // itself. Unless the corresponding extending load or truncating store is
1609 // legal, then this will scalarize.
1611 EVT MemVT = getTLI()->getValueType(DL, Src);
1612 if (Opcode == Instruction::Store)
1613 LA = getTLI()->getTruncStoreAction(LT.second, MemVT, Alignment,
1614 AddressSpace);
1615 else
1616 LA = getTLI()->getLoadAction(LT.second, MemVT, Alignment, AddressSpace,
1617 ISD::EXTLOAD, false);
1618
1619 if (LA != TargetLowering::Legal && LA != TargetLowering::Custom) {
1620 // This is a vector load/store for some illegal type that is scalarized.
1621 // We must account for the cost of building or decomposing the vector.
1623 cast<VectorType>(Src), Opcode != Instruction::Store,
1624 Opcode == Instruction::Store, CostKind);
1625 }
1626 }
1627
1628 return Cost;
1629 }
1630
1632 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
1633 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
1634 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override {
1635
1636 // We cannot scalarize scalable vectors, so return Invalid.
1637 if (isa<ScalableVectorType>(VecTy))
1639
1640 auto *VT = cast<FixedVectorType>(VecTy);
1641
1642 unsigned NumElts = VT->getNumElements();
1643 assert(Factor > 1 && NumElts % Factor == 0 && "Invalid interleave factor");
1644
1645 unsigned NumSubElts = NumElts / Factor;
1646 auto *SubVT = FixedVectorType::get(VT->getElementType(), NumSubElts);
1647
1648 // Firstly, the cost of load/store operation.
1650 if (UseMaskForCond || UseMaskForGaps) {
1651 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
1652 : Intrinsic::masked_store;
1653 Cost = thisT()->getMemIntrinsicInstrCost(
1654 MemIntrinsicCostAttributes(IID, VecTy, Alignment, AddressSpace),
1655 CostKind);
1656 } else
1657 Cost = thisT()->getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace,
1658 CostKind);
1659
1660 // Legalize the vector type, and get the legalized and unlegalized type
1661 // sizes.
1662 MVT VecTyLT = getTypeLegalizationCost(VecTy).second;
1663 unsigned VecTySize = thisT()->getDataLayout().getTypeStoreSize(VecTy);
1664 unsigned VecTyLTSize = VecTyLT.getStoreSize();
1665
1666 // Scale the cost of the memory operation by the fraction of legalized
1667 // instructions that will actually be used. We shouldn't account for the
1668 // cost of dead instructions since they will be removed.
1669 //
1670 // E.g., An interleaved load of factor 8:
1671 // %vec = load <16 x i64>, <16 x i64>* %ptr
1672 // %v0 = shufflevector %vec, undef, <0, 8>
1673 //
1674 // If <16 x i64> is legalized to 8 v2i64 loads, only 2 of the loads will be
1675 // used (those corresponding to elements [0:1] and [8:9] of the unlegalized
1676 // type). The other loads are unused.
1677 //
1678 // TODO: Note that legalization can turn masked loads/stores into unmasked
1679 // (legalized) loads/stores. This can be reflected in the cost.
1680 if (Cost.isValid() && VecTySize > VecTyLTSize) {
1681 // The number of loads of a legal type it will take to represent a load
1682 // of the unlegalized vector type.
1683 unsigned NumLegalInsts = divideCeil(VecTySize, VecTyLTSize);
1684
1685 // The number of elements of the unlegalized type that correspond to a
1686 // single legal instruction.
1687 unsigned NumEltsPerLegalInst = divideCeil(NumElts, NumLegalInsts);
1688
1689 // Determine which legal instructions will be used.
1690 BitVector UsedInsts(NumLegalInsts, false);
1691 for (unsigned Index : Indices)
1692 for (unsigned Elt = 0; Elt < NumSubElts; ++Elt)
1693 UsedInsts.set((Index + Elt * Factor) / NumEltsPerLegalInst);
1694
1695 // Scale the cost of the load by the fraction of legal instructions that
1696 // will be used.
1697 Cost = divideCeil(UsedInsts.count() * Cost.getValue(), NumLegalInsts);
1698 }
1699
1700 // Then plus the cost of interleave operation.
1701 assert(Indices.size() <= Factor &&
1702 "Interleaved memory op has too many members");
1703
1704 const APInt DemandedAllSubElts = APInt::getAllOnes(NumSubElts);
1705 const APInt DemandedAllResultElts = APInt::getAllOnes(NumElts);
1706
1707 APInt DemandedLoadStoreElts = APInt::getZero(NumElts);
1708 for (unsigned Index : Indices) {
1709 assert(Index < Factor && "Invalid index for interleaved memory op");
1710 for (unsigned Elm = 0; Elm < NumSubElts; Elm++)
1711 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
1712 }
1713
1714 if (Opcode == Instruction::Load) {
1715 // The interleave cost is similar to extract sub vectors' elements
1716 // from the wide vector, and insert them into sub vectors.
1717 //
1718 // E.g. An interleaved load of factor 2 (with one member of index 0):
1719 // %vec = load <8 x i32>, <8 x i32>* %ptr
1720 // %v0 = shuffle %vec, undef, <0, 2, 4, 6> ; Index 0
1721 // The cost is estimated as extract elements at 0, 2, 4, 6 from the
1722 // <8 x i32> vector and insert them into a <4 x i32> vector.
1723 InstructionCost InsSubCost = thisT()->getScalarizationOverhead(
1724 SubVT, DemandedAllSubElts,
1725 /*Insert*/ true, /*Extract*/ false, CostKind);
1726 Cost += Indices.size() * InsSubCost;
1727 Cost += thisT()->getScalarizationOverhead(VT, DemandedLoadStoreElts,
1728 /*Insert*/ false,
1729 /*Extract*/ true, CostKind);
1730 } else {
1731 // The interleave cost is extract elements from sub vectors, and
1732 // insert them into the wide vector.
1733 //
1734 // E.g. An interleaved store of factor 3 with 2 members at indices 0,1:
1735 // (using VF=4):
1736 // %v0_v1 = shuffle %v0, %v1, <0,4,undef,1,5,undef,2,6,undef,3,7,undef>
1737 // %gaps.mask = <true, true, false, true, true, false,
1738 // true, true, false, true, true, false>
1739 // call llvm.masked.store <12 x i32> %v0_v1, <12 x i32>* %ptr,
1740 // i32 Align, <12 x i1> %gaps.mask
1741 // The cost is estimated as extract all elements (of actual members,
1742 // excluding gaps) from both <4 x i32> vectors and insert into the <12 x
1743 // i32> vector.
1744 InstructionCost ExtSubCost = thisT()->getScalarizationOverhead(
1745 SubVT, DemandedAllSubElts,
1746 /*Insert*/ false, /*Extract*/ true, CostKind);
1747 Cost += ExtSubCost * Indices.size();
1748 Cost += thisT()->getScalarizationOverhead(VT, DemandedLoadStoreElts,
1749 /*Insert*/ true,
1750 /*Extract*/ false, CostKind);
1751 }
1752
1753 if (!UseMaskForCond)
1754 return Cost;
1755
1756 Type *I8Type = Type::getInt8Ty(VT->getContext());
1757
1758 Cost += thisT()->getReplicationShuffleCost(
1759 I8Type, Factor, NumSubElts,
1760 UseMaskForGaps ? DemandedLoadStoreElts : DemandedAllResultElts,
1761 CostKind);
1762
1763 // The Gaps mask is invariant and created outside the loop, therefore the
1764 // cost of creating it is not accounted for here. However if we have both
1765 // a MaskForGaps and some other mask that guards the execution of the
1766 // memory access, we need to account for the cost of And-ing the two masks
1767 // inside the loop.
1768 if (UseMaskForGaps) {
1769 auto *MaskVT = FixedVectorType::get(I8Type, NumElts);
1770 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::And, MaskVT,
1771 CostKind);
1772 }
1773
1774 return Cost;
1775 }
1776
1777 /// Get intrinsic cost based on arguments.
1780 TTI::TargetCostKind CostKind) const override {
1781 // Check for generically free intrinsics.
1783 return 0;
1784
1785 // Assume that target intrinsics are cheap.
1786 Intrinsic::ID IID = ICA.getID();
1789
1790 // VP Intrinsics should have the same cost as their non-vp counterpart.
1791 // TODO: Adjust the cost to make the vp intrinsic cheaper than its non-vp
1792 // counterpart when the vector length argument is smaller than the maximum
1793 // vector length.
1794 // TODO: Support other kinds of VPIntrinsics
1795 if (VPIntrinsic::isVPIntrinsic(ICA.getID())) {
1796 std::optional<unsigned> FOp =
1798 if (FOp) {
1799 if (ICA.getID() == Intrinsic::vp_load) {
1800 Align Alignment;
1801 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1802 Alignment = VPI->getPointerAlignment().valueOrOne();
1803 unsigned AS = 0;
1804 if (ICA.getArgTypes().size() > 1)
1805 if (auto *PtrTy = dyn_cast<PointerType>(ICA.getArgTypes()[0]))
1806 AS = PtrTy->getAddressSpace();
1807 return thisT()->getMemoryOpCost(*FOp, ICA.getReturnType(), Alignment,
1808 AS, CostKind);
1809 }
1810 if (ICA.getID() == Intrinsic::vp_store) {
1811 Align Alignment;
1812 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1813 Alignment = VPI->getPointerAlignment().valueOrOne();
1814 unsigned AS = 0;
1815 if (ICA.getArgTypes().size() >= 2)
1816 if (auto *PtrTy = dyn_cast<PointerType>(ICA.getArgTypes()[1]))
1817 AS = PtrTy->getAddressSpace();
1818 return thisT()->getMemoryOpCost(*FOp, ICA.getArgTypes()[0], Alignment,
1819 AS, CostKind);
1820 }
1821 if (ICA.getID() == Intrinsic::vp_udiv ||
1822 ICA.getID() == Intrinsic::vp_sdiv ||
1823 ICA.getID() == Intrinsic::vp_urem ||
1824 ICA.getID() == Intrinsic::vp_srem) {
1825 return thisT()->getArithmeticInstrCost(*FOp, ICA.getReturnType(),
1826 CostKind);
1827 }
1828 }
1829 if (ICA.getID() == Intrinsic::vp_load_ff) {
1830 Type *RetTy = ICA.getReturnType();
1831 Type *DataTy = cast<StructType>(RetTy)->getElementType(0);
1832 Align Alignment;
1833 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1834 Alignment = VPI->getPointerAlignment().valueOrOne();
1835 return thisT()->getMemIntrinsicInstrCost(
1836 MemIntrinsicCostAttributes(ICA.getID(), DataTy, Alignment),
1837 CostKind);
1838 }
1839 if (ICA.getID() == Intrinsic::vp_scatter) {
1840 if (ICA.isTypeBasedOnly()) {
1841 IntrinsicCostAttributes MaskedScatter(
1844 ICA.getFlags());
1845 return getTypeBasedIntrinsicInstrCost(MaskedScatter, CostKind);
1846 }
1847 Align Alignment;
1848 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1849 Alignment = VPI->getPointerAlignment().valueOrOne();
1850 bool VarMask = isa<Constant>(ICA.getArgs()[2]);
1851 return thisT()->getMemIntrinsicInstrCost(
1852 MemIntrinsicCostAttributes(Intrinsic::vp_scatter,
1853 ICA.getArgTypes()[0], ICA.getArgs()[1],
1854 VarMask, Alignment, nullptr),
1855 CostKind);
1856 }
1857 if (ICA.getID() == Intrinsic::vp_gather) {
1858 if (ICA.isTypeBasedOnly()) {
1859 IntrinsicCostAttributes MaskedGather(
1862 ICA.getFlags());
1863 return getTypeBasedIntrinsicInstrCost(MaskedGather, CostKind);
1864 }
1865 Align Alignment;
1866 if (auto *VPI = dyn_cast_or_null<VPIntrinsic>(ICA.getInst()))
1867 Alignment = VPI->getPointerAlignment().valueOrOne();
1868 bool VarMask = isa<Constant>(ICA.getArgs()[1]);
1869 return thisT()->getMemIntrinsicInstrCost(
1870 MemIntrinsicCostAttributes(Intrinsic::vp_gather,
1871 ICA.getReturnType(), ICA.getArgs()[0],
1872 VarMask, Alignment, nullptr),
1873 CostKind);
1874 }
1875
1876 if (ICA.getID() == Intrinsic::vp_merge) {
1877 TTI::OperandValueInfo OpInfoX, OpInfoY;
1878 if (!ICA.isTypeBasedOnly()) {
1879 OpInfoX = TTI::getOperandInfo(ICA.getArgs()[0]);
1880 OpInfoY = TTI::getOperandInfo(ICA.getArgs()[1]);
1881 }
1882 return getCmpSelInstrCost(
1883 Instruction::Select, ICA.getReturnType(), ICA.getArgTypes()[0],
1884 CmpInst::BAD_ICMP_PREDICATE, CostKind, OpInfoX, OpInfoY);
1885 }
1886
1887 std::optional<Intrinsic::ID> FID =
1889
1890 // Not functionally equivalent but close enough for cost modelling.
1891 if (ICA.getID() == Intrinsic::experimental_vp_reverse)
1892 FID = Intrinsic::vector_reverse;
1893
1894 if (FID) {
1895 // Non-vp version will have same arg types except mask and vector
1896 // length.
1897 assert(ICA.getArgTypes().size() >= 2 &&
1898 "Expected VPIntrinsic to have Mask and Vector Length args and "
1899 "types");
1900
1901 ArrayRef<const Value *> NewArgs = ArrayRef(ICA.getArgs());
1902 if (!ICA.isTypeBasedOnly())
1903 NewArgs = NewArgs.drop_back(2);
1905
1906 // VPReduction intrinsics have a start value argument that their non-vp
1907 // counterparts do not have, except for the fadd and fmul non-vp
1908 // counterpart.
1910 *FID != Intrinsic::vector_reduce_fadd &&
1911 *FID != Intrinsic::vector_reduce_fmul) {
1912 if (!ICA.isTypeBasedOnly())
1913 NewArgs = NewArgs.drop_front();
1914 NewTys = NewTys.drop_front();
1915 }
1916
1917 IntrinsicCostAttributes NewICA(*FID, ICA.getReturnType(), NewArgs,
1918 NewTys, ICA.getFlags());
1919 return thisT()->getIntrinsicInstrCost(NewICA, CostKind);
1920 }
1921 }
1922
1923 if (ICA.isTypeBasedOnly())
1925
1926 Type *RetTy = ICA.getReturnType();
1927
1928 ElementCount RetVF = isVectorizedTy(RetTy) ? getVectorizedTypeVF(RetTy)
1930
1931 const IntrinsicInst *I = ICA.getInst();
1932 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
1933 FastMathFlags FMF = ICA.getFlags();
1934 switch (IID) {
1935 default:
1936 break;
1937
1938 case Intrinsic::powi:
1939 if (auto *RHSC = dyn_cast<ConstantInt>(Args[1])) {
1940 bool ShouldOptForSize = I->getParent()->getParent()->hasOptSize();
1941 if (getTLI()->isBeneficialToExpandPowI(RHSC->getSExtValue(),
1942 ShouldOptForSize)) {
1943 // The cost is modeled on the expansion performed by ExpandPowI in
1944 // SelectionDAGBuilder.
1945 APInt Exponent = RHSC->getValue().abs();
1946 unsigned ActiveBits = Exponent.getActiveBits();
1947 unsigned PopCount = Exponent.popcount();
1948 InstructionCost Cost = (ActiveBits + PopCount - 2) *
1949 thisT()->getArithmeticInstrCost(
1950 Instruction::FMul, RetTy, CostKind);
1951 if (RHSC->isNegative())
1952 Cost += thisT()->getArithmeticInstrCost(Instruction::FDiv, RetTy,
1953 CostKind);
1954 return Cost;
1955 }
1956 }
1957 break;
1958 case Intrinsic::cttz:
1959 // FIXME: If necessary, this should go in target-specific overrides.
1960 if (RetVF.isScalar() && getTLI()->isCheapToSpeculateCttz(RetTy))
1962 break;
1963
1964 case Intrinsic::ctlz:
1965 // FIXME: If necessary, this should go in target-specific overrides.
1966 if (RetVF.isScalar() && getTLI()->isCheapToSpeculateCtlz(RetTy))
1968 break;
1969
1970 case Intrinsic::memcpy:
1971 return thisT()->getMemcpyCost(ICA.getInst());
1972
1973 case Intrinsic::masked_scatter: {
1974 const Value *Mask = Args[2];
1975 bool VarMask = !isa<Constant>(Mask);
1976 Align Alignment = I->getParamAlign(1).valueOrOne();
1977 return thisT()->getMemIntrinsicInstrCost(
1978 MemIntrinsicCostAttributes(Intrinsic::masked_scatter,
1979 ICA.getArgTypes()[0], Args[1], VarMask,
1980 Alignment, I),
1981 CostKind);
1982 }
1983 case Intrinsic::masked_gather: {
1984 const Value *Mask = Args[1];
1985 bool VarMask = !isa<Constant>(Mask);
1986 Align Alignment = I->getParamAlign(0).valueOrOne();
1987 return thisT()->getMemIntrinsicInstrCost(
1988 MemIntrinsicCostAttributes(Intrinsic::masked_gather, RetTy, Args[0],
1989 VarMask, Alignment, I),
1990 CostKind);
1991 }
1992 case Intrinsic::masked_compressstore: {
1993 const Value *Data = Args[0];
1994 const Value *Mask = Args[2];
1995 Align Alignment = I->getParamAlign(1).valueOrOne();
1996 return thisT()->getMemIntrinsicInstrCost(
1997 MemIntrinsicCostAttributes(IID, Data->getType(), !isa<Constant>(Mask),
1998 Alignment, I),
1999 CostKind);
2000 }
2001 case Intrinsic::masked_expandload: {
2002 const Value *Mask = Args[1];
2003 Align Alignment = I->getParamAlign(0).valueOrOne();
2004 return thisT()->getMemIntrinsicInstrCost(
2005 MemIntrinsicCostAttributes(IID, RetTy, !isa<Constant>(Mask),
2006 Alignment, I),
2007 CostKind);
2008 }
2009 case Intrinsic::experimental_vp_strided_store: {
2010 const Value *Data = Args[0];
2011 const Value *Ptr = Args[1];
2012 const Value *Stride = Args[2];
2013 const Value *Mask = Args[3];
2014 const Value *EVL = Args[4];
2015 bool VarMask = !isa<Constant>(Mask) || !isa<Constant>(EVL);
2016 Type *EltTy = cast<VectorType>(Data->getType())->getElementType();
2017 Align Alignment =
2018 I->getParamAlign(1).value_or(thisT()->DL.getABITypeAlign(EltTy));
2019 return thisT()->getMemIntrinsicInstrCost(
2020 MemIntrinsicCostAttributes(IID, Data->getType(), Ptr, VarMask,
2021 Alignment, I, Stride),
2022 CostKind);
2023 }
2024 case Intrinsic::experimental_vp_strided_load: {
2025 const Value *Ptr = Args[0];
2026 const Value *Stride = Args[1];
2027 const Value *Mask = Args[2];
2028 const Value *EVL = Args[3];
2029 bool VarMask = !isa<Constant>(Mask) || !isa<Constant>(EVL);
2030 Type *EltTy = cast<VectorType>(RetTy)->getElementType();
2031 Align Alignment =
2032 I->getParamAlign(0).value_or(thisT()->DL.getABITypeAlign(EltTy));
2033 return thisT()->getMemIntrinsicInstrCost(
2034 MemIntrinsicCostAttributes(IID, RetTy, Ptr, VarMask, Alignment, I,
2035 Stride),
2036 CostKind);
2037 }
2038 case Intrinsic::stepvector: {
2039 if (isa<ScalableVectorType>(RetTy))
2041 // The cost of materialising a constant integer vector.
2043 }
2044 case Intrinsic::vector_extract: {
2045 // FIXME: Handle case where a scalable vector is extracted from a scalable
2046 // vector
2047 if (isa<ScalableVectorType>(RetTy))
2049 unsigned Index = cast<ConstantInt>(Args[1])->getZExtValue();
2050 return thisT()->getShuffleCost(
2052 cast<VectorType>(Args[0]->getType()), CostKind, {}, Index,
2053 cast<VectorType>(RetTy));
2054 }
2055 case Intrinsic::vector_insert: {
2056 // FIXME: Handle case where a scalable vector is inserted into a scalable
2057 // vector
2058 if (isa<ScalableVectorType>(Args[1]->getType()))
2060 unsigned Index = cast<ConstantInt>(Args[2])->getZExtValue();
2061 return thisT()->getShuffleCost(
2063 cast<VectorType>(Args[0]->getType()), CostKind, {}, Index,
2064 cast<VectorType>(Args[1]->getType()));
2065 }
2066 case Intrinsic::vector_splice_left:
2067 case Intrinsic::vector_splice_right: {
2068 auto *COffset = dyn_cast<ConstantInt>(Args[2]);
2069 if (!COffset)
2070 break;
2071 unsigned Index = COffset->getZExtValue();
2072 return thisT()->getShuffleCost(
2074 cast<VectorType>(Args[0]->getType()), CostKind, {},
2075 IID == Intrinsic::vector_splice_left ? Index : -Index,
2076 cast<VectorType>(RetTy));
2077 }
2078 case Intrinsic::vector_reduce_add:
2079 case Intrinsic::vector_reduce_mul:
2080 case Intrinsic::vector_reduce_and:
2081 case Intrinsic::vector_reduce_or:
2082 case Intrinsic::vector_reduce_xor:
2083 case Intrinsic::vector_reduce_smax:
2084 case Intrinsic::vector_reduce_smin:
2085 case Intrinsic::vector_reduce_fmax:
2086 case Intrinsic::vector_reduce_fmin:
2087 case Intrinsic::vector_reduce_fmaximum:
2088 case Intrinsic::vector_reduce_fminimum:
2089 case Intrinsic::vector_reduce_fmaximumnum:
2090 case Intrinsic::vector_reduce_fminimumnum:
2091 case Intrinsic::vector_reduce_umax:
2092 case Intrinsic::vector_reduce_umin: {
2093 IntrinsicCostAttributes Attrs(IID, RetTy, Args[0]->getType(), FMF, I, 1);
2095 }
2096 case Intrinsic::vector_reduce_fadd:
2097 case Intrinsic::vector_reduce_fmul: {
2099 IID, RetTy, {Args[0]->getType(), Args[1]->getType()}, FMF, I, 1);
2101 }
2102 case Intrinsic::fshl:
2103 case Intrinsic::fshr: {
2104 const Value *X = Args[0];
2105 const Value *Y = Args[1];
2106 const Value *Z = Args[2];
2109 const TTI::OperandValueInfo OpInfoZ = TTI::getOperandInfo(Z);
2110
2111 // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
2112 // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
2114 Cost +=
2115 thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
2116 Cost += thisT()->getArithmeticInstrCost(
2117 BinaryOperator::Shl, RetTy, CostKind, OpInfoX,
2118 {OpInfoZ.Kind, TTI::OP_None});
2119 Cost += thisT()->getArithmeticInstrCost(
2120 BinaryOperator::LShr, RetTy, CostKind, OpInfoY,
2121 {OpInfoZ.Kind, TTI::OP_None});
2122
2123 if (!OpInfoZ.isConstant()) {
2124 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy,
2125 CostKind);
2126 // Non-constant shift amounts requires a modulo. If the typesize is a
2127 // power-2 then this will be converted to an and, otherwise it will use
2128 // a urem.
2129 Cost += thisT()->getArithmeticInstrCost(
2130 isPowerOf2_32(RetTy->getScalarSizeInBits()) ? BinaryOperator::And
2131 : BinaryOperator::URem,
2132 RetTy, CostKind, OpInfoZ,
2133 {TTI::OK_UniformConstantValue, TTI::OP_None});
2134 // For non-rotates (X != Y) we must add shift-by-zero handling costs.
2135 if (X != Y) {
2136 Type *CondTy = RetTy->getWithNewBitWidth(1);
2137 Cost += thisT()->getCmpSelInstrCost(
2138 BinaryOperator::ICmp, RetTy, CondTy, CmpInst::ICMP_EQ, CostKind);
2139 Cost +=
2140 thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
2142 }
2143 }
2144 return Cost;
2145 }
2146 case Intrinsic::experimental_cttz_elts: {
2147 EVT ArgType = getTLI()->getValueType(DL, ICA.getArgTypes()[0], true);
2148
2149 // TODO: The costs below reflect the expansion code in
2150 // TargetLowering::expandCttzElts, but we may want to sacrifice some
2151 // accuracy in favour of compile time.
2152
2153 // Find the smallest "sensible" element type to use for the expansion.
2154 bool ZeroIsPoison = !cast<ConstantInt>(Args[1])->isZero();
2155 ConstantRange VScaleRange(APInt(64, 1), APInt::getZero(64));
2156 if (isa<ScalableVectorType>(ICA.getArgTypes()[0]) && I && I->getCaller())
2157 VScaleRange = getVScaleRange(I->getCaller(), 64);
2158
2159 unsigned EltWidth = getTLI()->getBitWidthForCttzElements(
2160 getTLI()->getValueType(DL, RetTy), ArgType.getVectorElementCount(),
2161 ZeroIsPoison, &VScaleRange);
2162 Type *NewEltTy = IntegerType::getIntNTy(RetTy->getContext(), EltWidth);
2163
2164 // Create the new vector type & get the vector length
2165 Type *NewVecTy = VectorType::get(
2166 NewEltTy, cast<VectorType>(Args[0]->getType())->getElementCount());
2167
2168 IntrinsicCostAttributes StepVecAttrs(Intrinsic::stepvector, NewVecTy, {},
2169 FMF);
2171 thisT()->getIntrinsicInstrCost(StepVecAttrs, CostKind);
2172
2173 Cost +=
2174 thisT()->getArithmeticInstrCost(Instruction::Sub, NewVecTy, CostKind);
2175 Cost += thisT()->getCastInstrCost(Instruction::SExt, NewVecTy,
2176 Args[0]->getType(),
2178 Cost +=
2179 thisT()->getArithmeticInstrCost(Instruction::And, NewVecTy, CostKind);
2180
2181 IntrinsicCostAttributes ReducAttrs(Intrinsic::vector_reduce_umax,
2182 NewEltTy, NewVecTy, FMF, I, 1);
2183 Cost += thisT()->getTypeBasedIntrinsicInstrCost(ReducAttrs, CostKind);
2184 Cost +=
2185 thisT()->getArithmeticInstrCost(Instruction::Sub, NewEltTy, CostKind);
2186
2187 return Cost;
2188 }
2189 case Intrinsic::get_active_lane_mask:
2190 case Intrinsic::experimental_vector_match:
2191 case Intrinsic::experimental_vector_histogram_add:
2192 case Intrinsic::experimental_vector_histogram_uadd_sat:
2193 case Intrinsic::experimental_vector_histogram_umax:
2194 case Intrinsic::experimental_vector_histogram_umin:
2195 case Intrinsic::masked_udiv:
2196 case Intrinsic::masked_sdiv:
2197 case Intrinsic::masked_urem:
2198 case Intrinsic::masked_srem:
2199 return thisT()->getTypeBasedIntrinsicInstrCost(ICA, CostKind);
2200 case Intrinsic::modf:
2201 case Intrinsic::sincos:
2202 case Intrinsic::sincospi: {
2203 std::optional<unsigned> CallRetElementIndex;
2204 // The first element of the modf result is returned by value in the
2205 // libcall.
2206 if (ICA.getID() == Intrinsic::modf)
2207 CallRetElementIndex = 0;
2208
2209 if (auto Cost = getMultipleResultIntrinsicVectorLibCallCost(
2210 ICA, CostKind, CallRetElementIndex))
2211 return *Cost;
2212 // Otherwise, fallback to default scalarization cost.
2213 break;
2214 }
2215 case Intrinsic::loop_dependence_war_mask:
2216 case Intrinsic::loop_dependence_raw_mask: {
2217 // Compute the cost of the expanded version of these intrinsics:
2218 //
2219 // The possible expansions are...
2220 //
2221 // loop_dependence_war_mask:
2222 // diff = (addrB - addrA) / eltSize
2223 // cmp = icmp sle diff, 0
2224 // upper_bound = select cmp, -1, diff
2225 // mask = get_active_lane_mask 0, upper_bound
2226 //
2227 // loop_dependence_raw_mask:
2228 // diff = (abs(addrB - addrA)) / eltSize
2229 // cmp = icmp eq diff, 0
2230 // upper_bound = select cmp, -1, diff
2231 // mask = get_active_lane_mask 0, upper_bound
2232 //
2233 Type *AddrTy = ICA.getArgTypes()[0];
2234 bool IsReadAfterWrite = IID == Intrinsic::loop_dependence_raw_mask;
2235
2237 thisT()->getArithmeticInstrCost(Instruction::Sub, AddrTy, CostKind);
2238 if (IsReadAfterWrite) {
2239 IntrinsicCostAttributes AbsAttrs(Intrinsic::abs, AddrTy, {AddrTy}, {});
2240 Cost += thisT()->getIntrinsicInstrCost(AbsAttrs, CostKind);
2241 }
2242
2243 TTI::OperandValueInfo EltSizeOpInfo =
2244 TTI::getOperandInfo(ICA.getArgs()[2]);
2245 Cost += thisT()->getArithmeticInstrCost(Instruction::SDiv, AddrTy,
2246 CostKind, {}, EltSizeOpInfo);
2247
2248 Type *CondTy = IntegerType::getInt1Ty(RetTy->getContext());
2249 CmpInst::Predicate Pred =
2250 IsReadAfterWrite ? CmpInst::ICMP_EQ : CmpInst::ICMP_SLE;
2251 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, CondTy, AddrTy,
2252 Pred, CostKind);
2253 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, AddrTy,
2254 CondTy, Pred, CostKind);
2255
2256 IntrinsicCostAttributes Attrs(Intrinsic::get_active_lane_mask, RetTy,
2257 {AddrTy, AddrTy}, FMF);
2258 Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
2259 return Cost;
2260 }
2261 }
2262
2263 // Assume that we need to scalarize this intrinsic.)
2264 // Compute the scalarization overhead based on Args for a vector
2265 // intrinsic.
2266 InstructionCost ScalarizationCost = InstructionCost::getInvalid();
2267 if (RetVF.isVector() && !RetVF.isScalable()) {
2268 ScalarizationCost = 0;
2269 if (!RetTy->isVoidTy()) {
2270 for (Type *VectorTy : getContainedTypes(RetTy)) {
2271 ScalarizationCost += getScalarizationOverhead(
2272 cast<VectorType>(VectorTy),
2273 /*Insert=*/true, /*Extract=*/false, CostKind);
2274 }
2275 }
2276 ScalarizationCost += getOperandsScalarizationOverhead(
2277 filterConstantAndDuplicatedOperands(Args, ICA.getArgTypes()),
2278 CostKind);
2279 }
2280
2281 IntrinsicCostAttributes Attrs(IID, RetTy, ICA.getArgTypes(), FMF, I,
2282 ScalarizationCost);
2283 return thisT()->getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
2284 }
2285
2286 /// Get intrinsic cost based on argument types.
2287 /// If ScalarizationCostPassed is std::numeric_limits<unsigned>::max(), the
2288 /// cost of scalarizing the arguments and the return value will be computed
2289 /// based on types.
2293 Intrinsic::ID IID = ICA.getID();
2294 Type *RetTy = ICA.getReturnType();
2295 const SmallVectorImpl<Type *> &Tys = ICA.getArgTypes();
2296 FastMathFlags FMF = ICA.getFlags();
2297 InstructionCost ScalarizationCostPassed = ICA.getScalarizationCost();
2298 bool SkipScalarizationCost = ICA.skipScalarizationCost();
2299
2300 VectorType *VecOpTy = nullptr;
2301 if (!Tys.empty()) {
2302 // The vector reduction operand is operand 0 except for fadd/fmul.
2303 // Their operand 0 is a scalar start value, so the vector op is operand 1.
2304 unsigned VecTyIndex = 0;
2305 if (IID == Intrinsic::vector_reduce_fadd ||
2306 IID == Intrinsic::vector_reduce_fmul)
2307 VecTyIndex = 1;
2308 assert(Tys.size() > VecTyIndex && "Unexpected IntrinsicCostAttributes");
2309 VecOpTy = dyn_cast<VectorType>(Tys[VecTyIndex]);
2310 }
2311
2312 // Library call cost - other than size, make it expensive.
2313 unsigned SingleCallCost = CostKind == TTI::TCK_CodeSize ? 1 : 10;
2314 unsigned ISD = 0;
2315 switch (IID) {
2316 default: {
2317 // Scalable vectors cannot be scalarized, so return Invalid.
2318 if (isa<ScalableVectorType>(RetTy) || any_of(Tys, [](const Type *Ty) {
2319 return isa<ScalableVectorType>(Ty);
2320 }))
2322
2323 // Assume that we need to scalarize this intrinsic.
2324 InstructionCost ScalarizationCost =
2325 SkipScalarizationCost ? ScalarizationCostPassed : 0;
2326 unsigned ScalarCalls = 1;
2327 Type *ScalarRetTy = RetTy;
2328 if (auto *RetVTy = dyn_cast<VectorType>(RetTy)) {
2329 if (!SkipScalarizationCost)
2330 ScalarizationCost = getScalarizationOverhead(
2331 RetVTy, /*Insert*/ true, /*Extract*/ false, CostKind);
2332 ScalarCalls = std::max(ScalarCalls,
2333 cast<FixedVectorType>(RetVTy)->getNumElements());
2334 ScalarRetTy = RetTy->getScalarType();
2335 }
2336 SmallVector<Type *, 4> ScalarTys;
2337 for (Type *Ty : Tys) {
2338 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
2339 if (!SkipScalarizationCost)
2340 ScalarizationCost += getScalarizationOverhead(
2341 VTy, /*Insert*/ false, /*Extract*/ true, CostKind);
2342 ScalarCalls = std::max(ScalarCalls,
2343 cast<FixedVectorType>(VTy)->getNumElements());
2344 Ty = Ty->getScalarType();
2345 }
2346 ScalarTys.push_back(Ty);
2347 }
2348 if (ScalarCalls == 1)
2349 return 1; // Return cost of a scalar intrinsic. Assume it to be cheap.
2350
2351 IntrinsicCostAttributes ScalarAttrs(IID, ScalarRetTy, ScalarTys, FMF);
2352 InstructionCost ScalarCost =
2353 thisT()->getIntrinsicInstrCost(ScalarAttrs, CostKind);
2354
2355 return ScalarCalls * ScalarCost + ScalarizationCost;
2356 }
2357 // Look for intrinsics that can be lowered directly or turned into a scalar
2358 // intrinsic call.
2359 case Intrinsic::sqrt:
2360 ISD = ISD::FSQRT;
2361 break;
2362 case Intrinsic::sin:
2363 ISD = ISD::FSIN;
2364 break;
2365 case Intrinsic::cos:
2366 ISD = ISD::FCOS;
2367 break;
2368 case Intrinsic::sincos:
2369 ISD = ISD::FSINCOS;
2370 break;
2371 case Intrinsic::sincospi:
2373 break;
2374 case Intrinsic::modf:
2375 ISD = ISD::FMODF;
2376 break;
2377 case Intrinsic::tan:
2378 ISD = ISD::FTAN;
2379 break;
2380 case Intrinsic::asin:
2381 ISD = ISD::FASIN;
2382 break;
2383 case Intrinsic::acos:
2384 ISD = ISD::FACOS;
2385 break;
2386 case Intrinsic::atan:
2387 ISD = ISD::FATAN;
2388 break;
2389 case Intrinsic::atan2:
2390 ISD = ISD::FATAN2;
2391 break;
2392 case Intrinsic::sinh:
2393 ISD = ISD::FSINH;
2394 break;
2395 case Intrinsic::cosh:
2396 ISD = ISD::FCOSH;
2397 break;
2398 case Intrinsic::tanh:
2399 ISD = ISD::FTANH;
2400 break;
2401 case Intrinsic::exp:
2402 ISD = ISD::FEXP;
2403 break;
2404 case Intrinsic::exp2:
2405 ISD = ISD::FEXP2;
2406 break;
2407 case Intrinsic::exp10:
2408 ISD = ISD::FEXP10;
2409 break;
2410 case Intrinsic::log:
2411 ISD = ISD::FLOG;
2412 break;
2413 case Intrinsic::log10:
2414 ISD = ISD::FLOG10;
2415 break;
2416 case Intrinsic::log2:
2417 ISD = ISD::FLOG2;
2418 break;
2419 case Intrinsic::ldexp:
2420 ISD = ISD::FLDEXP;
2421 break;
2422 case Intrinsic::fabs:
2423 ISD = ISD::FABS;
2424 break;
2425 case Intrinsic::canonicalize:
2427 break;
2428 case Intrinsic::minnum:
2429 ISD = ISD::FMINNUM;
2430 break;
2431 case Intrinsic::maxnum:
2432 ISD = ISD::FMAXNUM;
2433 break;
2434 case Intrinsic::minimum:
2436 break;
2437 case Intrinsic::maximum:
2439 break;
2440 case Intrinsic::minimumnum:
2442 break;
2443 case Intrinsic::maximumnum:
2445 break;
2446 case Intrinsic::copysign:
2448 break;
2449 case Intrinsic::floor:
2450 ISD = ISD::FFLOOR;
2451 break;
2452 case Intrinsic::ceil:
2453 ISD = ISD::FCEIL;
2454 break;
2455 case Intrinsic::trunc:
2456 ISD = ISD::FTRUNC;
2457 break;
2458 case Intrinsic::nearbyint:
2460 break;
2461 case Intrinsic::rint:
2462 ISD = ISD::FRINT;
2463 break;
2464 case Intrinsic::lrint:
2465 ISD = ISD::LRINT;
2466 break;
2467 case Intrinsic::llrint:
2468 ISD = ISD::LLRINT;
2469 break;
2470 case Intrinsic::round:
2471 ISD = ISD::FROUND;
2472 break;
2473 case Intrinsic::roundeven:
2475 break;
2476 case Intrinsic::lround:
2477 ISD = ISD::LROUND;
2478 break;
2479 case Intrinsic::llround:
2480 ISD = ISD::LLROUND;
2481 break;
2482 case Intrinsic::pow:
2483 ISD = ISD::FPOW;
2484 break;
2485 case Intrinsic::fma:
2486 ISD = ISD::FMA;
2487 break;
2488 case Intrinsic::fmuladd:
2489 ISD = ISD::FMA;
2490 break;
2491 case Intrinsic::experimental_constrained_fmuladd:
2493 break;
2494 // FIXME: We should return 0 whenever getIntrinsicCost == TCC_Free.
2495 case Intrinsic::lifetime_start:
2496 case Intrinsic::lifetime_end:
2497 case Intrinsic::sideeffect:
2498 case Intrinsic::pseudoprobe:
2499 case Intrinsic::arithmetic_fence:
2500 return 0;
2501 case Intrinsic::masked_store: {
2502 Type *Ty = Tys[0];
2503 Align TyAlign = thisT()->DL.getABITypeAlign(Ty);
2504 return thisT()->getMemIntrinsicInstrCost(
2505 MemIntrinsicCostAttributes(IID, Ty, TyAlign, 0), CostKind);
2506 }
2507 case Intrinsic::masked_load: {
2508 Type *Ty = RetTy;
2509 Align TyAlign = thisT()->DL.getABITypeAlign(Ty);
2510 return thisT()->getMemIntrinsicInstrCost(
2511 MemIntrinsicCostAttributes(IID, Ty, TyAlign, 0), CostKind);
2512 }
2513 case Intrinsic::speculative_load: {
2514 const IntrinsicInst *I = ICA.getInst();
2515 Align Alignment = I ? I->getParamAlign(0).valueOrOne() : Align(1);
2516 unsigned AS = Tys[0]->getPointerAddressSpace();
2517 return thisT()->getMemIntrinsicInstrCost(
2518 MemIntrinsicCostAttributes(IID, RetTy, Alignment, AS), CostKind);
2519 }
2520 case Intrinsic::experimental_vp_strided_store: {
2521 auto *Ty = cast<VectorType>(ICA.getArgTypes()[0]);
2522 Align Alignment = thisT()->DL.getABITypeAlign(Ty->getElementType());
2523 return thisT()->getMemIntrinsicInstrCost(
2524 MemIntrinsicCostAttributes(IID, Ty, /*Ptr=*/nullptr,
2525 /*VariableMask=*/true, Alignment,
2526 ICA.getInst()),
2527 CostKind);
2528 }
2529 case Intrinsic::experimental_vp_strided_load: {
2530 auto *Ty = cast<VectorType>(ICA.getReturnType());
2531 Align Alignment = thisT()->DL.getABITypeAlign(Ty->getElementType());
2532 return thisT()->getMemIntrinsicInstrCost(
2533 MemIntrinsicCostAttributes(IID, Ty, /*Ptr=*/nullptr,
2534 /*VariableMask=*/true, Alignment,
2535 ICA.getInst()),
2536 CostKind);
2537 }
2538 case Intrinsic::vector_reduce_add:
2539 case Intrinsic::vector_reduce_mul:
2540 case Intrinsic::vector_reduce_and:
2541 case Intrinsic::vector_reduce_or:
2542 case Intrinsic::vector_reduce_xor:
2543 return thisT()->getArithmeticReductionCost(
2544 getArithmeticReductionInstruction(IID), VecOpTy, std::nullopt,
2545 CostKind);
2546 case Intrinsic::vector_reduce_fadd:
2547 case Intrinsic::vector_reduce_fmul:
2548 return thisT()->getArithmeticReductionCost(
2549 getArithmeticReductionInstruction(IID), VecOpTy, FMF, CostKind);
2550 case Intrinsic::vector_reduce_smax:
2551 case Intrinsic::vector_reduce_smin:
2552 case Intrinsic::vector_reduce_umax:
2553 case Intrinsic::vector_reduce_umin:
2554 case Intrinsic::vector_reduce_fmax:
2555 case Intrinsic::vector_reduce_fmin:
2556 case Intrinsic::vector_reduce_fmaximum:
2557 case Intrinsic::vector_reduce_fminimum:
2558 case Intrinsic::vector_reduce_fmaximumnum:
2559 case Intrinsic::vector_reduce_fminimumnum:
2560 return thisT()->getMinMaxReductionCost(getMinMaxReductionIntrinsicOp(IID),
2561 VecOpTy, ICA.getFlags(), CostKind);
2562 case Intrinsic::vector_partial_reduce_add:
2563 case Intrinsic::vector_partial_reduce_fadd: {
2564 VectorType *AccTy = cast<VectorType>(ICA.getArgTypes()[0]);
2565 VectorType *InTy = cast<VectorType>(ICA.getArgTypes()[1]);
2566 // TODO: See if something better can be done for scalable-to-fixed
2567 // partial reductions.
2568 if (AccTy->isScalableTy() != InTy->isScalableTy())
2570
2571 unsigned Opcode = 0;
2572 switch (IID) {
2573 default:
2574 llvm_unreachable("Unexpected partial reduction");
2575 break;
2576 case Intrinsic::vector_partial_reduce_add:
2577 Opcode = Instruction::Add;
2578 break;
2579 case Intrinsic::vector_partial_reduce_fadd:
2580 Opcode = Instruction::FAdd;
2581 break;
2582 }
2583
2584 // TODO: Factor in subvector extract costs if the types are different
2585 // sizes. We get some ridiculously high costs for vector_extract
2586 // at present, so fix that first.
2587 // For a type-only query, model as (possibly multiple) basic instructions
2588 // for the accumulator type.
2590 AccTy->getElementCount()) *
2591 thisT()->getArithmeticInstrCost(Opcode, AccTy, CostKind);
2592 }
2593 case Intrinsic::experimental_vector_match: {
2594 auto *SearchTy = cast<VectorType>(ICA.getArgTypes()[0]);
2595 auto *NeedleTy = cast<FixedVectorType>(ICA.getArgTypes()[1]);
2596 unsigned SearchSize = NeedleTy->getNumElements();
2597
2598 // Approximate the cost based on the expansion code in
2599 // TargetLowering::expandVectorMatch.
2601 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, NeedleTy,
2602 CostKind, 1, nullptr, nullptr);
2603 Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, SearchTy,
2604 CostKind, 0, nullptr, nullptr);
2605 Cost += thisT()->getShuffleCost(TTI::SK_Broadcast, SearchTy, SearchTy,
2606 CostKind, {}, 0, nullptr);
2607 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SearchTy, RetTy,
2609 Cost +=
2610 thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
2611 Cost *= SearchSize;
2612 Cost +=
2613 thisT()->getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
2614 return Cost;
2615 }
2616 case Intrinsic::vector_reverse:
2617 return thisT()->getShuffleCost(TTI::SK_Reverse, cast<VectorType>(RetTy),
2618 cast<VectorType>(ICA.getArgTypes()[0]),
2619 CostKind, {}, 0, cast<VectorType>(RetTy));
2620 case Intrinsic::experimental_vector_histogram_add:
2621 case Intrinsic::experimental_vector_histogram_uadd_sat:
2622 case Intrinsic::experimental_vector_histogram_umax:
2623 case Intrinsic::experimental_vector_histogram_umin: {
2625 Type *EltTy = ICA.getArgTypes()[1];
2626
2627 // Targets with scalable vectors must handle this on their own.
2628 if (!PtrsTy)
2630
2631 Align Alignment = thisT()->DL.getABITypeAlign(EltTy);
2633 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, PtrsTy,
2634 CostKind, 1, nullptr, nullptr);
2635 Cost += thisT()->getMemoryOpCost(Instruction::Load, EltTy, Alignment, 0,
2636 CostKind);
2637 switch (IID) {
2638 default:
2639 llvm_unreachable("Unhandled histogram update operation.");
2640 case Intrinsic::experimental_vector_histogram_add:
2641 Cost +=
2642 thisT()->getArithmeticInstrCost(Instruction::Add, EltTy, CostKind);
2643 break;
2644 case Intrinsic::experimental_vector_histogram_uadd_sat: {
2645 IntrinsicCostAttributes UAddSat(Intrinsic::uadd_sat, EltTy, {EltTy});
2646 Cost += thisT()->getIntrinsicInstrCost(UAddSat, CostKind);
2647 break;
2648 }
2649 case Intrinsic::experimental_vector_histogram_umax: {
2650 IntrinsicCostAttributes UMax(Intrinsic::umax, EltTy, {EltTy});
2651 Cost += thisT()->getIntrinsicInstrCost(UMax, CostKind);
2652 break;
2653 }
2654 case Intrinsic::experimental_vector_histogram_umin: {
2655 IntrinsicCostAttributes UMin(Intrinsic::umin, EltTy, {EltTy});
2656 Cost += thisT()->getIntrinsicInstrCost(UMin, CostKind);
2657 break;
2658 }
2659 }
2660 Cost += thisT()->getMemoryOpCost(Instruction::Store, EltTy, Alignment, 0,
2661 CostKind);
2662 Cost *= PtrsTy->getNumElements();
2663 return Cost;
2664 }
2665 case Intrinsic::get_active_lane_mask: {
2666 Type *ArgTy = ICA.getArgTypes()[0];
2667 EVT ResVT = getTLI()->getValueType(DL, RetTy, true);
2668 EVT ArgVT = getTLI()->getValueType(DL, ArgTy, true);
2669
2670 // If we're not expanding the intrinsic then we assume this is cheap
2671 // to implement.
2672 if (!getTLI()->shouldExpandGetActiveLaneMask(ResVT, ArgVT))
2673 return getTypeLegalizationCost(RetTy).first;
2674
2675 // Create the expanded types that will be used to calculate the uadd_sat
2676 // operation.
2677 Type *ExpRetTy =
2678 VectorType::get(ArgTy, cast<VectorType>(RetTy)->getElementCount());
2679 IntrinsicCostAttributes Attrs(Intrinsic::uadd_sat, ExpRetTy, {}, FMF);
2681 thisT()->getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
2682 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, ExpRetTy, RetTy,
2684 return Cost;
2685 }
2686 case Intrinsic::experimental_memset_pattern:
2687 // This cost is set to match the cost of the memset_pattern16 libcall.
2688 // It should likely be re-evaluated after migration to this intrinsic
2689 // is complete.
2690 return TTI::TCC_Basic * 4;
2691 case Intrinsic::abs:
2692 ISD = ISD::ABS;
2693 break;
2694 case Intrinsic::fshl:
2695 ISD = ISD::FSHL;
2696 break;
2697 case Intrinsic::fshr:
2698 ISD = ISD::FSHR;
2699 break;
2700 case Intrinsic::smax:
2701 ISD = ISD::SMAX;
2702 break;
2703 case Intrinsic::smin:
2704 ISD = ISD::SMIN;
2705 break;
2706 case Intrinsic::umax:
2707 ISD = ISD::UMAX;
2708 break;
2709 case Intrinsic::umin:
2710 ISD = ISD::UMIN;
2711 break;
2712 case Intrinsic::sadd_sat:
2713 ISD = ISD::SADDSAT;
2714 break;
2715 case Intrinsic::ssub_sat:
2716 ISD = ISD::SSUBSAT;
2717 break;
2718 case Intrinsic::uadd_sat:
2719 ISD = ISD::UADDSAT;
2720 break;
2721 case Intrinsic::usub_sat:
2722 ISD = ISD::USUBSAT;
2723 break;
2724 case Intrinsic::smul_fix:
2725 ISD = ISD::SMULFIX;
2726 break;
2727 case Intrinsic::umul_fix:
2728 ISD = ISD::UMULFIX;
2729 break;
2730 case Intrinsic::sadd_with_overflow:
2731 ISD = ISD::SADDO;
2732 break;
2733 case Intrinsic::ssub_with_overflow:
2734 ISD = ISD::SSUBO;
2735 break;
2736 case Intrinsic::uadd_with_overflow:
2737 ISD = ISD::UADDO;
2738 break;
2739 case Intrinsic::usub_with_overflow:
2740 ISD = ISD::USUBO;
2741 break;
2742 case Intrinsic::smul_with_overflow:
2743 ISD = ISD::SMULO;
2744 break;
2745 case Intrinsic::umul_with_overflow:
2746 ISD = ISD::UMULO;
2747 break;
2748 case Intrinsic::fptosi_sat:
2749 case Intrinsic::fptoui_sat: {
2750 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(Tys[0]);
2751 std::pair<InstructionCost, MVT> RetLT = getTypeLegalizationCost(RetTy);
2752
2753 // For cast instructions, types are different between source and
2754 // destination. Also need to check if the source type can be legalize.
2755 if (!SrcLT.first.isValid() || !RetLT.first.isValid())
2757 ISD = IID == Intrinsic::fptosi_sat ? ISD::FP_TO_SINT_SAT
2759 break;
2760 }
2761 case Intrinsic::ctpop:
2762 ISD = ISD::CTPOP;
2763 // In case of legalization use TCC_Expensive. This is cheaper than a
2764 // library call but still not a cheap instruction.
2765 SingleCallCost = TargetTransformInfo::TCC_Expensive;
2766 break;
2767 case Intrinsic::ctlz:
2768 ISD = ISD::CTLZ;
2769 break;
2770 case Intrinsic::cttz:
2771 ISD = ISD::CTTZ;
2772 break;
2773 case Intrinsic::bswap:
2774 ISD = ISD::BSWAP;
2775 break;
2776 case Intrinsic::bitreverse:
2778 break;
2779 case Intrinsic::ucmp:
2780 ISD = ISD::UCMP;
2781 break;
2782 case Intrinsic::scmp:
2783 ISD = ISD::SCMP;
2784 break;
2785 case Intrinsic::clmul:
2786 ISD = ISD::CLMUL;
2787 break;
2788 case Intrinsic::smulh:
2789 ISD = ISD::MULHS;
2790 break;
2791 case Intrinsic::umulh:
2792 ISD = ISD::MULHU;
2793 break;
2794 case Intrinsic::masked_udiv:
2795 case Intrinsic::masked_sdiv:
2796 case Intrinsic::masked_urem:
2797 case Intrinsic::masked_srem: {
2798 unsigned UnmaskedOpc;
2799 switch (IID) {
2800 case Intrinsic::masked_udiv:
2802 UnmaskedOpc = Instruction::UDiv;
2803 break;
2804 case Intrinsic::masked_sdiv:
2806 UnmaskedOpc = Instruction::SDiv;
2807 break;
2808 case Intrinsic::masked_urem:
2810 UnmaskedOpc = Instruction::URem;
2811 break;
2812 case Intrinsic::masked_srem:
2814 UnmaskedOpc = Instruction::SRem;
2815 break;
2816 default:
2817 llvm_unreachable("Unexpected intrinsic ID");
2818 }
2820 thisT()->getArithmeticInstrCost(UnmaskedOpc, RetTy, CostKind);
2821
2822 // Expansion generates a (select %mask, %rhs, 1) for the divisor.
2823 MVT LT = getTypeLegalizationCost(RetTy).second;
2824 if (!getTLI()->isOperationLegalOrCustom(ISD, LT)) {
2825 Type *CondTy = cast<VectorType>(RetTy)->getWithNewType(
2827 Cost += thisT()->getCmpSelInstrCost(
2828 BinaryOperator::Select, RetTy, CondTy, CmpInst::BAD_ICMP_PREDICATE,
2830 }
2831
2832 return Cost;
2833 }
2834 }
2835
2836 auto *ST = dyn_cast<StructType>(RetTy);
2837 Type *LegalizeTy = ST ? ST->getContainedType(0) : RetTy;
2838 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(LegalizeTy);
2839
2840 const TargetLoweringBase *TLI = getTLI();
2841
2842 if (TLI->isOperationLegalOrPromote(ISD, LT.second)) {
2843 if (IID == Intrinsic::fabs && LT.second.isFloatingPoint() &&
2844 TLI->isFAbsFree(LT.second)) {
2845 return 0;
2846 }
2847
2848 // The operation is legal. Assume it costs 1.
2849 // If the type is split to multiple registers, assume that there is some
2850 // overhead to this.
2851 // TODO: Once we have extract/insert subvector cost we need to use them.
2852 if (LT.first > 1)
2853 return (LT.first * 2);
2854 else
2855 return (LT.first * 1);
2856 } else if (TLI->isOperationCustom(ISD, LT.second)) {
2857 // If the operation is custom lowered then assume
2858 // that the code is twice as expensive.
2859 return (LT.first * 2);
2860 }
2861
2862 switch (IID) {
2863 case Intrinsic::fmuladd: {
2864 // If we can't lower fmuladd into an FMA estimate the cost as a floating
2865 // point mul followed by an add.
2866
2867 return thisT()->getArithmeticInstrCost(BinaryOperator::FMul, RetTy,
2868 CostKind) +
2869 thisT()->getArithmeticInstrCost(BinaryOperator::FAdd, RetTy,
2870 CostKind);
2871 }
2872 case Intrinsic::experimental_constrained_fmuladd: {
2873 IntrinsicCostAttributes FMulAttrs(
2874 Intrinsic::experimental_constrained_fmul, RetTy, Tys);
2875 IntrinsicCostAttributes FAddAttrs(
2876 Intrinsic::experimental_constrained_fadd, RetTy, Tys);
2877 return thisT()->getIntrinsicInstrCost(FMulAttrs, CostKind) +
2878 thisT()->getIntrinsicInstrCost(FAddAttrs, CostKind);
2879 }
2880 case Intrinsic::smin:
2881 case Intrinsic::smax:
2882 case Intrinsic::umin:
2883 case Intrinsic::umax: {
2884 // minmax(X,Y) = select(icmp(X,Y),X,Y)
2885 Type *CondTy = RetTy->getWithNewBitWidth(1);
2886 bool IsUnsigned = IID == Intrinsic::umax || IID == Intrinsic::umin;
2887 CmpInst::Predicate Pred =
2888 IsUnsigned ? CmpInst::ICMP_UGT : CmpInst::ICMP_SGT;
2890 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
2891 Pred, CostKind);
2892 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
2893 Pred, CostKind);
2894 return Cost;
2895 }
2896 case Intrinsic::sadd_with_overflow:
2897 case Intrinsic::ssub_with_overflow: {
2898 Type *SumTy = RetTy->getContainedType(0);
2899 Type *OverflowTy = RetTy->getContainedType(1);
2900 unsigned Opcode = IID == Intrinsic::sadd_with_overflow
2901 ? BinaryOperator::Add
2902 : BinaryOperator::Sub;
2903
2904 // Add:
2905 // Overflow -> (Result < LHS) ^ (RHS < 0)
2906 // Sub:
2907 // Overflow -> (Result < LHS) ^ (RHS > 0)
2909 Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
2910 Cost +=
2911 2 * thisT()->getCmpSelInstrCost(Instruction::ICmp, SumTy, OverflowTy,
2913 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::Xor, OverflowTy,
2914 CostKind);
2915 return Cost;
2916 }
2917 case Intrinsic::uadd_with_overflow:
2918 case Intrinsic::usub_with_overflow: {
2919 Type *SumTy = RetTy->getContainedType(0);
2920 Type *OverflowTy = RetTy->getContainedType(1);
2921 unsigned Opcode = IID == Intrinsic::uadd_with_overflow
2922 ? BinaryOperator::Add
2923 : BinaryOperator::Sub;
2924 CmpInst::Predicate Pred = IID == Intrinsic::uadd_with_overflow
2927
2929 Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
2930 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy,
2931 OverflowTy, Pred, CostKind);
2932 return Cost;
2933 }
2934 case Intrinsic::smul_with_overflow:
2935 case Intrinsic::umul_with_overflow: {
2936 Type *MulTy = RetTy->getContainedType(0);
2937 Type *OverflowTy = RetTy->getContainedType(1);
2938 unsigned ExtSize = MulTy->getScalarSizeInBits() * 2;
2939 Type *ExtTy = MulTy->getWithNewBitWidth(ExtSize);
2940 bool IsSigned = IID == Intrinsic::smul_with_overflow;
2941
2942 unsigned ExtOp = IsSigned ? Instruction::SExt : Instruction::ZExt;
2944
2946 Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, MulTy, CCH, CostKind);
2947 Cost +=
2948 thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
2949 Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, MulTy, ExtTy,
2950 CCH, CostKind);
2951 Cost += thisT()->getArithmeticInstrCost(
2952 Instruction::LShr, ExtTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
2954
2955 if (IsSigned)
2956 Cost += thisT()->getArithmeticInstrCost(
2957 Instruction::AShr, MulTy, CostKind,
2960
2961 Cost += thisT()->getCmpSelInstrCost(
2962 BinaryOperator::ICmp, MulTy, OverflowTy, CmpInst::ICMP_NE, CostKind);
2963 return Cost;
2964 }
2965 case Intrinsic::sadd_sat:
2966 case Intrinsic::ssub_sat: {
2967 // Assume a default expansion.
2968 Type *CondTy = RetTy->getWithNewBitWidth(1);
2969
2970 Type *OpTy = StructType::create({RetTy, CondTy});
2971 Intrinsic::ID OverflowOp = IID == Intrinsic::sadd_sat
2972 ? Intrinsic::sadd_with_overflow
2973 : Intrinsic::ssub_with_overflow;
2975
2976 // SatMax -> Overflow && SumDiff < 0
2977 // SatMin -> Overflow && SumDiff >= 0
2979 IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
2980 nullptr, ScalarizationCostPassed);
2981 Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
2982 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
2983 Pred, CostKind);
2984 Cost += 2 * thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
2985 CondTy, Pred, CostKind);
2986 return Cost;
2987 }
2988 case Intrinsic::uadd_sat:
2989 case Intrinsic::usub_sat: {
2990 Type *CondTy = RetTy->getWithNewBitWidth(1);
2991
2992 Type *OpTy = StructType::create({RetTy, CondTy});
2993 Intrinsic::ID OverflowOp = IID == Intrinsic::uadd_sat
2994 ? Intrinsic::uadd_with_overflow
2995 : Intrinsic::usub_with_overflow;
2996
2998 IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
2999 nullptr, ScalarizationCostPassed);
3000 Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
3001 Cost +=
3002 thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
3004 return Cost;
3005 }
3006 case Intrinsic::smul_fix:
3007 case Intrinsic::umul_fix: {
3008 unsigned ExtSize = RetTy->getScalarSizeInBits() * 2;
3009 Type *ExtTy = RetTy->getWithNewBitWidth(ExtSize);
3010
3011 unsigned ExtOp =
3012 IID == Intrinsic::smul_fix ? Instruction::SExt : Instruction::ZExt;
3014
3016 Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, RetTy, CCH, CostKind);
3017 Cost +=
3018 thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
3019 Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, RetTy, ExtTy,
3020 CCH, CostKind);
3021 Cost += thisT()->getArithmeticInstrCost(
3022 Instruction::LShr, RetTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3024 Cost += thisT()->getArithmeticInstrCost(
3025 Instruction::Shl, RetTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3027 Cost += thisT()->getArithmeticInstrCost(Instruction::Or, RetTy, CostKind);
3028 return Cost;
3029 }
3030 case Intrinsic::abs: {
3031 // abs(X) = select(icmp(X,0),X,sub(0,X))
3032 Type *CondTy = RetTy->getWithNewBitWidth(1);
3035 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
3036 Pred, CostKind);
3037 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
3038 Pred, CostKind);
3039 // TODO: Should we add an OperandValueProperties::OP_Zero property?
3040 Cost += thisT()->getArithmeticInstrCost(
3041 BinaryOperator::Sub, RetTy, CostKind,
3043 return Cost;
3044 }
3045 case Intrinsic::fshl:
3046 case Intrinsic::fshr: {
3047 // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
3048 // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
3049 Type *CondTy = RetTy->getWithNewBitWidth(1);
3051 Cost +=
3052 thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
3053 Cost +=
3054 thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
3055 Cost +=
3056 thisT()->getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
3057 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::LShr, RetTy,
3058 CostKind);
3059 // Non-constant shift amounts requires a modulo. If the typesize is a
3060 // power-2 then this will be converted to an and, otherwise it will use a
3061 // urem.
3062 Cost += thisT()->getArithmeticInstrCost(
3063 isPowerOf2_32(RetTy->getScalarSizeInBits()) ? BinaryOperator::And
3064 : BinaryOperator::URem,
3065 RetTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3066 {TTI::OK_UniformConstantValue, TTI::OP_None});
3067 // Shift-by-zero handling.
3068 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
3070 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
3072 return Cost;
3073 }
3074 case Intrinsic::fptosi_sat:
3075 case Intrinsic::fptoui_sat: {
3076 if (Tys.empty())
3077 break;
3078 Type *FromTy = Tys[0];
3079 bool IsSigned = IID == Intrinsic::fptosi_sat;
3080
3082 IntrinsicCostAttributes Attrs1(Intrinsic::minnum, FromTy,
3083 {FromTy, FromTy});
3084 Cost += thisT()->getIntrinsicInstrCost(Attrs1, CostKind);
3085 IntrinsicCostAttributes Attrs2(Intrinsic::maxnum, FromTy,
3086 {FromTy, FromTy});
3087 Cost += thisT()->getIntrinsicInstrCost(Attrs2, CostKind);
3088 Cost += thisT()->getCastInstrCost(
3089 IsSigned ? Instruction::FPToSI : Instruction::FPToUI, RetTy, FromTy,
3091 if (IsSigned) {
3092 Type *CondTy = RetTy->getWithNewBitWidth(1);
3093 Cost += thisT()->getCmpSelInstrCost(
3094 BinaryOperator::FCmp, FromTy, CondTy, CmpInst::FCMP_UNO, CostKind);
3095 Cost += thisT()->getCmpSelInstrCost(
3096 BinaryOperator::Select, RetTy, CondTy, CmpInst::FCMP_UNO, CostKind);
3097 }
3098 return Cost;
3099 }
3100 case Intrinsic::ucmp:
3101 case Intrinsic::scmp: {
3102 Type *CmpTy = Tys[0];
3103 Type *CondTy = RetTy->getWithNewBitWidth(1);
3105 thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, CmpTy, CondTy,
3107 CostKind) +
3108 thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, CmpTy, CondTy,
3110 CostKind);
3111
3112 EVT VT = TLI->getValueType(DL, CmpTy, true);
3114 // x < y ? -1 : (x > y ? 1 : 0)
3115 Cost += 2 * thisT()->getCmpSelInstrCost(
3116 BinaryOperator::Select, RetTy, CondTy,
3118 } else {
3119 // zext(x > y) - zext(x < y)
3120 Cost +=
3121 2 * thisT()->getCastInstrCost(CastInst::ZExt, RetTy, CondTy,
3123 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy,
3124 CostKind);
3125 }
3126 return Cost;
3127 }
3128 case Intrinsic::maximumnum:
3129 case Intrinsic::minimumnum: {
3130 // On platform that support FMAXNUM_IEEE/FMINNUM_IEEE, we expand
3131 // maximumnum/minimumnum to
3132 // ARG0 = fcanonicalize ARG0, ARG0 // to quiet ARG0
3133 // ARG1 = fcanonicalize ARG1, ARG1 // to quiet ARG1
3134 // RESULT = MAXNUM_IEEE ARG0, ARG1 // or MINNUM_IEEE
3135 // FIXME: In LangRef, we claimed FMAXNUM has the same behaviour of
3136 // FMAXNUM_IEEE, while the backend hasn't migrated the code yet.
3137 // Finally, we will remove FMAXNUM_IEEE and FMINNUM_IEEE.
3138 int IeeeISD =
3139 IID == Intrinsic::maximumnum ? ISD::FMAXNUM_IEEE : ISD::FMINNUM_IEEE;
3140 if (TLI->isOperationLegal(IeeeISD, LT.second)) {
3141 IntrinsicCostAttributes FCanonicalizeAttrs(Intrinsic::canonicalize,
3142 RetTy, Tys[0]);
3143 InstructionCost FCanonicalizeCost =
3144 thisT()->getIntrinsicInstrCost(FCanonicalizeAttrs, CostKind);
3145 return LT.first + FCanonicalizeCost * 2;
3146 }
3147 break;
3148 }
3149 case Intrinsic::clmul: {
3150 // This cost model should match the expansion in
3151 // TargetLowering::expandCLMUL.
3152 unsigned BW = RetTy->getScalarSizeInBits();
3153 InstructionCost AndCost =
3154 thisT()->getArithmeticInstrCost(Instruction::And, RetTy, CostKind);
3155 InstructionCost OrCost =
3156 thisT()->getArithmeticInstrCost(Instruction::Or, RetTy, CostKind);
3157 InstructionCost XorCost =
3158 thisT()->getArithmeticInstrCost(Instruction::Xor, RetTy, CostKind);
3159 InstructionCost MulCost =
3160 thisT()->getArithmeticInstrCost(Instruction::Mul, RetTy, CostKind);
3161
3162 // When the multiplication with holes approach is used, it splits the
3163 // operands into S phases (the smallest stride with ceil(BW/S) <= 2^S) and
3164 // emits S*S MULs, 3*S ANDs, S*(S-1) XORs and S-1 ORs.
3165 //
3166 // * BW <= 8 uses S = 2
3167 // * BW <= 24 uses S = 3
3168 // * BW <= 64 uses S = 4
3169 // * BW <= 160 uses S = 5
3170 // * BW <= 384 uses S = 6
3171 unsigned S = 1;
3172 while (S < 32 && divideCeil(BW, S) > (1u << S))
3173 ++S;
3174
3175 // The naive algorithm usually uses AND+MUL+XOR per bit.
3176 unsigned NaiveCost = 3 * BW;
3177 unsigned HolesCost = S * S + 3 * S + S * (S - 1) + (S - 1);
3178
3179 if (HolesCost < NaiveCost &&
3181 TLI->getValueType(DL, RetTy))) {
3182 return S * S * MulCost + 3 * S * AndCost + S * (S - 1) * XorCost +
3183 (S - 1) * OrCost;
3184 }
3185
3186 InstructionCost PerBitCostMul = AndCost + MulCost + XorCost;
3187 InstructionCost PerBitCostBittest =
3188 AndCost +
3189 thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, RetTy,
3191 thisT()->getCmpSelInstrCost(Instruction::ICmp, RetTy, RetTy,
3193 InstructionCost PerBitCost = std::min(PerBitCostMul, PerBitCostBittest);
3194 return BW * PerBitCost;
3195 }
3196 case Intrinsic::smulh:
3197 case Intrinsic::umulh: {
3198 unsigned BW = RetTy->getScalarSizeInBits();
3199 Type *WideTy = RetTy->getWithNewBitWidth(BW * 2);
3200 bool IsSigned = IID == Intrinsic::smulh;
3201 unsigned ExtOp = IsSigned ? Instruction::SExt : Instruction::ZExt;
3203 Cost +=
3204 2 * thisT()->getCastInstrCost(ExtOp, WideTy, RetTy,
3206 Cost +=
3207 thisT()->getArithmeticInstrCost(Instruction::Mul, WideTy, CostKind);
3208 Cost += thisT()->getArithmeticInstrCost(
3209 Instruction::LShr, WideTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3211 Cost += thisT()->getCastInstrCost(Instruction::Trunc, RetTy, WideTy,
3213 return Cost;
3214 }
3215 default:
3216 break;
3217 }
3218
3219 // Else, assume that we need to scalarize this intrinsic. For math builtins
3220 // this will emit a costly libcall, adding call overhead and spills. Make it
3221 // very expensive.
3222 if (isVectorizedTy(RetTy)) {
3223 ArrayRef<Type *> RetVTys = getContainedTypes(RetTy);
3224
3225 // Scalable vectors cannot be scalarized, so return Invalid.
3226 if (any_of(concat<Type *const>(RetVTys, Tys),
3227 [](Type *Ty) { return isa<ScalableVectorType>(Ty); }))
3229
3230 InstructionCost ScalarizationCost = ScalarizationCostPassed;
3231 if (!SkipScalarizationCost) {
3232 ScalarizationCost = 0;
3233 for (Type *RetVTy : RetVTys) {
3234 ScalarizationCost += getScalarizationOverhead(
3235 cast<VectorType>(RetVTy), /*Insert=*/true,
3236 /*Extract=*/false, CostKind);
3237 }
3238 }
3239
3240 unsigned ScalarCalls = getVectorizedTypeVF(RetTy).getFixedValue();
3241 SmallVector<Type *, 4> ScalarTys;
3242 for (Type *Ty : Tys) {
3243 if (Ty->isVectorTy())
3244 Ty = Ty->getScalarType();
3245 ScalarTys.push_back(Ty);
3246 }
3247 IntrinsicCostAttributes Attrs(IID, toScalarizedTy(RetTy), ScalarTys, FMF);
3248 InstructionCost ScalarCost =
3249 thisT()->getIntrinsicInstrCost(Attrs, CostKind);
3250 for (Type *Ty : Tys) {
3251 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
3252 if (!ICA.skipScalarizationCost())
3253 ScalarizationCost += getScalarizationOverhead(
3254 VTy, /*Insert*/ false, /*Extract*/ true, CostKind);
3255 ScalarCalls = std::max(ScalarCalls,
3256 cast<FixedVectorType>(VTy)->getNumElements());
3257 }
3258 }
3259 return ScalarCalls * ScalarCost + ScalarizationCost;
3260 }
3261
3262 // This is going to be turned into a library call, make it expensive.
3263 return SingleCallCost;
3264 }
3265
3266 /// Get memory intrinsic cost based on arguments.
3269 TTI::TargetCostKind CostKind) const override {
3270 unsigned Id = MICA.getID();
3271 Type *DataTy = MICA.getDataType();
3272 bool VariableMask = MICA.getVariableMask();
3273 Align Alignment = MICA.getAlignment();
3274
3275 switch (Id) {
3276 case Intrinsic::experimental_vp_strided_load:
3277 case Intrinsic::experimental_vp_strided_store: {
3278 unsigned Opcode = Id == Intrinsic::experimental_vp_strided_load
3279 ? Instruction::Load
3280 : Instruction::Store;
3281 // For a target without strided memory operations (or for an illegal
3282 // operation type on one which does), assume we lower to a gather/scatter
3283 // operation. (Which may in turn be scalarized.)
3284 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment,
3285 VariableMask, true, CostKind);
3286 }
3287 case Intrinsic::masked_scatter:
3288 case Intrinsic::masked_gather:
3289 case Intrinsic::vp_scatter:
3290 case Intrinsic::vp_gather: {
3291 unsigned Opcode = (MICA.getID() == Intrinsic::masked_gather ||
3292 MICA.getID() == Intrinsic::vp_gather)
3293 ? Instruction::Load
3294 : Instruction::Store;
3295
3296 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment,
3297 VariableMask, true, CostKind);
3298 }
3299 case Intrinsic::vp_load:
3300 case Intrinsic::vp_store:
3302 case Intrinsic::masked_load:
3303 case Intrinsic::masked_store: {
3304 unsigned Opcode =
3305 Id == Intrinsic::masked_load ? Instruction::Load : Instruction::Store;
3306 // TODO: Pass on AddressSpace when we have test coverage.
3307 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment, true, false,
3308 CostKind);
3309 }
3310 case Intrinsic::masked_compressstore:
3311 case Intrinsic::masked_expandload: {
3312 unsigned Opcode = MICA.getID() == Intrinsic::masked_expandload
3313 ? Instruction::Load
3314 : Instruction::Store;
3315 // Treat expand load/compress store as gather/scatter operation.
3316 // TODO: implement more precise cost estimation for these intrinsics.
3317 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment,
3318 VariableMask,
3319 /*IsGatherScatter*/ true, CostKind);
3320 }
3321 case Intrinsic::vp_load_ff:
3323 case Intrinsic::speculative_load:
3324 // Speculative loads are lowered to regular loads of the full type.
3325 return thisT()->getMemoryOpCost(Instruction::Load, DataTy, Alignment,
3326 MICA.getAddressSpace(), CostKind);
3327 default:
3328 llvm_unreachable("unexpected intrinsic");
3329 }
3330 }
3331
3332 /// Compute a cost of the given call instruction.
3333 ///
3334 /// Compute the cost of calling function F with return type RetTy and
3335 /// argument types Tys. F might be nullptr, in this case the cost of an
3336 /// arbitrary call with the specified signature will be returned.
3337 /// This is used, for instance, when we estimate call of a vector
3338 /// counterpart of the given function.
3339 /// \param F Called function, might be nullptr.
3340 /// \param RetTy Return value types.
3341 /// \param Tys Argument types.
3342 /// \returns The cost of Call instruction.
3345 TTI::TargetCostKind CostKind) const override {
3346 return 10;
3347 }
3348
3349 unsigned getNumberOfParts(Type *Tp) const override {
3350 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Tp);
3351 if (!LT.first.isValid())
3352 return 0;
3353 // Try to find actual number of parts for non-power-of-2 elements as
3354 // ceil(num-of-elements/num-of-subtype-elements).
3355 if (auto *FTp = dyn_cast<FixedVectorType>(Tp);
3356 FTp && LT.second.isFixedLengthVector() &&
3357 !has_single_bit(FTp->getNumElements())) {
3358 if (auto *SubTp = dyn_cast_if_present<FixedVectorType>(
3359 EVT(LT.second).getTypeForEVT(Tp->getContext()));
3360 SubTp && SubTp->getElementType() == FTp->getElementType())
3361 return divideCeil(FTp->getNumElements(), SubTp->getNumElements());
3362 }
3363 return LT.first.getValue();
3364 }
3365
3368 TTI::TargetCostKind) const override {
3369 return 0;
3370 }
3371
3372 /// Try to calculate arithmetic and shuffle op costs for reduction intrinsics.
3373 /// We're assuming that reduction operation are performing the following way:
3374 ///
3375 /// %val1 = shufflevector<n x t> %val, <n x t> %undef,
3376 /// <n x i32> <i32 n/2, i32 n/2 + 1, ..., i32 n, i32 undef, ..., i32 undef>
3377 /// \----------------v-------------/ \----------v------------/
3378 /// n/2 elements n/2 elements
3379 /// %red1 = op <n x t> %val, <n x t> val1
3380 /// After this operation we have a vector %red1 where only the first n/2
3381 /// elements are meaningful, the second n/2 elements are undefined and can be
3382 /// dropped. All other operations are actually working with the vector of
3383 /// length n/2, not n, though the real vector length is still n.
3384 /// %val2 = shufflevector<n x t> %red1, <n x t> %undef,
3385 /// <n x i32> <i32 n/4, i32 n/4 + 1, ..., i32 n/2, i32 undef, ..., i32 undef>
3386 /// \----------------v-------------/ \----------v------------/
3387 /// n/4 elements 3*n/4 elements
3388 /// %red2 = op <n x t> %red1, <n x t> val2 - working with the vector of
3389 /// length n/2, the resulting vector has length n/4 etc.
3390 ///
3391 /// The cost model should take into account that the actual length of the
3392 /// vector is reduced on each iteration.
3395 // Targets must implement a default value for the scalable case, since
3396 // we don't know how many lanes the vector has.
3399
3400 Type *ScalarTy = Ty->getElementType();
3401 unsigned NumVecElts = cast<FixedVectorType>(Ty)->getNumElements();
3402 if ((Opcode == Instruction::Or || Opcode == Instruction::And) &&
3403 ScalarTy == IntegerType::getInt1Ty(Ty->getContext()) &&
3404 NumVecElts >= 2) {
3405 // Or reduction for i1 is represented as:
3406 // %val = bitcast <ReduxWidth x i1> to iReduxWidth
3407 // %res = cmp ne iReduxWidth %val, 0
3408 // And reduction for i1 is represented as:
3409 // %val = bitcast <ReduxWidth x i1> to iReduxWidth
3410 // %res = cmp eq iReduxWidth %val, 11111
3411 Type *ValTy = IntegerType::get(Ty->getContext(), NumVecElts);
3412 return thisT()->getCastInstrCost(Instruction::BitCast, ValTy, Ty,
3414 thisT()->getCmpSelInstrCost(Instruction::ICmp, ValTy,
3417 }
3418 unsigned NumReduxLevels = Log2_32(NumVecElts);
3419 InstructionCost ArithCost = 0;
3420 InstructionCost ShuffleCost = 0;
3421 std::pair<InstructionCost, MVT> LT = thisT()->getTypeLegalizationCost(Ty);
3422 unsigned LongVectorCount = 0;
3423 unsigned MVTLen =
3424 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
3425 while (NumVecElts > MVTLen) {
3426 NumVecElts /= 2;
3427 VectorType *SubTy = FixedVectorType::get(ScalarTy, NumVecElts);
3428 ShuffleCost += thisT()->getShuffleCost(
3429 TTI::SK_ExtractSubvector, SubTy, Ty, CostKind, {}, NumVecElts, SubTy);
3430 ArithCost += thisT()->getArithmeticInstrCost(Opcode, SubTy, CostKind);
3431 Ty = SubTy;
3432 ++LongVectorCount;
3433 }
3434
3435 NumReduxLevels -= LongVectorCount;
3436
3437 // The minimal length of the vector is limited by the real length of vector
3438 // operations performed on the current platform. That's why several final
3439 // reduction operations are performed on the vectors with the same
3440 // architecture-dependent length.
3441
3442 // By default reductions need one shuffle per reduction level.
3443 ShuffleCost +=
3444 NumReduxLevels * thisT()->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
3445 Ty, CostKind, {}, 0, Ty);
3446 ArithCost +=
3447 NumReduxLevels * thisT()->getArithmeticInstrCost(Opcode, Ty, CostKind);
3448 return ShuffleCost + ArithCost +
3449 thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty,
3450 CostKind, 0, nullptr, nullptr);
3451 }
3452
3453 /// Try to calculate the cost of performing strict (in-order) reductions,
3454 /// which involves doing a sequence of floating point additions in lane
3455 /// order, starting with an initial value. For example, consider a scalar
3456 /// initial value 'InitVal' of type float and a vector of type <4 x float>:
3457 ///
3458 /// Vector = <float %v0, float %v1, float %v2, float %v3>
3459 ///
3460 /// %add1 = %InitVal + %v0
3461 /// %add2 = %add1 + %v1
3462 /// %add3 = %add2 + %v2
3463 /// %add4 = %add3 + %v3
3464 ///
3465 /// As a simple estimate we can say the cost of such a reduction is 4 times
3466 /// the cost of a scalar FP addition. We can only estimate the costs for
3467 /// fixed-width vectors here because for scalable vectors we do not know the
3468 /// runtime number of operations.
3471 // Targets must implement a default value for the scalable case, since
3472 // we don't know how many lanes the vector has.
3475
3476 auto *VTy = cast<FixedVectorType>(Ty);
3478 VTy, /*Insert=*/false, /*Extract=*/true, CostKind);
3479 InstructionCost ArithCost = thisT()->getArithmeticInstrCost(
3480 Opcode, VTy->getElementType(), CostKind);
3481 ArithCost *= VTy->getNumElements();
3482
3483 return ExtractCost + ArithCost;
3484 }
3485
3488 std::optional<FastMathFlags> FMF,
3489 TTI::TargetCostKind CostKind) const override {
3490 assert(Ty && "Unknown reduction vector type");
3492 return getOrderedReductionCost(Opcode, Ty, CostKind);
3493 return getTreeReductionCost(Opcode, Ty, CostKind);
3494 }
3495
3496 /// Try to calculate op costs for min/max reduction operations.
3497 /// \param CondTy Conditional type for the Select instruction.
3500 TTI::TargetCostKind CostKind) const override {
3501 // Targets must implement a default value for the scalable case, since
3502 // we don't know how many lanes the vector has.
3505
3506 Type *ScalarTy = Ty->getElementType();
3507 unsigned NumVecElts = cast<FixedVectorType>(Ty)->getNumElements();
3508 unsigned NumReduxLevels = Log2_32(NumVecElts);
3509 InstructionCost MinMaxCost = 0;
3510 InstructionCost ShuffleCost = 0;
3511 std::pair<InstructionCost, MVT> LT = thisT()->getTypeLegalizationCost(Ty);
3512 unsigned LongVectorCount = 0;
3513 unsigned MVTLen =
3514 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
3515 while (NumVecElts > MVTLen) {
3516 NumVecElts /= 2;
3517 auto *SubTy = FixedVectorType::get(ScalarTy, NumVecElts);
3518
3519 ShuffleCost += thisT()->getShuffleCost(
3520 TTI::SK_ExtractSubvector, SubTy, Ty, CostKind, {}, NumVecElts, SubTy);
3521
3522 IntrinsicCostAttributes Attrs(IID, SubTy, {SubTy, SubTy}, FMF);
3523 MinMaxCost += getIntrinsicInstrCost(Attrs, CostKind);
3524 Ty = SubTy;
3525 ++LongVectorCount;
3526 }
3527
3528 NumReduxLevels -= LongVectorCount;
3529
3530 // The minimal length of the vector is limited by the real length of vector
3531 // operations performed on the current platform. That's why several final
3532 // reduction opertions are perfomed on the vectors with the same
3533 // architecture-dependent length.
3534 ShuffleCost +=
3535 NumReduxLevels * thisT()->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
3536 Ty, CostKind, {}, 0, Ty);
3537 IntrinsicCostAttributes Attrs(IID, Ty, {Ty, Ty}, FMF);
3538 MinMaxCost += NumReduxLevels * getIntrinsicInstrCost(Attrs, CostKind);
3539 // The last min/max should be in vector registers and we counted it above.
3540 // So just need a single extractelement.
3541 return ShuffleCost + MinMaxCost +
3542 thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty,
3543 CostKind, 0, nullptr, nullptr);
3544 }
3545
3547 getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy,
3548 VectorType *Ty, std::optional<FastMathFlags> FMF,
3549 TTI::TargetCostKind CostKind) const override {
3550 if (auto *FTy = dyn_cast<FixedVectorType>(Ty);
3551 FTy && IsUnsigned && Opcode == Instruction::Add &&
3552 FTy->getElementType() == IntegerType::getInt1Ty(Ty->getContext())) {
3553 // Represent vector_reduce_add(ZExt(<n x i1>)) as
3554 // ZExtOrTrunc(ctpop(bitcast <n x i1> to in)).
3555 auto *IntTy =
3556 IntegerType::get(ResTy->getContext(), FTy->getNumElements());
3557 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy},
3558 FMF ? *FMF : FastMathFlags());
3559 return thisT()->getCastInstrCost(Instruction::BitCast, IntTy, FTy,
3561 thisT()->getIntrinsicInstrCost(ICA, CostKind);
3562 }
3563 // Without any native support, this is equivalent to the cost of
3564 // vecreduce.opcode(ext(Ty A)).
3565 VectorType *ExtTy = VectorType::get(ResTy, Ty);
3566 InstructionCost RedCost =
3567 thisT()->getArithmeticReductionCost(Opcode, ExtTy, FMF, CostKind);
3568 InstructionCost ExtCost = thisT()->getCastInstrCost(
3569 IsUnsigned ? Instruction::ZExt : Instruction::SExt, ExtTy, Ty,
3571
3572 return RedCost + ExtCost;
3573 }
3574
3576 getMulAccReductionCost(bool IsUnsigned, unsigned RedOpcode, Type *ResTy,
3577 VectorType *Ty,
3578 TTI::TargetCostKind CostKind) const override {
3579 // Without any native support, this is equivalent to the cost of
3580 // vecreduce.add(mul(ext(Ty A), ext(Ty B))) or
3581 // vecreduce.add(mul(A, B)).
3582 assert((RedOpcode == Instruction::Add || RedOpcode == Instruction::Sub) &&
3583 "The reduction opcode is expected to be Add or Sub.");
3584 VectorType *ExtTy = VectorType::get(ResTy, Ty);
3585 InstructionCost RedCost = thisT()->getArithmeticReductionCost(
3586 RedOpcode, ExtTy, std::nullopt, CostKind);
3587 InstructionCost ExtCost = thisT()->getCastInstrCost(
3588 IsUnsigned ? Instruction::ZExt : Instruction::SExt, ExtTy, Ty,
3590
3591 InstructionCost MulCost =
3592 thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
3593
3594 return RedCost + MulCost + 2 * ExtCost;
3595 }
3596
3598 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
3600 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
3602 std::optional<FastMathFlags> FMF) const override {
3603 unsigned EltSizeAcc = AccumType->getScalarSizeInBits();
3604 unsigned EltSizeInA = InputTypeA->getScalarSizeInBits();
3605 unsigned Ratio = EltSizeAcc / EltSizeInA;
3606 if (VF.getKnownMinValue() <= Ratio || VF.getKnownMinValue() % Ratio != 0 ||
3607 EltSizeAcc % EltSizeInA != 0 || (BinOp && InputTypeA != InputTypeB))
3609
3610 Type *InputVectorType = VectorType::get(InputTypeA, VF);
3611 Type *ExtInputVectorType = VectorType::get(AccumType, VF);
3612 Type *AccumVectorType =
3613 VectorType::get(AccumType, VF.divideCoefficientBy(Ratio));
3614
3615 InstructionCost ExtendCostA = 0;
3617 ExtendCostA = getCastInstrCost(
3619 ExtInputVectorType, InputVectorType, TTI::CastContextHint::None,
3620 CostKind);
3621
3622 // TODO: add cost of extracting subvectors from the source vector that
3623 // is to be partially reduced.
3624 InstructionCost ReductionOpCost =
3625 Ratio * getArithmeticInstrCost(Opcode, AccumVectorType, CostKind);
3626
3627 if (!BinOp)
3628 return ExtendCostA + ReductionOpCost;
3629
3630 InstructionCost ExtendCostB = 0;
3632 ExtendCostB = getCastInstrCost(
3634 ExtInputVectorType, InputVectorType, TTI::CastContextHint::None,
3635 CostKind);
3636 return ExtendCostA + ExtendCostB + ReductionOpCost +
3637 getArithmeticInstrCost(*BinOp, ExtInputVectorType, CostKind);
3638 }
3639
3641
3642 /// @}
3643};
3644
3645/// Concrete BasicTTIImpl that can be used if no further customization
3646/// is needed.
3647class BasicTTIImpl : public BasicTTIImplBase<BasicTTIImpl> {
3648 using BaseT = BasicTTIImplBase<BasicTTIImpl>;
3649
3650 friend class BasicTTIImplBase<BasicTTIImpl>;
3651
3652 const TargetSubtargetInfo *ST;
3653 const TargetLoweringBase *TLI;
3654
3655 const TargetSubtargetInfo *getST() const { return ST; }
3656 const TargetLoweringBase *getTLI() const { return TLI; }
3657
3658public:
3659 LLVM_ABI explicit BasicTTIImpl(const TargetMachine *TM, const Function &F);
3660};
3661
3662} // end namespace llvm
3663
3664#endif // LLVM_CODEGEN_BASICTTIIMPL_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
uint64_t Imm
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:211
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:321
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:306
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:317
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:76
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:31
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:41
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:40
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:344
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
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
Definition Type.cpp:61
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...
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
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:201
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS*X will result in a value whose quantity matches our own.
Definition TypeSize.h:274
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:217
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
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:253
#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:805
@ 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:765
@ 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:796
@ 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:822
@ 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 - Same as FMINNUM/FMAXNUM, except that a signaling NaN operand deterministi...
@ FMINNUM
FMINNUM/FMAXNUM - Same semantics as the llvm.minnum/maxnum intrinsics.
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:359
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:745
@ 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:831
@ FMINIMUM
FMINIMUM/FMAXIMUM - Same semantics as the llvm.minimum/maximum intrinsics.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
Definition ISDOpcodes.h:753
@ 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:971
@ 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 - Same semantics as the llvm.minimumnum/maximumnum intrinsics.
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 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).