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