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::mask_beforefirst:
2191 case Intrinsic::experimental_vector_match:
2192 case Intrinsic::experimental_vector_histogram_add:
2193 case Intrinsic::experimental_vector_histogram_uadd_sat:
2194 case Intrinsic::experimental_vector_histogram_umax:
2195 case Intrinsic::experimental_vector_histogram_umin:
2196 case Intrinsic::masked_udiv:
2197 case Intrinsic::masked_sdiv:
2198 case Intrinsic::masked_urem:
2199 case Intrinsic::masked_srem:
2200 return thisT()->getTypeBasedIntrinsicInstrCost(ICA, CostKind);
2201 case Intrinsic::modf:
2202 case Intrinsic::sincos:
2203 case Intrinsic::sincospi: {
2204 std::optional<unsigned> CallRetElementIndex;
2205 // The first element of the modf result is returned by value in the
2206 // libcall.
2207 if (ICA.getID() == Intrinsic::modf)
2208 CallRetElementIndex = 0;
2209
2210 if (auto Cost = getMultipleResultIntrinsicVectorLibCallCost(
2211 ICA, CostKind, CallRetElementIndex))
2212 return *Cost;
2213 // Otherwise, fallback to default scalarization cost.
2214 break;
2215 }
2216 case Intrinsic::loop_dependence_war_mask:
2217 case Intrinsic::loop_dependence_raw_mask: {
2218 // Compute the cost of the expanded version of these intrinsics:
2219 //
2220 // The possible expansions are...
2221 //
2222 // loop_dependence_war_mask:
2223 // diff = (addrB - addrA) / eltSize
2224 // cmp = icmp sle diff, 0
2225 // upper_bound = select cmp, -1, diff
2226 // mask = get_active_lane_mask 0, upper_bound
2227 //
2228 // loop_dependence_raw_mask:
2229 // diff = (abs(addrB - addrA)) / eltSize
2230 // cmp = icmp eq diff, 0
2231 // upper_bound = select cmp, -1, diff
2232 // mask = get_active_lane_mask 0, upper_bound
2233 //
2234 Type *AddrTy = ICA.getArgTypes()[0];
2235 bool IsReadAfterWrite = IID == Intrinsic::loop_dependence_raw_mask;
2236
2238 thisT()->getArithmeticInstrCost(Instruction::Sub, AddrTy, CostKind);
2239 if (IsReadAfterWrite) {
2240 IntrinsicCostAttributes AbsAttrs(Intrinsic::abs, AddrTy, {AddrTy}, {});
2241 Cost += thisT()->getIntrinsicInstrCost(AbsAttrs, CostKind);
2242 }
2243
2244 TTI::OperandValueInfo EltSizeOpInfo =
2245 TTI::getOperandInfo(ICA.getArgs()[2]);
2246 Cost += thisT()->getArithmeticInstrCost(Instruction::SDiv, AddrTy,
2247 CostKind, {}, EltSizeOpInfo);
2248
2249 Type *CondTy = IntegerType::getInt1Ty(RetTy->getContext());
2250 CmpInst::Predicate Pred =
2251 IsReadAfterWrite ? CmpInst::ICMP_EQ : CmpInst::ICMP_SLE;
2252 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, CondTy, AddrTy,
2253 Pred, CostKind);
2254 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, AddrTy,
2255 CondTy, Pred, CostKind);
2256
2257 IntrinsicCostAttributes Attrs(Intrinsic::get_active_lane_mask, RetTy,
2258 {AddrTy, AddrTy}, FMF);
2259 Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
2260 return Cost;
2261 }
2262 }
2263
2264 // Assume that we need to scalarize this intrinsic.)
2265 // Compute the scalarization overhead based on Args for a vector
2266 // intrinsic.
2267 InstructionCost ScalarizationCost = InstructionCost::getInvalid();
2268 if (RetVF.isVector() && !RetVF.isScalable()) {
2269 ScalarizationCost = 0;
2270 if (!RetTy->isVoidTy()) {
2271 for (Type *VectorTy : getContainedTypes(RetTy)) {
2272 ScalarizationCost += getScalarizationOverhead(
2273 cast<VectorType>(VectorTy),
2274 /*Insert=*/true, /*Extract=*/false, CostKind);
2275 }
2276 }
2277 ScalarizationCost += getOperandsScalarizationOverhead(
2278 filterConstantAndDuplicatedOperands(Args, ICA.getArgTypes()),
2279 CostKind);
2280 }
2281
2282 IntrinsicCostAttributes Attrs(IID, RetTy, ICA.getArgTypes(), FMF, I,
2283 ScalarizationCost);
2284 return thisT()->getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
2285 }
2286
2287 /// Get intrinsic cost based on argument types.
2288 /// If ScalarizationCostPassed is std::numeric_limits<unsigned>::max(), the
2289 /// cost of scalarizing the arguments and the return value will be computed
2290 /// based on types.
2294 Intrinsic::ID IID = ICA.getID();
2295 Type *RetTy = ICA.getReturnType();
2296 const SmallVectorImpl<Type *> &Tys = ICA.getArgTypes();
2297 FastMathFlags FMF = ICA.getFlags();
2298 InstructionCost ScalarizationCostPassed = ICA.getScalarizationCost();
2299 bool SkipScalarizationCost = ICA.skipScalarizationCost();
2300
2301 VectorType *VecOpTy = nullptr;
2302 if (!Tys.empty()) {
2303 // The vector reduction operand is operand 0 except for fadd/fmul.
2304 // Their operand 0 is a scalar start value, so the vector op is operand 1.
2305 unsigned VecTyIndex = 0;
2306 if (IID == Intrinsic::vector_reduce_fadd ||
2307 IID == Intrinsic::vector_reduce_fmul)
2308 VecTyIndex = 1;
2309 assert(Tys.size() > VecTyIndex && "Unexpected IntrinsicCostAttributes");
2310 VecOpTy = dyn_cast<VectorType>(Tys[VecTyIndex]);
2311 }
2312
2313 // Library call cost - other than size, make it expensive.
2314 unsigned SingleCallCost = CostKind == TTI::TCK_CodeSize ? 1 : 10;
2315 unsigned ISD = 0;
2316 switch (IID) {
2317 default: {
2318 // Scalable vectors cannot be scalarized, so return Invalid.
2319 if (isa<ScalableVectorType>(RetTy) || any_of(Tys, [](const Type *Ty) {
2320 return isa<ScalableVectorType>(Ty);
2321 }))
2323
2324 // Assume that we need to scalarize this intrinsic.
2325 InstructionCost ScalarizationCost =
2326 SkipScalarizationCost ? ScalarizationCostPassed : 0;
2327 unsigned ScalarCalls = 1;
2328 Type *ScalarRetTy = RetTy;
2329 if (auto *RetVTy = dyn_cast<VectorType>(RetTy)) {
2330 if (!SkipScalarizationCost)
2331 ScalarizationCost = getScalarizationOverhead(
2332 RetVTy, /*Insert*/ true, /*Extract*/ false, CostKind);
2333 ScalarCalls = std::max(ScalarCalls,
2334 cast<FixedVectorType>(RetVTy)->getNumElements());
2335 ScalarRetTy = RetTy->getScalarType();
2336 }
2337 SmallVector<Type *, 4> ScalarTys;
2338 for (Type *Ty : Tys) {
2339 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
2340 if (!SkipScalarizationCost)
2341 ScalarizationCost += getScalarizationOverhead(
2342 VTy, /*Insert*/ false, /*Extract*/ true, CostKind);
2343 ScalarCalls = std::max(ScalarCalls,
2344 cast<FixedVectorType>(VTy)->getNumElements());
2345 Ty = Ty->getScalarType();
2346 }
2347 ScalarTys.push_back(Ty);
2348 }
2349 if (ScalarCalls == 1)
2350 return 1; // Return cost of a scalar intrinsic. Assume it to be cheap.
2351
2352 IntrinsicCostAttributes ScalarAttrs(IID, ScalarRetTy, ScalarTys, FMF);
2353 InstructionCost ScalarCost =
2354 thisT()->getIntrinsicInstrCost(ScalarAttrs, CostKind);
2355
2356 return ScalarCalls * ScalarCost + ScalarizationCost;
2357 }
2358 // Look for intrinsics that can be lowered directly or turned into a scalar
2359 // intrinsic call.
2360 case Intrinsic::sqrt:
2361 ISD = ISD::FSQRT;
2362 break;
2363 case Intrinsic::sin:
2364 ISD = ISD::FSIN;
2365 break;
2366 case Intrinsic::cos:
2367 ISD = ISD::FCOS;
2368 break;
2369 case Intrinsic::sincos:
2370 ISD = ISD::FSINCOS;
2371 break;
2372 case Intrinsic::sincospi:
2374 break;
2375 case Intrinsic::modf:
2376 ISD = ISD::FMODF;
2377 break;
2378 case Intrinsic::tan:
2379 ISD = ISD::FTAN;
2380 break;
2381 case Intrinsic::asin:
2382 ISD = ISD::FASIN;
2383 break;
2384 case Intrinsic::acos:
2385 ISD = ISD::FACOS;
2386 break;
2387 case Intrinsic::atan:
2388 ISD = ISD::FATAN;
2389 break;
2390 case Intrinsic::atan2:
2391 ISD = ISD::FATAN2;
2392 break;
2393 case Intrinsic::sinh:
2394 ISD = ISD::FSINH;
2395 break;
2396 case Intrinsic::cosh:
2397 ISD = ISD::FCOSH;
2398 break;
2399 case Intrinsic::tanh:
2400 ISD = ISD::FTANH;
2401 break;
2402 case Intrinsic::exp:
2403 ISD = ISD::FEXP;
2404 break;
2405 case Intrinsic::exp2:
2406 ISD = ISD::FEXP2;
2407 break;
2408 case Intrinsic::exp10:
2409 ISD = ISD::FEXP10;
2410 break;
2411 case Intrinsic::log:
2412 ISD = ISD::FLOG;
2413 break;
2414 case Intrinsic::log10:
2415 ISD = ISD::FLOG10;
2416 break;
2417 case Intrinsic::log2:
2418 ISD = ISD::FLOG2;
2419 break;
2420 case Intrinsic::ldexp:
2421 ISD = ISD::FLDEXP;
2422 break;
2423 case Intrinsic::fabs:
2424 ISD = ISD::FABS;
2425 break;
2426 case Intrinsic::canonicalize:
2428 break;
2429 case Intrinsic::minnum:
2430 ISD = ISD::FMINNUM;
2431 break;
2432 case Intrinsic::maxnum:
2433 ISD = ISD::FMAXNUM;
2434 break;
2435 case Intrinsic::minimum:
2437 break;
2438 case Intrinsic::maximum:
2440 break;
2441 case Intrinsic::minimumnum:
2443 break;
2444 case Intrinsic::maximumnum:
2446 break;
2447 case Intrinsic::copysign:
2449 break;
2450 case Intrinsic::floor:
2451 ISD = ISD::FFLOOR;
2452 break;
2453 case Intrinsic::ceil:
2454 ISD = ISD::FCEIL;
2455 break;
2456 case Intrinsic::trunc:
2457 ISD = ISD::FTRUNC;
2458 break;
2459 case Intrinsic::nearbyint:
2461 break;
2462 case Intrinsic::rint:
2463 ISD = ISD::FRINT;
2464 break;
2465 case Intrinsic::lrint:
2466 ISD = ISD::LRINT;
2467 break;
2468 case Intrinsic::llrint:
2469 ISD = ISD::LLRINT;
2470 break;
2471 case Intrinsic::round:
2472 ISD = ISD::FROUND;
2473 break;
2474 case Intrinsic::roundeven:
2476 break;
2477 case Intrinsic::lround:
2478 ISD = ISD::LROUND;
2479 break;
2480 case Intrinsic::llround:
2481 ISD = ISD::LLROUND;
2482 break;
2483 case Intrinsic::pow:
2484 ISD = ISD::FPOW;
2485 break;
2486 case Intrinsic::fma:
2487 ISD = ISD::FMA;
2488 break;
2489 case Intrinsic::fmuladd:
2490 ISD = ISD::FMA;
2491 break;
2492 case Intrinsic::experimental_constrained_fmuladd:
2494 break;
2495 // FIXME: We should return 0 whenever getIntrinsicCost == TCC_Free.
2496 case Intrinsic::lifetime_start:
2497 case Intrinsic::lifetime_end:
2498 case Intrinsic::sideeffect:
2499 case Intrinsic::pseudoprobe:
2500 case Intrinsic::arithmetic_fence:
2501 return 0;
2502 case Intrinsic::masked_store: {
2503 Type *Ty = Tys[0];
2504 Align TyAlign = thisT()->DL.getABITypeAlign(Ty);
2505 return thisT()->getMemIntrinsicInstrCost(
2506 MemIntrinsicCostAttributes(IID, Ty, TyAlign, 0), CostKind);
2507 }
2508 case Intrinsic::masked_load: {
2509 Type *Ty = RetTy;
2510 Align TyAlign = thisT()->DL.getABITypeAlign(Ty);
2511 return thisT()->getMemIntrinsicInstrCost(
2512 MemIntrinsicCostAttributes(IID, Ty, TyAlign, 0), CostKind);
2513 }
2514 case Intrinsic::speculative_load: {
2515 const IntrinsicInst *I = ICA.getInst();
2516 Align Alignment = I ? I->getParamAlign(0).valueOrOne() : Align(1);
2517 unsigned AS = Tys[0]->getPointerAddressSpace();
2518 return thisT()->getMemIntrinsicInstrCost(
2519 MemIntrinsicCostAttributes(IID, RetTy, Alignment, AS), CostKind);
2520 }
2521 case Intrinsic::experimental_vp_strided_store: {
2522 auto *Ty = cast<VectorType>(ICA.getArgTypes()[0]);
2523 Align Alignment = thisT()->DL.getABITypeAlign(Ty->getElementType());
2524 return thisT()->getMemIntrinsicInstrCost(
2525 MemIntrinsicCostAttributes(IID, Ty, /*Ptr=*/nullptr,
2526 /*VariableMask=*/true, Alignment,
2527 ICA.getInst()),
2528 CostKind);
2529 }
2530 case Intrinsic::experimental_vp_strided_load: {
2531 auto *Ty = cast<VectorType>(ICA.getReturnType());
2532 Align Alignment = thisT()->DL.getABITypeAlign(Ty->getElementType());
2533 return thisT()->getMemIntrinsicInstrCost(
2534 MemIntrinsicCostAttributes(IID, Ty, /*Ptr=*/nullptr,
2535 /*VariableMask=*/true, Alignment,
2536 ICA.getInst()),
2537 CostKind);
2538 }
2539 case Intrinsic::vector_reduce_add:
2540 case Intrinsic::vector_reduce_mul:
2541 case Intrinsic::vector_reduce_and:
2542 case Intrinsic::vector_reduce_or:
2543 case Intrinsic::vector_reduce_xor:
2544 return thisT()->getArithmeticReductionCost(
2545 getArithmeticReductionInstruction(IID), VecOpTy, std::nullopt,
2546 CostKind);
2547 case Intrinsic::vector_reduce_fadd:
2548 case Intrinsic::vector_reduce_fmul:
2549 return thisT()->getArithmeticReductionCost(
2550 getArithmeticReductionInstruction(IID), VecOpTy, FMF, CostKind);
2551 case Intrinsic::vector_reduce_smax:
2552 case Intrinsic::vector_reduce_smin:
2553 case Intrinsic::vector_reduce_umax:
2554 case Intrinsic::vector_reduce_umin:
2555 case Intrinsic::vector_reduce_fmax:
2556 case Intrinsic::vector_reduce_fmin:
2557 case Intrinsic::vector_reduce_fmaximum:
2558 case Intrinsic::vector_reduce_fminimum:
2559 case Intrinsic::vector_reduce_fmaximumnum:
2560 case Intrinsic::vector_reduce_fminimumnum:
2561 return thisT()->getMinMaxReductionCost(getMinMaxReductionIntrinsicOp(IID),
2562 VecOpTy, ICA.getFlags(), CostKind);
2563 case Intrinsic::vector_partial_reduce_add:
2564 case Intrinsic::vector_partial_reduce_fadd: {
2565 VectorType *AccTy = cast<VectorType>(ICA.getArgTypes()[0]);
2566 VectorType *InTy = cast<VectorType>(ICA.getArgTypes()[1]);
2567 // TODO: See if something better can be done for scalable-to-fixed
2568 // partial reductions.
2569 if (AccTy->isScalableTy() != InTy->isScalableTy())
2571
2572 unsigned Opcode = 0;
2573 switch (IID) {
2574 default:
2575 llvm_unreachable("Unexpected partial reduction");
2576 break;
2577 case Intrinsic::vector_partial_reduce_add:
2578 Opcode = Instruction::Add;
2579 break;
2580 case Intrinsic::vector_partial_reduce_fadd:
2581 Opcode = Instruction::FAdd;
2582 break;
2583 }
2584
2585 // TODO: Factor in subvector extract costs if the types are different
2586 // sizes. We get some ridiculously high costs for vector_extract
2587 // at present, so fix that first.
2588 // For a type-only query, model as (possibly multiple) basic instructions
2589 // for the accumulator type.
2591 AccTy->getElementCount()) *
2592 thisT()->getArithmeticInstrCost(Opcode, AccTy, CostKind);
2593 }
2594 case Intrinsic::experimental_vector_match: {
2595 auto *SearchTy = cast<VectorType>(ICA.getArgTypes()[0]);
2596 auto *NeedleTy = cast<FixedVectorType>(ICA.getArgTypes()[1]);
2597 unsigned SearchSize = NeedleTy->getNumElements();
2598
2599 // Approximate the cost based on the expansion code in
2600 // TargetLowering::expandVectorMatch.
2602 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, NeedleTy,
2603 CostKind, 1, nullptr, nullptr);
2604 Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, SearchTy,
2605 CostKind, 0, nullptr, nullptr);
2606 Cost += thisT()->getShuffleCost(TTI::SK_Broadcast, SearchTy, SearchTy,
2607 CostKind, {}, 0, nullptr);
2608 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SearchTy, RetTy,
2610 Cost +=
2611 thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
2612 Cost *= SearchSize;
2613 Cost +=
2614 thisT()->getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
2615 return Cost;
2616 }
2617 case Intrinsic::vector_reverse:
2618 return thisT()->getShuffleCost(TTI::SK_Reverse, cast<VectorType>(RetTy),
2619 cast<VectorType>(ICA.getArgTypes()[0]),
2620 CostKind, {}, 0, cast<VectorType>(RetTy));
2621 case Intrinsic::experimental_vector_histogram_add:
2622 case Intrinsic::experimental_vector_histogram_uadd_sat:
2623 case Intrinsic::experimental_vector_histogram_umax:
2624 case Intrinsic::experimental_vector_histogram_umin: {
2626 Type *EltTy = ICA.getArgTypes()[1];
2627
2628 // Targets with scalable vectors must handle this on their own.
2629 if (!PtrsTy)
2631
2632 Align Alignment = thisT()->DL.getABITypeAlign(EltTy);
2634 Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, PtrsTy,
2635 CostKind, 1, nullptr, nullptr);
2636 Cost += thisT()->getMemoryOpCost(Instruction::Load, EltTy, Alignment, 0,
2637 CostKind);
2638 switch (IID) {
2639 default:
2640 llvm_unreachable("Unhandled histogram update operation.");
2641 case Intrinsic::experimental_vector_histogram_add:
2642 Cost +=
2643 thisT()->getArithmeticInstrCost(Instruction::Add, EltTy, CostKind);
2644 break;
2645 case Intrinsic::experimental_vector_histogram_uadd_sat: {
2646 IntrinsicCostAttributes UAddSat(Intrinsic::uadd_sat, EltTy, {EltTy});
2647 Cost += thisT()->getIntrinsicInstrCost(UAddSat, CostKind);
2648 break;
2649 }
2650 case Intrinsic::experimental_vector_histogram_umax: {
2651 IntrinsicCostAttributes UMax(Intrinsic::umax, EltTy, {EltTy});
2652 Cost += thisT()->getIntrinsicInstrCost(UMax, CostKind);
2653 break;
2654 }
2655 case Intrinsic::experimental_vector_histogram_umin: {
2656 IntrinsicCostAttributes UMin(Intrinsic::umin, EltTy, {EltTy});
2657 Cost += thisT()->getIntrinsicInstrCost(UMin, CostKind);
2658 break;
2659 }
2660 }
2661 Cost += thisT()->getMemoryOpCost(Instruction::Store, EltTy, Alignment, 0,
2662 CostKind);
2663 Cost *= PtrsTy->getNumElements();
2664 return Cost;
2665 }
2666 case Intrinsic::get_active_lane_mask: {
2667 Type *ArgTy = ICA.getArgTypes()[0];
2668 EVT ResVT = getTLI()->getValueType(DL, RetTy, true);
2669 EVT ArgVT = getTLI()->getValueType(DL, ArgTy, true);
2670
2671 // If we're not expanding the intrinsic then we assume this is cheap
2672 // to implement.
2673 if (!getTLI()->shouldExpandGetActiveLaneMask(ResVT, ArgVT))
2674 return getTypeLegalizationCost(RetTy).first;
2675
2676 // Create the expanded types that will be used to calculate the uadd_sat
2677 // operation.
2678 Type *ExpRetTy =
2679 VectorType::get(ArgTy, cast<VectorType>(RetTy)->getElementCount());
2680 IntrinsicCostAttributes Attrs(Intrinsic::uadd_sat, ExpRetTy, {}, FMF);
2682 thisT()->getTypeBasedIntrinsicInstrCost(Attrs, CostKind);
2683 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, ExpRetTy, RetTy,
2685 return Cost;
2686 }
2687 case Intrinsic::mask_beforefirst: {
2689 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
2690 if (!getTLI()->isOperationExpand(ISD, LT.second))
2691 break;
2692
2693 // Scalar types are lowered as a not.
2694 if (!LT.second.isVector())
2695 return LT.first *
2696 thisT()->getArithmeticInstrCost(
2697 Instruction::Xor, RetTy->getScalarType(), CostKind);
2698
2699 // Expansion via (get_active_lane_mask 0, (cttz.elts mask))
2700 RetTy = VectorType::get(RetTy->getScalarType(),
2701 LT.second.getVectorElementCount());
2702 Type *IdxTy =
2704 getTLI()->getVectorIdxTy(DL).getFixedSizeInBits());
2705 IntrinsicCostAttributes CttzEltsAttrs(Intrinsic::experimental_cttz_elts,
2706 IdxTy, RetTy, FMF);
2708 thisT()->getIntrinsicInstrCost(CttzEltsAttrs, CostKind);
2709
2710 IntrinsicCostAttributes ActiveLaneMaskAttrs(
2711 Intrinsic::get_active_lane_mask, RetTy, {IdxTy, IdxTy}, FMF);
2712 Cost += thisT()->getIntrinsicInstrCost(ActiveLaneMaskAttrs, CostKind);
2713 return Cost * LT.first;
2714 }
2715 case Intrinsic::experimental_memset_pattern:
2716 // This cost is set to match the cost of the memset_pattern16 libcall.
2717 // It should likely be re-evaluated after migration to this intrinsic
2718 // is complete.
2719 return TTI::TCC_Basic * 4;
2720 case Intrinsic::abs:
2721 ISD = ISD::ABS;
2722 break;
2723 case Intrinsic::fshl:
2724 ISD = ISD::FSHL;
2725 break;
2726 case Intrinsic::fshr:
2727 ISD = ISD::FSHR;
2728 break;
2729 case Intrinsic::smax:
2730 ISD = ISD::SMAX;
2731 break;
2732 case Intrinsic::smin:
2733 ISD = ISD::SMIN;
2734 break;
2735 case Intrinsic::umax:
2736 ISD = ISD::UMAX;
2737 break;
2738 case Intrinsic::umin:
2739 ISD = ISD::UMIN;
2740 break;
2741 case Intrinsic::sadd_sat:
2742 ISD = ISD::SADDSAT;
2743 break;
2744 case Intrinsic::ssub_sat:
2745 ISD = ISD::SSUBSAT;
2746 break;
2747 case Intrinsic::uadd_sat:
2748 ISD = ISD::UADDSAT;
2749 break;
2750 case Intrinsic::usub_sat:
2751 ISD = ISD::USUBSAT;
2752 break;
2753 case Intrinsic::smul_fix:
2754 ISD = ISD::SMULFIX;
2755 break;
2756 case Intrinsic::umul_fix:
2757 ISD = ISD::UMULFIX;
2758 break;
2759 case Intrinsic::sadd_with_overflow:
2760 ISD = ISD::SADDO;
2761 break;
2762 case Intrinsic::ssub_with_overflow:
2763 ISD = ISD::SSUBO;
2764 break;
2765 case Intrinsic::uadd_with_overflow:
2766 ISD = ISD::UADDO;
2767 break;
2768 case Intrinsic::usub_with_overflow:
2769 ISD = ISD::USUBO;
2770 break;
2771 case Intrinsic::smul_with_overflow:
2772 ISD = ISD::SMULO;
2773 break;
2774 case Intrinsic::umul_with_overflow:
2775 ISD = ISD::UMULO;
2776 break;
2777 case Intrinsic::fptosi_sat:
2778 case Intrinsic::fptoui_sat: {
2779 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(Tys[0]);
2780 std::pair<InstructionCost, MVT> RetLT = getTypeLegalizationCost(RetTy);
2781
2782 // For cast instructions, types are different between source and
2783 // destination. Also need to check if the source type can be legalize.
2784 if (!SrcLT.first.isValid() || !RetLT.first.isValid())
2786 ISD = IID == Intrinsic::fptosi_sat ? ISD::FP_TO_SINT_SAT
2788 break;
2789 }
2790 case Intrinsic::ctpop:
2791 ISD = ISD::CTPOP;
2792 // In case of legalization use TCC_Expensive. This is cheaper than a
2793 // library call but still not a cheap instruction.
2794 SingleCallCost = TargetTransformInfo::TCC_Expensive;
2795 break;
2796 case Intrinsic::ctlz:
2797 ISD = ISD::CTLZ;
2798 break;
2799 case Intrinsic::cttz:
2800 ISD = ISD::CTTZ;
2801 break;
2802 case Intrinsic::bswap:
2803 ISD = ISD::BSWAP;
2804 break;
2805 case Intrinsic::bitreverse:
2807 break;
2808 case Intrinsic::ucmp:
2809 ISD = ISD::UCMP;
2810 break;
2811 case Intrinsic::scmp:
2812 ISD = ISD::SCMP;
2813 break;
2814 case Intrinsic::clmul:
2815 ISD = ISD::CLMUL;
2816 break;
2817 case Intrinsic::smulh:
2818 ISD = ISD::MULHS;
2819 break;
2820 case Intrinsic::umulh:
2821 ISD = ISD::MULHU;
2822 break;
2823 case Intrinsic::masked_udiv:
2824 case Intrinsic::masked_sdiv:
2825 case Intrinsic::masked_urem:
2826 case Intrinsic::masked_srem: {
2827 unsigned UnmaskedOpc;
2828 switch (IID) {
2829 case Intrinsic::masked_udiv:
2831 UnmaskedOpc = Instruction::UDiv;
2832 break;
2833 case Intrinsic::masked_sdiv:
2835 UnmaskedOpc = Instruction::SDiv;
2836 break;
2837 case Intrinsic::masked_urem:
2839 UnmaskedOpc = Instruction::URem;
2840 break;
2841 case Intrinsic::masked_srem:
2843 UnmaskedOpc = Instruction::SRem;
2844 break;
2845 default:
2846 llvm_unreachable("Unexpected intrinsic ID");
2847 }
2849 thisT()->getArithmeticInstrCost(UnmaskedOpc, RetTy, CostKind);
2850
2851 // Expansion generates a (select %mask, %rhs, 1) for the divisor.
2852 MVT LT = getTypeLegalizationCost(RetTy).second;
2853 if (!getTLI()->isOperationLegalOrCustom(ISD, LT)) {
2854 Type *CondTy = cast<VectorType>(RetTy)->getWithNewType(
2856 Cost += thisT()->getCmpSelInstrCost(
2857 BinaryOperator::Select, RetTy, CondTy, CmpInst::BAD_ICMP_PREDICATE,
2859 }
2860
2861 return Cost;
2862 }
2863 }
2864
2865 auto *ST = dyn_cast<StructType>(RetTy);
2866 Type *LegalizeTy = ST ? ST->getContainedType(0) : RetTy;
2867 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(LegalizeTy);
2868
2869 const TargetLoweringBase *TLI = getTLI();
2870
2871 if (TLI->isOperationLegalOrPromote(ISD, LT.second)) {
2872 if (IID == Intrinsic::fabs && LT.second.isFloatingPoint() &&
2873 TLI->isFAbsFree(LT.second)) {
2874 return 0;
2875 }
2876
2877 // The operation is legal. Assume it costs 1.
2878 // If the type is split to multiple registers, assume that there is some
2879 // overhead to this.
2880 // TODO: Once we have extract/insert subvector cost we need to use them.
2881 if (LT.first > 1)
2882 return (LT.first * 2);
2883 else
2884 return (LT.first * 1);
2885 } else if (TLI->isOperationCustom(ISD, LT.second)) {
2886 // If the operation is custom lowered then assume
2887 // that the code is twice as expensive.
2888 return (LT.first * 2);
2889 }
2890
2891 switch (IID) {
2892 case Intrinsic::fmuladd: {
2893 // If we can't lower fmuladd into an FMA estimate the cost as a floating
2894 // point mul followed by an add.
2895
2896 return thisT()->getArithmeticInstrCost(BinaryOperator::FMul, RetTy,
2897 CostKind) +
2898 thisT()->getArithmeticInstrCost(BinaryOperator::FAdd, RetTy,
2899 CostKind);
2900 }
2901 case Intrinsic::experimental_constrained_fmuladd: {
2902 IntrinsicCostAttributes FMulAttrs(
2903 Intrinsic::experimental_constrained_fmul, RetTy, Tys);
2904 IntrinsicCostAttributes FAddAttrs(
2905 Intrinsic::experimental_constrained_fadd, RetTy, Tys);
2906 return thisT()->getIntrinsicInstrCost(FMulAttrs, CostKind) +
2907 thisT()->getIntrinsicInstrCost(FAddAttrs, CostKind);
2908 }
2909 case Intrinsic::smin:
2910 case Intrinsic::smax:
2911 case Intrinsic::umin:
2912 case Intrinsic::umax: {
2913 // minmax(X,Y) = select(icmp(X,Y),X,Y)
2914 Type *CondTy = RetTy->getWithNewBitWidth(1);
2915 bool IsUnsigned = IID == Intrinsic::umax || IID == Intrinsic::umin;
2916 CmpInst::Predicate Pred =
2917 IsUnsigned ? CmpInst::ICMP_UGT : CmpInst::ICMP_SGT;
2919 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
2920 Pred, CostKind);
2921 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
2922 Pred, CostKind);
2923 return Cost;
2924 }
2925 case Intrinsic::sadd_with_overflow:
2926 case Intrinsic::ssub_with_overflow: {
2927 Type *SumTy = RetTy->getContainedType(0);
2928 Type *OverflowTy = RetTy->getContainedType(1);
2929 unsigned Opcode = IID == Intrinsic::sadd_with_overflow
2930 ? BinaryOperator::Add
2931 : BinaryOperator::Sub;
2932
2933 // Add:
2934 // Overflow -> (Result < LHS) ^ (RHS < 0)
2935 // Sub:
2936 // Overflow -> (Result < LHS) ^ (RHS > 0)
2938 Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
2939 Cost +=
2940 2 * thisT()->getCmpSelInstrCost(Instruction::ICmp, SumTy, OverflowTy,
2942 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::Xor, OverflowTy,
2943 CostKind);
2944 return Cost;
2945 }
2946 case Intrinsic::uadd_with_overflow:
2947 case Intrinsic::usub_with_overflow: {
2948 Type *SumTy = RetTy->getContainedType(0);
2949 Type *OverflowTy = RetTy->getContainedType(1);
2950 unsigned Opcode = IID == Intrinsic::uadd_with_overflow
2951 ? BinaryOperator::Add
2952 : BinaryOperator::Sub;
2953 CmpInst::Predicate Pred = IID == Intrinsic::uadd_with_overflow
2956
2958 Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
2959 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy,
2960 OverflowTy, Pred, CostKind);
2961 return Cost;
2962 }
2963 case Intrinsic::smul_with_overflow:
2964 case Intrinsic::umul_with_overflow: {
2965 Type *MulTy = RetTy->getContainedType(0);
2966 Type *OverflowTy = RetTy->getContainedType(1);
2967 unsigned ExtSize = MulTy->getScalarSizeInBits() * 2;
2968 Type *ExtTy = MulTy->getWithNewBitWidth(ExtSize);
2969 bool IsSigned = IID == Intrinsic::smul_with_overflow;
2970
2971 unsigned ExtOp = IsSigned ? Instruction::SExt : Instruction::ZExt;
2973
2975 Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, MulTy, CCH, CostKind);
2976 Cost +=
2977 thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
2978 Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, MulTy, ExtTy,
2979 CCH, CostKind);
2980 Cost += thisT()->getArithmeticInstrCost(
2981 Instruction::LShr, ExtTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
2983
2984 if (IsSigned)
2985 Cost += thisT()->getArithmeticInstrCost(
2986 Instruction::AShr, MulTy, CostKind,
2989
2990 Cost += thisT()->getCmpSelInstrCost(
2991 BinaryOperator::ICmp, MulTy, OverflowTy, CmpInst::ICMP_NE, CostKind);
2992 return Cost;
2993 }
2994 case Intrinsic::sadd_sat:
2995 case Intrinsic::ssub_sat: {
2996 // Assume a default expansion.
2997 Type *CondTy = RetTy->getWithNewBitWidth(1);
2998
2999 Type *OpTy = StructType::create({RetTy, CondTy});
3000 Intrinsic::ID OverflowOp = IID == Intrinsic::sadd_sat
3001 ? Intrinsic::sadd_with_overflow
3002 : Intrinsic::ssub_with_overflow;
3004
3005 // SatMax -> Overflow && SumDiff < 0
3006 // SatMin -> Overflow && SumDiff >= 0
3008 IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
3009 nullptr, ScalarizationCostPassed);
3010 Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
3011 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
3012 Pred, CostKind);
3013 Cost += 2 * thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
3014 CondTy, Pred, CostKind);
3015 return Cost;
3016 }
3017 case Intrinsic::uadd_sat:
3018 case Intrinsic::usub_sat: {
3019 Type *CondTy = RetTy->getWithNewBitWidth(1);
3020
3021 Type *OpTy = StructType::create({RetTy, CondTy});
3022 Intrinsic::ID OverflowOp = IID == Intrinsic::uadd_sat
3023 ? Intrinsic::uadd_with_overflow
3024 : Intrinsic::usub_with_overflow;
3025
3027 IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
3028 nullptr, ScalarizationCostPassed);
3029 Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
3030 Cost +=
3031 thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
3033 return Cost;
3034 }
3035 case Intrinsic::smul_fix:
3036 case Intrinsic::umul_fix: {
3037 unsigned ExtSize = RetTy->getScalarSizeInBits() * 2;
3038 Type *ExtTy = RetTy->getWithNewBitWidth(ExtSize);
3039
3040 unsigned ExtOp =
3041 IID == Intrinsic::smul_fix ? Instruction::SExt : Instruction::ZExt;
3043
3045 Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, RetTy, CCH, CostKind);
3046 Cost +=
3047 thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
3048 Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, RetTy, ExtTy,
3049 CCH, CostKind);
3050 Cost += thisT()->getArithmeticInstrCost(
3051 Instruction::LShr, RetTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3053 Cost += thisT()->getArithmeticInstrCost(
3054 Instruction::Shl, RetTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3056 Cost += thisT()->getArithmeticInstrCost(Instruction::Or, RetTy, CostKind);
3057 return Cost;
3058 }
3059 case Intrinsic::abs: {
3060 // abs(X) = select(icmp(X,0),X,sub(0,X))
3061 Type *CondTy = RetTy->getWithNewBitWidth(1);
3064 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
3065 Pred, CostKind);
3066 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
3067 Pred, CostKind);
3068 // TODO: Should we add an OperandValueProperties::OP_Zero property?
3069 Cost += thisT()->getArithmeticInstrCost(
3070 BinaryOperator::Sub, RetTy, CostKind,
3072 return Cost;
3073 }
3074 case Intrinsic::fshl:
3075 case Intrinsic::fshr: {
3076 // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
3077 // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
3078 Type *CondTy = RetTy->getWithNewBitWidth(1);
3080 Cost +=
3081 thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
3082 Cost +=
3083 thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
3084 Cost +=
3085 thisT()->getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
3086 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::LShr, RetTy,
3087 CostKind);
3088 // Non-constant shift amounts requires a modulo. If the typesize is a
3089 // power-2 then this will be converted to an and, otherwise it will use a
3090 // urem.
3091 Cost += thisT()->getArithmeticInstrCost(
3092 isPowerOf2_32(RetTy->getScalarSizeInBits()) ? BinaryOperator::And
3093 : BinaryOperator::URem,
3094 RetTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3095 {TTI::OK_UniformConstantValue, TTI::OP_None});
3096 // Shift-by-zero handling.
3097 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
3099 Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
3101 return Cost;
3102 }
3103 case Intrinsic::fptosi_sat:
3104 case Intrinsic::fptoui_sat: {
3105 if (Tys.empty())
3106 break;
3107 Type *FromTy = Tys[0];
3108 bool IsSigned = IID == Intrinsic::fptosi_sat;
3109
3111 IntrinsicCostAttributes Attrs1(Intrinsic::minnum, FromTy,
3112 {FromTy, FromTy});
3113 Cost += thisT()->getIntrinsicInstrCost(Attrs1, CostKind);
3114 IntrinsicCostAttributes Attrs2(Intrinsic::maxnum, FromTy,
3115 {FromTy, FromTy});
3116 Cost += thisT()->getIntrinsicInstrCost(Attrs2, CostKind);
3117 Cost += thisT()->getCastInstrCost(
3118 IsSigned ? Instruction::FPToSI : Instruction::FPToUI, RetTy, FromTy,
3120 if (IsSigned) {
3121 Type *CondTy = RetTy->getWithNewBitWidth(1);
3122 Cost += thisT()->getCmpSelInstrCost(
3123 BinaryOperator::FCmp, FromTy, CondTy, CmpInst::FCMP_UNO, CostKind);
3124 Cost += thisT()->getCmpSelInstrCost(
3125 BinaryOperator::Select, RetTy, CondTy, CmpInst::FCMP_UNO, CostKind);
3126 }
3127 return Cost;
3128 }
3129 case Intrinsic::ucmp:
3130 case Intrinsic::scmp: {
3131 Type *CmpTy = Tys[0];
3132 Type *CondTy = RetTy->getWithNewBitWidth(1);
3134 thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, CmpTy, CondTy,
3136 CostKind) +
3137 thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, CmpTy, CondTy,
3139 CostKind);
3140
3141 EVT VT = TLI->getValueType(DL, CmpTy, true);
3143 // x < y ? -1 : (x > y ? 1 : 0)
3144 Cost += 2 * thisT()->getCmpSelInstrCost(
3145 BinaryOperator::Select, RetTy, CondTy,
3147 } else {
3148 // zext(x > y) - zext(x < y)
3149 Cost +=
3150 2 * thisT()->getCastInstrCost(CastInst::ZExt, RetTy, CondTy,
3152 Cost += thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy,
3153 CostKind);
3154 }
3155 return Cost;
3156 }
3157 case Intrinsic::maximumnum:
3158 case Intrinsic::minimumnum: {
3159 // On platform that support FMAXNUM_IEEE/FMINNUM_IEEE, we expand
3160 // maximumnum/minimumnum to
3161 // ARG0 = fcanonicalize ARG0, ARG0 // to quiet ARG0
3162 // ARG1 = fcanonicalize ARG1, ARG1 // to quiet ARG1
3163 // RESULT = MAXNUM_IEEE ARG0, ARG1 // or MINNUM_IEEE
3164 // FIXME: In LangRef, we claimed FMAXNUM has the same behaviour of
3165 // FMAXNUM_IEEE, while the backend hasn't migrated the code yet.
3166 // Finally, we will remove FMAXNUM_IEEE and FMINNUM_IEEE.
3167 int IeeeISD =
3168 IID == Intrinsic::maximumnum ? ISD::FMAXNUM_IEEE : ISD::FMINNUM_IEEE;
3169 if (TLI->isOperationLegal(IeeeISD, LT.second)) {
3170 IntrinsicCostAttributes FCanonicalizeAttrs(Intrinsic::canonicalize,
3171 RetTy, Tys[0]);
3172 InstructionCost FCanonicalizeCost =
3173 thisT()->getIntrinsicInstrCost(FCanonicalizeAttrs, CostKind);
3174 return LT.first + FCanonicalizeCost * 2;
3175 }
3176 break;
3177 }
3178 case Intrinsic::clmul: {
3179 // This cost model should match the expansion in
3180 // TargetLowering::expandCLMUL.
3181 unsigned BW = RetTy->getScalarSizeInBits();
3182 InstructionCost AndCost =
3183 thisT()->getArithmeticInstrCost(Instruction::And, RetTy, CostKind);
3184 InstructionCost OrCost =
3185 thisT()->getArithmeticInstrCost(Instruction::Or, RetTy, CostKind);
3186 InstructionCost XorCost =
3187 thisT()->getArithmeticInstrCost(Instruction::Xor, RetTy, CostKind);
3188 InstructionCost MulCost =
3189 thisT()->getArithmeticInstrCost(Instruction::Mul, RetTy, CostKind);
3190
3191 // When the multiplication with holes approach is used, it splits the
3192 // operands into S phases (the smallest stride with ceil(BW/S) <= 2^S) and
3193 // emits S*S MULs, 3*S ANDs, S*(S-1) XORs and S-1 ORs.
3194 //
3195 // * BW <= 8 uses S = 2
3196 // * BW <= 24 uses S = 3
3197 // * BW <= 64 uses S = 4
3198 // * BW <= 160 uses S = 5
3199 // * BW <= 384 uses S = 6
3200 unsigned S = 1;
3201 while (S < 32 && divideCeil(BW, S) > (1u << S))
3202 ++S;
3203
3204 // The naive algorithm usually uses AND+MUL+XOR per bit.
3205 unsigned NaiveCost = 3 * BW;
3206 unsigned HolesCost = S * S + 3 * S + S * (S - 1) + (S - 1);
3207
3208 if (HolesCost < NaiveCost &&
3210 TLI->getValueType(DL, RetTy))) {
3211 return S * S * MulCost + 3 * S * AndCost + S * (S - 1) * XorCost +
3212 (S - 1) * OrCost;
3213 }
3214
3215 InstructionCost PerBitCostMul = AndCost + MulCost + XorCost;
3216 InstructionCost PerBitCostBittest =
3217 AndCost +
3218 thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, RetTy,
3220 thisT()->getCmpSelInstrCost(Instruction::ICmp, RetTy, RetTy,
3222 InstructionCost PerBitCost = std::min(PerBitCostMul, PerBitCostBittest);
3223 return BW * PerBitCost;
3224 }
3225 case Intrinsic::smulh:
3226 case Intrinsic::umulh: {
3227 unsigned BW = RetTy->getScalarSizeInBits();
3228 Type *WideTy = RetTy->getWithNewBitWidth(BW * 2);
3229 bool IsSigned = IID == Intrinsic::smulh;
3230 unsigned ExtOp = IsSigned ? Instruction::SExt : Instruction::ZExt;
3232 Cost +=
3233 2 * thisT()->getCastInstrCost(ExtOp, WideTy, RetTy,
3235 Cost +=
3236 thisT()->getArithmeticInstrCost(Instruction::Mul, WideTy, CostKind);
3237 Cost += thisT()->getArithmeticInstrCost(
3238 Instruction::LShr, WideTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
3240 Cost += thisT()->getCastInstrCost(Instruction::Trunc, RetTy, WideTy,
3242 return Cost;
3243 }
3244 default:
3245 break;
3246 }
3247
3248 // Else, assume that we need to scalarize this intrinsic. For math builtins
3249 // this will emit a costly libcall, adding call overhead and spills. Make it
3250 // very expensive.
3251 if (isVectorizedTy(RetTy)) {
3252 ArrayRef<Type *> RetVTys = getContainedTypes(RetTy);
3253
3254 // Scalable vectors cannot be scalarized, so return Invalid.
3255 if (any_of(concat<Type *const>(RetVTys, Tys),
3256 [](Type *Ty) { return isa<ScalableVectorType>(Ty); }))
3258
3259 InstructionCost ScalarizationCost = ScalarizationCostPassed;
3260 if (!SkipScalarizationCost) {
3261 ScalarizationCost = 0;
3262 for (Type *RetVTy : RetVTys) {
3263 ScalarizationCost += getScalarizationOverhead(
3264 cast<VectorType>(RetVTy), /*Insert=*/true,
3265 /*Extract=*/false, CostKind);
3266 }
3267 }
3268
3269 unsigned ScalarCalls = getVectorizedTypeVF(RetTy).getFixedValue();
3270 SmallVector<Type *, 4> ScalarTys;
3271 for (Type *Ty : Tys) {
3272 if (Ty->isVectorTy())
3273 Ty = Ty->getScalarType();
3274 ScalarTys.push_back(Ty);
3275 }
3276 IntrinsicCostAttributes Attrs(IID, toScalarizedTy(RetTy), ScalarTys, FMF);
3277 InstructionCost ScalarCost =
3278 thisT()->getIntrinsicInstrCost(Attrs, CostKind);
3279 for (Type *Ty : Tys) {
3280 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
3281 if (!ICA.skipScalarizationCost())
3282 ScalarizationCost += getScalarizationOverhead(
3283 VTy, /*Insert*/ false, /*Extract*/ true, CostKind);
3284 ScalarCalls = std::max(ScalarCalls,
3285 cast<FixedVectorType>(VTy)->getNumElements());
3286 }
3287 }
3288 return ScalarCalls * ScalarCost + ScalarizationCost;
3289 }
3290
3291 // This is going to be turned into a library call, make it expensive.
3292 return SingleCallCost;
3293 }
3294
3295 /// Get memory intrinsic cost based on arguments.
3298 TTI::TargetCostKind CostKind) const override {
3299 unsigned Id = MICA.getID();
3300 Type *DataTy = MICA.getDataType();
3301 bool VariableMask = MICA.getVariableMask();
3302 Align Alignment = MICA.getAlignment();
3303
3304 switch (Id) {
3305 case Intrinsic::experimental_vp_strided_load:
3306 case Intrinsic::experimental_vp_strided_store: {
3307 unsigned Opcode = Id == Intrinsic::experimental_vp_strided_load
3308 ? Instruction::Load
3309 : Instruction::Store;
3310 // For a target without strided memory operations (or for an illegal
3311 // operation type on one which does), assume we lower to a gather/scatter
3312 // operation. (Which may in turn be scalarized.)
3313 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment,
3314 VariableMask, true, CostKind);
3315 }
3316 case Intrinsic::masked_scatter:
3317 case Intrinsic::masked_gather:
3318 case Intrinsic::vp_scatter:
3319 case Intrinsic::vp_gather: {
3320 unsigned Opcode = (MICA.getID() == Intrinsic::masked_gather ||
3321 MICA.getID() == Intrinsic::vp_gather)
3322 ? Instruction::Load
3323 : Instruction::Store;
3324
3325 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment,
3326 VariableMask, true, CostKind);
3327 }
3328 case Intrinsic::vp_load:
3329 case Intrinsic::vp_store:
3331 case Intrinsic::masked_load:
3332 case Intrinsic::masked_store: {
3333 unsigned Opcode =
3334 Id == Intrinsic::masked_load ? Instruction::Load : Instruction::Store;
3335 // TODO: Pass on AddressSpace when we have test coverage.
3336 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment, true, false,
3337 CostKind);
3338 }
3339 case Intrinsic::masked_compressstore:
3340 case Intrinsic::masked_expandload: {
3341 unsigned Opcode = MICA.getID() == Intrinsic::masked_expandload
3342 ? Instruction::Load
3343 : Instruction::Store;
3344 // Treat expand load/compress store as gather/scatter operation.
3345 // TODO: implement more precise cost estimation for these intrinsics.
3346 return getCommonMaskedMemoryOpCost(Opcode, DataTy, Alignment,
3347 VariableMask,
3348 /*IsGatherScatter*/ true, CostKind);
3349 }
3350 case Intrinsic::vp_load_ff:
3352 case Intrinsic::speculative_load:
3353 // Speculative loads are lowered to regular loads of the full type.
3354 return thisT()->getMemoryOpCost(Instruction::Load, DataTy, Alignment,
3355 MICA.getAddressSpace(), CostKind);
3356 default:
3357 llvm_unreachable("unexpected intrinsic");
3358 }
3359 }
3360
3361 /// Compute a cost of the given call instruction.
3362 ///
3363 /// Compute the cost of calling function F with return type RetTy and
3364 /// argument types Tys. F might be nullptr, in this case the cost of an
3365 /// arbitrary call with the specified signature will be returned.
3366 /// This is used, for instance, when we estimate call of a vector
3367 /// counterpart of the given function.
3368 /// \param F Called function, might be nullptr.
3369 /// \param RetTy Return value types.
3370 /// \param Tys Argument types.
3371 /// \returns The cost of Call instruction.
3374 TTI::TargetCostKind CostKind) const override {
3375 return 10;
3376 }
3377
3378 unsigned getNumberOfParts(Type *Tp) const override {
3379 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Tp);
3380 if (!LT.first.isValid())
3381 return 0;
3382 // Try to find actual number of parts for non-power-of-2 elements as
3383 // ceil(num-of-elements/num-of-subtype-elements).
3384 if (auto *FTp = dyn_cast<FixedVectorType>(Tp);
3385 FTp && LT.second.isFixedLengthVector() &&
3386 !has_single_bit(FTp->getNumElements())) {
3387 if (auto *SubTp = dyn_cast_if_present<FixedVectorType>(
3388 EVT(LT.second).getTypeForEVT(Tp->getContext()));
3389 SubTp && SubTp->getElementType() == FTp->getElementType())
3390 return divideCeil(FTp->getNumElements(), SubTp->getNumElements());
3391 }
3392 return LT.first.getValue();
3393 }
3394
3397 TTI::TargetCostKind) const override {
3398 return 0;
3399 }
3400
3401 /// Try to calculate arithmetic and shuffle op costs for reduction intrinsics.
3402 /// We're assuming that reduction operation are performing the following way:
3403 ///
3404 /// %val1 = shufflevector<n x t> %val, <n x t> %undef,
3405 /// <n x i32> <i32 n/2, i32 n/2 + 1, ..., i32 n, i32 undef, ..., i32 undef>
3406 /// \----------------v-------------/ \----------v------------/
3407 /// n/2 elements n/2 elements
3408 /// %red1 = op <n x t> %val, <n x t> val1
3409 /// After this operation we have a vector %red1 where only the first n/2
3410 /// elements are meaningful, the second n/2 elements are undefined and can be
3411 /// dropped. All other operations are actually working with the vector of
3412 /// length n/2, not n, though the real vector length is still n.
3413 /// %val2 = shufflevector<n x t> %red1, <n x t> %undef,
3414 /// <n x i32> <i32 n/4, i32 n/4 + 1, ..., i32 n/2, i32 undef, ..., i32 undef>
3415 /// \----------------v-------------/ \----------v------------/
3416 /// n/4 elements 3*n/4 elements
3417 /// %red2 = op <n x t> %red1, <n x t> val2 - working with the vector of
3418 /// length n/2, the resulting vector has length n/4 etc.
3419 ///
3420 /// The cost model should take into account that the actual length of the
3421 /// vector is reduced on each iteration.
3424 // Targets must implement a default value for the scalable case, since
3425 // we don't know how many lanes the vector has.
3428
3429 Type *ScalarTy = Ty->getElementType();
3430 unsigned NumVecElts = cast<FixedVectorType>(Ty)->getNumElements();
3431 if ((Opcode == Instruction::Or || Opcode == Instruction::And) &&
3432 ScalarTy == IntegerType::getInt1Ty(Ty->getContext()) &&
3433 NumVecElts >= 2) {
3434 // Or reduction for i1 is represented as:
3435 // %val = bitcast <ReduxWidth x i1> to iReduxWidth
3436 // %res = cmp ne iReduxWidth %val, 0
3437 // And reduction for i1 is represented as:
3438 // %val = bitcast <ReduxWidth x i1> to iReduxWidth
3439 // %res = cmp eq iReduxWidth %val, 11111
3440 Type *ValTy = IntegerType::get(Ty->getContext(), NumVecElts);
3441 return thisT()->getCastInstrCost(Instruction::BitCast, ValTy, Ty,
3443 thisT()->getCmpSelInstrCost(Instruction::ICmp, ValTy,
3446 }
3447 unsigned NumReduxLevels = Log2_32(NumVecElts);
3448 InstructionCost ArithCost = 0;
3449 InstructionCost ShuffleCost = 0;
3450 std::pair<InstructionCost, MVT> LT = thisT()->getTypeLegalizationCost(Ty);
3451 unsigned LongVectorCount = 0;
3452 unsigned MVTLen =
3453 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
3454 while (NumVecElts > MVTLen) {
3455 NumVecElts /= 2;
3456 VectorType *SubTy = FixedVectorType::get(ScalarTy, NumVecElts);
3457 ShuffleCost += thisT()->getShuffleCost(
3458 TTI::SK_ExtractSubvector, SubTy, Ty, CostKind, {}, NumVecElts, SubTy);
3459 ArithCost += thisT()->getArithmeticInstrCost(Opcode, SubTy, CostKind);
3460 Ty = SubTy;
3461 ++LongVectorCount;
3462 }
3463
3464 NumReduxLevels -= LongVectorCount;
3465
3466 // The minimal length of the vector is limited by the real length of vector
3467 // operations performed on the current platform. That's why several final
3468 // reduction operations are performed on the vectors with the same
3469 // architecture-dependent length.
3470
3471 // By default reductions need one shuffle per reduction level.
3472 ShuffleCost +=
3473 NumReduxLevels * thisT()->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
3474 Ty, CostKind, {}, 0, Ty);
3475 ArithCost +=
3476 NumReduxLevels * thisT()->getArithmeticInstrCost(Opcode, Ty, CostKind);
3477 return ShuffleCost + ArithCost +
3478 thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty,
3479 CostKind, 0, nullptr, nullptr);
3480 }
3481
3482 /// Try to calculate the cost of performing strict (in-order) reductions,
3483 /// which involves doing a sequence of floating point additions in lane
3484 /// order, starting with an initial value. For example, consider a scalar
3485 /// initial value 'InitVal' of type float and a vector of type <4 x float>:
3486 ///
3487 /// Vector = <float %v0, float %v1, float %v2, float %v3>
3488 ///
3489 /// %add1 = %InitVal + %v0
3490 /// %add2 = %add1 + %v1
3491 /// %add3 = %add2 + %v2
3492 /// %add4 = %add3 + %v3
3493 ///
3494 /// As a simple estimate we can say the cost of such a reduction is 4 times
3495 /// the cost of a scalar FP addition. We can only estimate the costs for
3496 /// fixed-width vectors here because for scalable vectors we do not know the
3497 /// runtime number of operations.
3500 // Targets must implement a default value for the scalable case, since
3501 // we don't know how many lanes the vector has.
3504
3505 auto *VTy = cast<FixedVectorType>(Ty);
3507 VTy, /*Insert=*/false, /*Extract=*/true, CostKind);
3508 InstructionCost ArithCost = thisT()->getArithmeticInstrCost(
3509 Opcode, VTy->getElementType(), CostKind);
3510 ArithCost *= VTy->getNumElements();
3511
3512 return ExtractCost + ArithCost;
3513 }
3514
3517 std::optional<FastMathFlags> FMF,
3518 TTI::TargetCostKind CostKind) const override {
3519 assert(Ty && "Unknown reduction vector type");
3521 return getOrderedReductionCost(Opcode, Ty, CostKind);
3522 return getTreeReductionCost(Opcode, Ty, CostKind);
3523 }
3524
3525 /// Try to calculate op costs for min/max reduction operations.
3526 /// \param CondTy Conditional type for the Select instruction.
3529 TTI::TargetCostKind CostKind) const override {
3530 // Targets must implement a default value for the scalable case, since
3531 // we don't know how many lanes the vector has.
3534
3535 Type *ScalarTy = Ty->getElementType();
3536 unsigned NumVecElts = cast<FixedVectorType>(Ty)->getNumElements();
3537 unsigned NumReduxLevels = Log2_32(NumVecElts);
3538 InstructionCost MinMaxCost = 0;
3539 InstructionCost ShuffleCost = 0;
3540 std::pair<InstructionCost, MVT> LT = thisT()->getTypeLegalizationCost(Ty);
3541 unsigned LongVectorCount = 0;
3542 unsigned MVTLen =
3543 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
3544 while (NumVecElts > MVTLen) {
3545 NumVecElts /= 2;
3546 auto *SubTy = FixedVectorType::get(ScalarTy, NumVecElts);
3547
3548 ShuffleCost += thisT()->getShuffleCost(
3549 TTI::SK_ExtractSubvector, SubTy, Ty, CostKind, {}, NumVecElts, SubTy);
3550
3551 IntrinsicCostAttributes Attrs(IID, SubTy, {SubTy, SubTy}, FMF);
3552 MinMaxCost += getIntrinsicInstrCost(Attrs, CostKind);
3553 Ty = SubTy;
3554 ++LongVectorCount;
3555 }
3556
3557 NumReduxLevels -= LongVectorCount;
3558
3559 // The minimal length of the vector is limited by the real length of vector
3560 // operations performed on the current platform. That's why several final
3561 // reduction opertions are perfomed on the vectors with the same
3562 // architecture-dependent length.
3563 ShuffleCost +=
3564 NumReduxLevels * thisT()->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
3565 Ty, CostKind, {}, 0, Ty);
3566 IntrinsicCostAttributes Attrs(IID, Ty, {Ty, Ty}, FMF);
3567 MinMaxCost += NumReduxLevels * getIntrinsicInstrCost(Attrs, CostKind);
3568 // The last min/max should be in vector registers and we counted it above.
3569 // So just need a single extractelement.
3570 return ShuffleCost + MinMaxCost +
3571 thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty,
3572 CostKind, 0, nullptr, nullptr);
3573 }
3574
3576 getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy,
3577 VectorType *Ty, std::optional<FastMathFlags> FMF,
3578 TTI::TargetCostKind CostKind) const override {
3579 if (auto *FTy = dyn_cast<FixedVectorType>(Ty);
3580 FTy && IsUnsigned && Opcode == Instruction::Add &&
3581 FTy->getElementType() == IntegerType::getInt1Ty(Ty->getContext())) {
3582 // Represent vector_reduce_add(ZExt(<n x i1>)) as
3583 // ZExtOrTrunc(ctpop(bitcast <n x i1> to in)).
3584 auto *IntTy =
3585 IntegerType::get(ResTy->getContext(), FTy->getNumElements());
3586 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy},
3587 FMF ? *FMF : FastMathFlags());
3588 return thisT()->getCastInstrCost(Instruction::BitCast, IntTy, FTy,
3590 thisT()->getIntrinsicInstrCost(ICA, CostKind);
3591 }
3592 // Without any native support, this is equivalent to the cost of
3593 // vecreduce.opcode(ext(Ty A)).
3594 VectorType *ExtTy = VectorType::get(ResTy, Ty);
3595 InstructionCost RedCost =
3596 thisT()->getArithmeticReductionCost(Opcode, ExtTy, FMF, CostKind);
3597 InstructionCost ExtCost = thisT()->getCastInstrCost(
3598 IsUnsigned ? Instruction::ZExt : Instruction::SExt, ExtTy, Ty,
3600
3601 return RedCost + ExtCost;
3602 }
3603
3605 getMulAccReductionCost(bool IsUnsigned, unsigned RedOpcode, Type *ResTy,
3606 VectorType *Ty,
3607 TTI::TargetCostKind CostKind) const override {
3608 // Without any native support, this is equivalent to the cost of
3609 // vecreduce.add(mul(ext(Ty A), ext(Ty B))) or
3610 // vecreduce.add(mul(A, B)).
3611 assert((RedOpcode == Instruction::Add || RedOpcode == Instruction::Sub) &&
3612 "The reduction opcode is expected to be Add or Sub.");
3613 VectorType *ExtTy = VectorType::get(ResTy, Ty);
3614 InstructionCost RedCost = thisT()->getArithmeticReductionCost(
3615 RedOpcode, ExtTy, std::nullopt, CostKind);
3616 InstructionCost ExtCost = thisT()->getCastInstrCost(
3617 IsUnsigned ? Instruction::ZExt : Instruction::SExt, ExtTy, Ty,
3619
3620 InstructionCost MulCost =
3621 thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
3622
3623 return RedCost + MulCost + 2 * ExtCost;
3624 }
3625
3627 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
3629 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
3631 std::optional<FastMathFlags> FMF) const override {
3632 unsigned EltSizeAcc = AccumType->getScalarSizeInBits();
3633 unsigned EltSizeInA = InputTypeA->getScalarSizeInBits();
3634 unsigned Ratio = EltSizeAcc / EltSizeInA;
3635 if (VF.getKnownMinValue() <= Ratio || VF.getKnownMinValue() % Ratio != 0 ||
3636 EltSizeAcc % EltSizeInA != 0 || (BinOp && InputTypeA != InputTypeB))
3638
3639 Type *InputVectorType = VectorType::get(InputTypeA, VF);
3640 Type *ExtInputVectorType = VectorType::get(AccumType, VF);
3641 Type *AccumVectorType =
3642 VectorType::get(AccumType, VF.divideCoefficientBy(Ratio));
3643
3644 InstructionCost ExtendCostA = 0;
3646 ExtendCostA = getCastInstrCost(
3648 ExtInputVectorType, InputVectorType, TTI::CastContextHint::None,
3649 CostKind);
3650
3651 // TODO: add cost of extracting subvectors from the source vector that
3652 // is to be partially reduced.
3653 InstructionCost ReductionOpCost =
3654 Ratio * getArithmeticInstrCost(Opcode, AccumVectorType, CostKind);
3655
3656 if (!BinOp)
3657 return ExtendCostA + ReductionOpCost;
3658
3659 InstructionCost ExtendCostB = 0;
3661 ExtendCostB = getCastInstrCost(
3663 ExtInputVectorType, InputVectorType, TTI::CastContextHint::None,
3664 CostKind);
3665 return ExtendCostA + ExtendCostB + ReductionOpCost +
3666 getArithmeticInstrCost(*BinOp, ExtInputVectorType, CostKind);
3667 }
3668
3670
3671 /// @}
3672};
3673
3674/// Concrete BasicTTIImpl that can be used if no further customization
3675/// is needed.
3676class BasicTTIImpl : public BasicTTIImplBase<BasicTTIImpl> {
3677 using BaseT = BasicTTIImplBase<BasicTTIImpl>;
3678
3679 friend class BasicTTIImplBase<BasicTTIImpl>;
3680
3681 const TargetSubtargetInfo *ST;
3682 const TargetLoweringBase *TLI;
3683
3684 const TargetSubtargetInfo *getST() const { return ST; }
3685 const TargetLoweringBase *getTLI() const { return TLI; }
3686
3687public:
3688 LLVM_ABI explicit BasicTTIImpl(const TargetMachine *TM, const Function &F);
3689};
3690
3691} // end namespace llvm
3692
3693#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:348
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
@ MASK_BEFOREFIRST
Has one mask vector operand.
@ 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).