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