LLVM 24.0.0git
AMDGPUTargetTransformInfo.cpp
Go to the documentation of this file.
1//===- AMDGPUTargetTransformInfo.cpp - AMDGPU specific TTI pass -----------===//
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 implements a TargetTransformInfo analysis pass specific to the
11// AMDGPU target machine. It uses the target's detailed information to provide
12// more precise answers to certain TTI queries, while letting the target
13// independent and default TTI implementations handle the rest.
14//
15//===----------------------------------------------------------------------===//
16
18#include "AMDGPUSubtarget.h"
19#include "AMDGPUTargetMachine.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/IRBuilder.h"
29#include "llvm/IR/IntrinsicsAMDGPU.h"
32#include <optional>
33
34using namespace llvm;
35
36#define DEBUG_TYPE "AMDGPUtti"
37
39 "amdgpu-unroll-threshold-private",
40 cl::desc("Unroll threshold for AMDGPU if private memory used in a loop"),
41 cl::init(2700), cl::Hidden);
42
44 "amdgpu-unroll-threshold-local",
45 cl::desc("Unroll threshold for AMDGPU if local memory used in a loop"),
46 cl::init(1000), cl::Hidden);
47
49 "amdgpu-unroll-threshold-if",
50 cl::desc("Unroll threshold increment for AMDGPU for each if statement inside loop"),
51 cl::init(200), cl::Hidden);
52
54 "amdgpu-unroll-runtime-local",
55 cl::desc("Allow runtime unroll for AMDGPU if local memory used in a loop"),
56 cl::init(true), cl::Hidden);
57
59 "amdgpu-unroll-max-block-to-analyze",
60 cl::desc("Inner loop block size threshold to analyze in unroll for AMDGPU"),
61 cl::init(32), cl::Hidden);
62
63static cl::opt<unsigned> ArgAllocaCost("amdgpu-inline-arg-alloca-cost",
64 cl::Hidden, cl::init(4000),
65 cl::desc("Cost of alloca argument"));
66
67// If the amount of scratch memory to eliminate exceeds our ability to allocate
68// it into registers we gain nothing by aggressively inlining functions for that
69// heuristic.
71 ArgAllocaCutoff("amdgpu-inline-arg-alloca-cutoff", cl::Hidden,
72 cl::init(256),
73 cl::desc("Maximum alloca size to use for inline cost"));
74
75// Inliner constraint to achieve reasonable compilation time.
77 "amdgpu-inline-max-bb", cl::Hidden, cl::init(1100),
78 cl::desc("Maximum number of BBs allowed in a function after inlining"
79 " (compile time constraint)"));
80
81// This default unroll factor is based on microbenchmarks on gfx1030.
83 "amdgpu-memcpy-loop-unroll",
84 cl::desc("Unroll factor (affecting 4x32-bit operations) to use for memory "
85 "operations when lowering statically-sized memcpy, memmove, or"
86 "memset as a loop"),
87 cl::init(16), cl::Hidden);
88
89static bool dependsOnLocalPhi(const Loop *L, const Value *Cond,
90 unsigned Depth = 0) {
92 if (!I)
93 return false;
94
95 if (!L->contains(I))
96 return false;
97 for (const Value *V : I->operand_values()) {
98 if (const PHINode *PHI = dyn_cast<PHINode>(V)) {
99 if (llvm::none_of(L->getSubLoops(), [PHI](const Loop* SubLoop) {
100 return SubLoop->contains(PHI); }))
101 return true;
102 } else if (Depth < 10 && dependsOnLocalPhi(L, V, Depth+1))
103 return true;
104 }
105 return false;
106}
107
109 : BaseT(TM, F.getDataLayout()),
110 TargetTriple(F.getParent()->getTargetTriple()),
111 ST(static_cast<const GCNSubtarget *>(TM->getSubtargetImpl(F))),
112 TLI(ST->getTargetLowering()) {}
113
116 OptimizationRemarkEmitter *ORE) const {
117 const Function &F = *L->getHeader()->getParent();
118 UP.Threshold = static_cast<unsigned>(
119 F.getFnAttributeAsParsedInteger("amdgpu-unroll-threshold", 300));
120 UP.PartialThreshold = static_cast<unsigned>(
121 F.getFnAttributeAsParsedInteger("amdgpu-partial-unroll-threshold", 150));
122 UP.MaxCount = std::numeric_limits<unsigned>::max();
123 UP.Partial = true;
124
125 // Conditional branch in a loop back edge needs 3 additional exec
126 // manipulations in average.
127 UP.BEInsns += 3;
128
129 // We want to run unroll even for the loops which have been vectorized.
130 UP.UnrollVectorizedLoop = true;
131
132 // Enable runtime unrolling for loops whose trip count is not known at
133 // compile time.
134 UP.Runtime = true;
135
136 // Maximum alloca size than can fit registers. Reserve 16 registers.
137 const unsigned MaxAlloca = (256 - 16) * 4;
138 unsigned ThresholdPrivate = UnrollThresholdPrivate;
139 unsigned ThresholdLocal = UnrollThresholdLocal;
140
141 // If this loop has the amdgpu.loop.unroll.threshold metadata we will use the
142 // provided threshold value as the default for Threshold
143 if (MDNode *LoopUnrollThreshold =
144 findOptionMDForLoop(L, "amdgpu.loop.unroll.threshold")) {
145 if (LoopUnrollThreshold->getNumOperands() == 2) {
147 LoopUnrollThreshold->getOperand(1));
148 if (MetaThresholdValue) {
149 // We will also use the supplied value for PartialThreshold for now.
150 // We may introduce additional metadata if it becomes necessary in the
151 // future.
152 UP.Threshold =
153 static_cast<unsigned>(MetaThresholdValue->getSExtValue());
155 ThresholdPrivate = std::min(ThresholdPrivate, UP.Threshold);
156 ThresholdLocal = std::min(ThresholdLocal, UP.Threshold);
157 }
158 }
159 }
160
161 unsigned MaxBoost = std::max(ThresholdPrivate, ThresholdLocal);
162 for (const BasicBlock *BB : L->getBlocks()) {
163 const DataLayout &DL = BB->getDataLayout();
164 unsigned LocalGEPsSeen = 0;
165
166 if (llvm::any_of(L->getSubLoops(), [BB](const Loop* SubLoop) {
167 return SubLoop->contains(BB); }))
168 continue; // Block belongs to an inner loop.
169
170 for (const Instruction &I : *BB) {
171 // Unroll a loop which contains an "if" statement whose condition
172 // defined by a PHI belonging to the loop. This may help to eliminate
173 // if region and potentially even PHI itself, saving on both divergence
174 // and registers used for the PHI.
175 // Add a small bonus for each of such "if" statements.
176 if (const CondBrInst *Br = dyn_cast<CondBrInst>(&I)) {
177 if (UP.Threshold < MaxBoost) {
178 BasicBlock *Succ0 = Br->getSuccessor(0);
179 BasicBlock *Succ1 = Br->getSuccessor(1);
180 if ((L->contains(Succ0) && L->isLoopExiting(Succ0)) ||
181 (L->contains(Succ1) && L->isLoopExiting(Succ1)))
182 continue;
183 if (dependsOnLocalPhi(L, Br->getCondition())) {
185 LLVM_DEBUG(dbgs() << "Set unroll threshold " << UP.Threshold
186 << " for loop:\n"
187 << *L << " due to " << *Br << '\n');
188 if (UP.Threshold >= MaxBoost)
189 return;
190 }
191 }
192 continue;
193 }
194
196 if (!GEP)
197 continue;
198
199 unsigned AS = GEP->getAddressSpace();
200 unsigned Threshold = 0;
202 Threshold = ThresholdPrivate;
204 Threshold = ThresholdLocal;
205 else
206 continue;
207
208 if (UP.Threshold >= Threshold)
209 continue;
210
211 if (AS == AMDGPUAS::PRIVATE_ADDRESS) {
212 const Value *Ptr = GEP->getPointerOperand();
213 const AllocaInst *Alloca =
215 if (!Alloca || !Alloca->isStaticAlloca())
216 continue;
217 auto AllocaSize = Alloca->getAllocationSize(DL);
218 if (!AllocaSize || AllocaSize->getFixedValue() > MaxAlloca)
219 continue;
220 } else if (AS == AMDGPUAS::LOCAL_ADDRESS ||
222 LocalGEPsSeen++;
223 // Inhibit unroll for local memory if we have seen addressing not to
224 // a variable, most likely we will be unable to combine it.
225 // Do not unroll too deep inner loops for local memory to give a chance
226 // to unroll an outer loop for a more important reason.
227 if (LocalGEPsSeen > 1 || L->getLoopDepth() > 2 ||
228 (!isa<GlobalVariable>(GEP->getPointerOperand()) &&
229 !isa<Argument>(GEP->getPointerOperand())))
230 continue;
231 LLVM_DEBUG(dbgs() << "Allow unroll runtime for loop:\n"
232 << *L << " due to LDS use.\n");
234 }
235
236 // Check if GEP depends on a value defined by this loop itself.
237 bool HasLoopDef = false;
238 for (const Value *Op : GEP->operands()) {
239 const Instruction *Inst = dyn_cast<Instruction>(Op);
240 if (!Inst || L->isLoopInvariant(Op))
241 continue;
242
243 if (llvm::any_of(L->getSubLoops(), [Inst](const Loop* SubLoop) {
244 return SubLoop->contains(Inst); }))
245 continue;
246 HasLoopDef = true;
247 break;
248 }
249 if (!HasLoopDef)
250 continue;
251
252 // We want to do whatever we can to limit the number of alloca
253 // instructions that make it through to the code generator. allocas
254 // require us to use indirect addressing, which is slow and prone to
255 // compiler bugs. If this loop does an address calculation on an
256 // alloca ptr, then we want to use a higher than normal loop unroll
257 // threshold. This will give SROA a better chance to eliminate these
258 // allocas.
259 //
260 // We also want to have more unrolling for local memory to let ds
261 // instructions with different offsets combine.
262 //
263 // Don't use the maximum allowed value here as it will make some
264 // programs way too big.
265 UP.Threshold = Threshold;
266 LLVM_DEBUG(dbgs() << "Set unroll threshold " << Threshold
267 << " for loop:\n"
268 << *L << " due to " << *GEP << '\n');
269 if (UP.Threshold >= MaxBoost)
270 return;
271 }
272
273 // If we got a GEP in a small BB from inner loop then increase max trip
274 // count to analyze for better estimation cost in unroll
275 if (L->isInnermost() && BB->size() < UnrollMaxBlockToAnalyze)
277 }
278}
279
284
286 return 1024;
287}
288
290 : BaseT(TM, F.getDataLayout()),
291 ST(static_cast<const GCNSubtarget *>(TM->getSubtargetImpl(F))),
292 TLI(ST->getTargetLowering()), CommonTTI(TM, F),
293 IsGraphics(AMDGPU::isGraphics(F.getCallingConv())) {
295 HasFP32Denormals = Mode.FP32Denormals != DenormalMode::getPreserveSign();
296}
297
299 return !F || !ST->isSingleLaneExecution(*F);
300}
301
302unsigned GCNTTIImpl::getNumberOfRegisters(unsigned RCID) const {
303 // NB: RCID is not an RCID. In fact it is 0 or 1 for scalar or vector
304 // registers. See getRegisterClassForType for the implementation.
305 // In this case vector registers are not vector in terms of
306 // VGPRs, but those which can hold multiple values.
307
308 // This is really the number of registers to fill when vectorizing /
309 // interleaving loops, so we lie to avoid trying to use all registers.
310 return 4;
311}
312
315 switch (K) {
317 return TypeSize::getFixed(32);
319 return TypeSize::getFixed(
320 (ST->hasAnyPackedFP64Ops() || ST->hasAnyPackedU64Ops()) ? 128
321 : ST->hasAnyPackedFP32Ops() ? 64
322 : 32);
324 return TypeSize::getScalable(0);
325 }
326 llvm_unreachable("Unsupported register kind");
327}
328
330 return 32;
331}
332
333unsigned GCNTTIImpl::getMaximumVF(unsigned ElemWidth, unsigned Opcode) const {
334 if (Opcode == Instruction::Load || Opcode == Instruction::Store)
335 return 32 * 4 / ElemWidth;
336 // For a given width return the max 0number of elements that can be combined
337 // into a wider bit value:
338 return (ElemWidth == 8 && ST->has16BitInsts()) ? 4
339 : (ElemWidth == 16 && ST->has16BitInsts()) ? 2
340 : (ElemWidth == 32 && ST->hasAnyPackedFP32Ops()) ? 2
341 : (ElemWidth == 64 &&
342 (ST->hasAnyPackedFP64Ops() || ST->hasAnyPackedU64Ops()))
343 ? 2
344 : 1;
345}
346
348 // The integer inst-count heuristic causes regressions on gfx94x and gfx950
349 // because 2-element vector trees that pass the scalar/vector instruction
350 // count comparison still widen scalar moves (e.g. v_mov_b32 to v_mov_b64)
351 // after codegen, increasing register pressure and throughput cost without
352 // reducing the total instruction count.
353 return !ST->hasGFX940Insts() && !ST->hasGFX950Insts();
354}
355
356unsigned GCNTTIImpl::getLoadVectorFactor(unsigned VF, unsigned LoadSize,
357 unsigned ChainSizeInBytes,
358 VectorType *VecTy) const {
359 unsigned VecRegBitWidth = VF * LoadSize;
360 if (VecRegBitWidth > 128 && VecTy->getScalarSizeInBits() < 32)
361 // TODO: Support element-size less than 32bit?
362 return 128 / LoadSize;
363
364 return VF;
365}
366
367unsigned GCNTTIImpl::getStoreVectorFactor(unsigned VF, unsigned StoreSize,
368 unsigned ChainSizeInBytes,
369 VectorType *VecTy) const {
370 unsigned VecRegBitWidth = VF * StoreSize;
371 if (VecRegBitWidth > 128)
372 return 128 / StoreSize;
373
374 return VF;
375}
376
377unsigned GCNTTIImpl::getLoadStoreVecRegBitWidth(unsigned AddrSpace) const {
378 if (AddrSpace == AMDGPUAS::GLOBAL_ADDRESS ||
379 AddrSpace == AMDGPUAS::CONSTANT_ADDRESS ||
381 AddrSpace == AMDGPUAS::BUFFER_FAT_POINTER ||
382 AddrSpace == AMDGPUAS::BUFFER_RESOURCE ||
384 return 512;
385 }
386
387 if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS)
388 return 8 * ST->getMaxPrivateElementSize();
389
390 // Common to flat, global, local and region. Assume for unknown addrspace.
391 return 128;
392}
393
394bool GCNTTIImpl::isLegalToVectorizeMemChain(unsigned ChainSizeInBytes,
395 Align Alignment,
396 unsigned AddrSpace) const {
397 // We allow vectorization of flat stores, even though we may need to decompose
398 // them later if they may access private memory. We don't have enough context
399 // here, and legalization can handle it.
400 if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS) {
401 return (Alignment >= 4 || ST->hasUnalignedScratchAccessEnabled()) &&
402 ChainSizeInBytes <= ST->getMaxPrivateElementSize();
403 }
404 return true;
405}
406
407bool GCNTTIImpl::isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,
408 Align Alignment,
409 unsigned AddrSpace) const {
410 return isLegalToVectorizeMemChain(ChainSizeInBytes, Alignment, AddrSpace);
411}
412
413bool GCNTTIImpl::isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,
414 Align Alignment,
415 unsigned AddrSpace) const {
416 return isLegalToVectorizeMemChain(ChainSizeInBytes, Alignment, AddrSpace);
417}
418
420 return 1024;
421}
422
424 LLVMContext &Context, Value *Length, unsigned SrcAddrSpace,
425 unsigned DestAddrSpace, Align SrcAlign, Align DestAlign,
426 std::optional<uint32_t> AtomicElementSize) const {
427
428 if (AtomicElementSize)
429 return Type::getIntNTy(Context, *AtomicElementSize * 8);
430
431 // 16-byte accesses achieve the highest copy throughput.
432 // If the operation has a fixed known length that is large enough, it is
433 // worthwhile to return an even wider type and let legalization lower it into
434 // multiple accesses, effectively unrolling the memcpy loop.
435 // We also rely on legalization to decompose into smaller accesses for
436 // subtargets and address spaces where it is necessary.
437 //
438 // Don't unroll if Length is not a constant, since unrolling leads to worse
439 // performance for length values that are smaller or slightly larger than the
440 // total size of the type returned here. Mitigating that would require a more
441 // complex lowering for variable-length memcpy and memmove.
442 unsigned I32EltsInVector = 4;
445 MemcpyLoopUnroll * I32EltsInVector);
446
447 return FixedVectorType::get(Type::getInt32Ty(Context), I32EltsInVector);
448}
449
451 SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
452 unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
453 Align SrcAlign, Align DestAlign,
454 std::optional<uint32_t> AtomicCpySize) const {
455
456 if (AtomicCpySize)
458 OpsOut, Context, RemainingBytes, SrcAddrSpace, DestAddrSpace, SrcAlign,
459 DestAlign, AtomicCpySize);
460
461 Type *I32x4Ty = FixedVectorType::get(Type::getInt32Ty(Context), 4);
462 while (RemainingBytes >= 16) {
463 OpsOut.push_back(I32x4Ty);
464 RemainingBytes -= 16;
465 }
466
467 Type *I64Ty = Type::getInt64Ty(Context);
468 while (RemainingBytes >= 8) {
469 OpsOut.push_back(I64Ty);
470 RemainingBytes -= 8;
471 }
472
473 Type *I32Ty = Type::getInt32Ty(Context);
474 while (RemainingBytes >= 4) {
475 OpsOut.push_back(I32Ty);
476 RemainingBytes -= 4;
477 }
478
479 Type *I16Ty = Type::getInt16Ty(Context);
480 while (RemainingBytes >= 2) {
481 OpsOut.push_back(I16Ty);
482 RemainingBytes -= 2;
483 }
484
485 Type *I8Ty = Type::getInt8Ty(Context);
486 while (RemainingBytes) {
487 OpsOut.push_back(I8Ty);
488 --RemainingBytes;
489 }
490}
491
493 bool HasUnorderedReductions) const {
494 // Disable unrolling if the loop is not vectorized.
495 // TODO: Enable this again.
496 if (VF.isScalar())
497 return 1;
498
499 return 8;
500}
501
503 MemIntrinsicInfo &Info) const {
504 switch (Inst->getIntrinsicID()) {
505 case Intrinsic::amdgcn_ds_ordered_add:
506 case Intrinsic::amdgcn_ds_ordered_swap: {
507 auto *Ordering = dyn_cast<ConstantInt>(Inst->getArgOperand(2));
508 auto *Volatile = dyn_cast<ConstantInt>(Inst->getArgOperand(4));
509 if (!Ordering || !Volatile)
510 return false; // Invalid.
511
512 uint64_t OrderingVal = Ordering->getZExtValue();
513 if (!isValidAtomicOrdering(OrderingVal))
514 return false;
515
516 Info.PtrVal = Inst->getArgOperand(0);
517 Info.Ordering = static_cast<AtomicOrdering>(OrderingVal);
518 Info.ReadMem = true;
519 Info.WriteMem = true;
520 Info.IsVolatile = !Volatile->isZero();
521 return true;
522 }
523 default:
524 return false;
525 }
526}
527
528/// \returns true if \p FMul and its single fadd/fsub user \p FAddSub are
529/// expected to fuse during instruction selection. \p Ty is the type the fused
530/// operation runs on.
531static bool canFuseFMulWithFAddSub(const SITargetLowering &TLI, Type *Ty,
532 const Instruction *FMul,
533 const Instruction *FAddSub) {
534 assert((FAddSub->getOpcode() == Instruction::FAdd ||
535 FAddSub->getOpcode() == Instruction::FSub) &&
536 "Expected an fadd or an fsub");
537
538 // The mad forms fuse exactly without fast-math flags but flush denormals.
539 // An fma forms only when it is not slower than the separate operations.
540 const Function &F = *FAddSub->getFunction();
541 const bool HasFMAD = TLI.isFMADLegal(F, Ty);
542 const bool HasFMA = TLI.isFMAFasterThanFMulAndFAdd(F, Ty);
543 if (!HasFMAD && !HasFMA)
544 return false;
545
546 // Without a mad the pair fuses only when both carry contract.
547 return HasFMAD || (FAddSub->hasAllowContract() && FMul->hasAllowContract());
548}
549
550/// An fma holds one multiply, so only one fmul operand fuses with \p FAddSub.
551static const Instruction *getFusedFMul(const SITargetLowering &TLI, Type *Ty,
552 const Instruction *FAddSub) {
553 for (const Value *Op : FAddSub->operands()) {
554 const auto *FMul = dyn_cast<Instruction>(Op);
555 if (FMul && FMul->getOpcode() == Instruction::FMul && FMul->hasOneUse() &&
556 canFuseFMulWithFAddSub(TLI, Ty, FMul, FAddSub))
557 return FMul;
558 }
559 return nullptr;
560}
561
562static bool isFusedFMul(const SITargetLowering &TLI, Type *Ty,
563 const Instruction *FMul, const Instruction *FAddSub) {
564 const Instruction *Fused = getFusedFMul(TLI, Ty, FAddSub);
565 if (Fused == FMul)
566 return true;
567 // (a * b + c * d) + e becomes fma(a, b, fma(c, d, e)) if the outer fadd has
568 // reassoc.
569 if (!Fused || FAddSub->getOpcode() != Instruction::FAdd ||
570 !FAddSub->hasOneUse())
571 return false;
572 const auto *Outer = dyn_cast<BinaryOperator>(*FAddSub->user_begin());
573 return Outer && Outer->getOpcode() == Instruction::FAdd &&
574 Outer->hasAllowReassoc() &&
575 canFuseFMulWithFAddSub(TLI, Ty, FMul, Outer);
576}
577
579 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
581 ArrayRef<const Value *> Args, const Instruction *CtxI) const {
582
583 // Legalize the type.
584 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
585 int ISD = TLI->InstructionOpcodeToISD(Opcode);
586
587 // Because we don't have any legal vector operations, but the legal types, we
588 // need to account for split vectors.
589 unsigned NElts = LT.second.isVector() ?
590 LT.second.getVectorNumElements() : 1;
591
592 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
593
594 switch (ISD) {
595 case ISD::SHL:
596 case ISD::SRL:
597 case ISD::SRA:
598 if (SLT == MVT::i64)
599 return get64BitInstrCost(CostKind) * LT.first * NElts;
600
601 if (ST->has16BitInsts() && SLT == MVT::i16)
602 NElts = (NElts + 1) / 2;
603
604 // i32
605 return getFullRateInstrCost() * LT.first * NElts;
606 case ISD::ADD:
607 case ISD::SUB:
608 if (SLT == MVT::i64 && ST->hasAnyPackedU64Ops())
609 NElts = (NElts + 1) / 2;
610 [[fallthrough]];
611 case ISD::AND:
612 case ISD::OR:
613 case ISD::XOR:
614 if (SLT == MVT::i64) {
615 // and, or and xor are typically split into 2 VALU instructions.
616 return 2 * getFullRateInstrCost() * LT.first * NElts;
617 }
618
619 if (ST->has16BitInsts() && SLT == MVT::i16)
620 NElts = (NElts + 1) / 2;
621
622 return LT.first * NElts * getFullRateInstrCost();
623 case ISD::MUL: {
624 const int QuarterRateCost = getQuarterRateInstrCost(CostKind);
625 if (SLT == MVT::i64) {
626 const int FullRateCost = getFullRateInstrCost();
627 return (4 * QuarterRateCost + (2 * 2) * FullRateCost) * LT.first * NElts;
628 }
629
630 if (ST->has16BitInsts() && SLT == MVT::i16)
631 NElts = (NElts + 1) / 2;
632
633 // i32
634 return QuarterRateCost * NElts * LT.first;
635 }
636 case ISD::FMUL:
637 // Check possible fuse {fadd|fsub}(a,fmul(b,c)) and return zero cost for
638 // fmul(b,c) supposing the fadd|fsub will get estimated cost for the whole
639 // fused operation. A vector fmul priced with a scalar context fuses with
640 // the scalar fadd|fsub only when it is emitted lane by lane.
641 if (CtxI && CtxI->hasOneUse() &&
642 (CtxI->getType() == Ty ||
643 getMaximumVF(Ty->getScalarSizeInBits(), Opcode) == 1)) {
644 const auto *FAddSub = dyn_cast<BinaryOperator>(*CtxI->user_begin());
645 if (FAddSub &&
646 (FAddSub->getOpcode() == Instruction::FAdd ||
647 FAddSub->getOpcode() == Instruction::FSub) &&
648 isFusedFMul(*TLI, Ty, CtxI, FAddSub))
650 }
651 [[fallthrough]];
652 case ISD::FADD:
653 case ISD::FSUB:
654 if (ST->hasAnyPackedFP32Ops() && SLT == MVT::f32)
655 NElts = (NElts + 1) / 2;
656 if (ST->hasBF16PackedInsts() && SLT == MVT::bf16)
657 NElts = (NElts + 1) / 2;
658 if (SLT == MVT::f64) {
659 if (ST->hasAnyPackedFP64Ops())
660 NElts = (NElts + 1) / 2;
661 return LT.first * NElts * get64BitInstrCost(CostKind);
662 }
663
664 if (ST->has16BitInsts() && SLT == MVT::f16)
665 NElts = (NElts + 1) / 2;
666
667 if (SLT == MVT::f32 || SLT == MVT::f16 || SLT == MVT::bf16)
668 return LT.first * NElts * getFullRateInstrCost();
669 break;
670 case ISD::FDIV:
671 case ISD::FREM:
672 // FIXME: frem should be handled separately. The fdiv in it is most of it,
673 // but the current lowering is also not entirely correct.
674 if (SLT == MVT::f64) {
675 int Cost = 7 * get64BitInstrCost(CostKind) +
676 getQuarterRateInstrCost(CostKind) +
677 3 * getHalfRateInstrCost(CostKind);
678 // Add cost of workaround.
679 if (!ST->hasUsableDivScaleConditionOutput())
680 Cost += 3 * getFullRateInstrCost();
681
682 return LT.first * Cost * NElts;
683 }
684
685 if (!Args.empty() && match(Args[0], PatternMatch::m_FPOne())) {
686 // TODO: This is more complicated, unsafe flags etc.
687 if ((SLT == MVT::f32 && !HasFP32Denormals) ||
688 (SLT == MVT::f16 && ST->has16BitInsts())) {
689 return LT.first * getTransInstrCost(CostKind) * NElts;
690 }
691 }
692
693 if (SLT == MVT::f16 && ST->has16BitInsts()) {
694 // 2 x v_cvt_f32_f16
695 // f32 rcp
696 // f32 fmul
697 // v_cvt_f16_f32
698 // f16 div_fixup
699 int Cost = 4 * getFullRateInstrCost() + 2 * getTransInstrCost(CostKind);
700 return LT.first * Cost * NElts;
701 }
702
703 if (SLT == MVT::f32 && (CtxI && CtxI->hasApproxFunc())) {
704 // Fast unsafe fdiv lowering:
705 // f32 rcp
706 // f32 fmul
707 int Cost = getTransInstrCost(CostKind) + getFullRateInstrCost();
708 return LT.first * Cost * NElts;
709 }
710
711 if (SLT == MVT::f32 || SLT == MVT::f16) {
712 // 4 more v_cvt_* insts without f16 insts support
713 int Cost = (SLT == MVT::f16 ? 14 : 10) * getFullRateInstrCost() +
714 1 * getTransInstrCost(CostKind);
715
716 if (!HasFP32Denormals) {
717 // FP mode switches.
718 Cost += 2 * getFullRateInstrCost();
719 }
720
721 return LT.first * NElts * Cost;
722 }
723 break;
724 case ISD::FNEG:
725 // Use the backend' estimation. If fneg is not free each element will cost
726 // one additional instruction.
727 return TLI->isFNegFree(SLT) ? 0 : NElts;
728 default:
729 break;
730 }
731
732 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
733 Args, CtxI);
734}
735
736// Return true if there's a potential benefit from using v2f16/v2i16
737// instructions for an intrinsic, even if it requires nontrivial legalization.
739 switch (ID) {
740 case Intrinsic::fma:
741 case Intrinsic::fmuladd:
742 case Intrinsic::copysign:
743 case Intrinsic::minimumnum:
744 case Intrinsic::maximumnum:
745 case Intrinsic::canonicalize:
746 // There's a small benefit to using vector ops in the legalized code.
747 case Intrinsic::round:
748 case Intrinsic::uadd_sat:
749 case Intrinsic::usub_sat:
750 case Intrinsic::sadd_sat:
751 case Intrinsic::ssub_sat:
752 case Intrinsic::abs:
753 return true;
754 default:
755 return false;
756 }
757}
758
761 TTI::TargetCostKind CostKind) const {
762 switch (ICA.getID()) {
763 case Intrinsic::fabs:
764 // Free source modifier in the common case.
765 return 0;
766 case Intrinsic::amdgcn_workitem_id_x:
767 case Intrinsic::amdgcn_workitem_id_y:
768 case Intrinsic::amdgcn_workitem_id_z:
769 // TODO: If hasPackedTID, or if the calling context is not an entry point
770 // there may be a bit instruction.
771 return 0;
772 case Intrinsic::amdgcn_workgroup_id_x:
773 case Intrinsic::amdgcn_workgroup_id_y:
774 case Intrinsic::amdgcn_workgroup_id_z:
775 case Intrinsic::amdgcn_lds_kernel_id:
776 case Intrinsic::amdgcn_dispatch_ptr:
777 case Intrinsic::amdgcn_dispatch_id:
778 case Intrinsic::amdgcn_implicitarg_ptr:
779 case Intrinsic::amdgcn_queue_ptr:
780 // Read from an argument register.
781 return 0;
782 default:
783 break;
784 }
785
786 Type *RetTy = ICA.getReturnType();
787
788 Intrinsic::ID IID = ICA.getID();
789 switch (IID) {
790 case Intrinsic::exp:
791 case Intrinsic::exp2:
792 case Intrinsic::exp10: {
793 // Legalize the type.
794 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
795 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
796 unsigned NElts =
797 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
798
799 if (SLT == MVT::f64) {
800 unsigned NumOps = 20;
801 if (IID == Intrinsic::exp)
802 ++NumOps;
803 else if (IID == Intrinsic::exp10)
804 NumOps += 3;
805
806 return LT.first * NElts * NumOps * get64BitInstrCost(CostKind);
807 }
808
809 if (SLT == MVT::f32) {
810 unsigned NumFullRateOps = 0;
811 // v_exp_f32 (transcendental).
812 unsigned NumTransOps = 1;
813
814 if (!ICA.getFlags().approxFunc() && IID != Intrinsic::exp2) {
815 // Non-AFN exp/exp10: range reduction + v_exp_f32 + ldexp +
816 // overflow/underflow checks (lowerFEXP). Denorm is also handled.
817 // FMA preamble: ~13 full-rate ops; non-FMA: ~17.
818 NumFullRateOps = ST->hasFastFMAF32() ? 13 : 17;
819 } else {
820 if (IID == Intrinsic::exp) {
821 // lowerFEXPUnsafe: fmul (base conversion) + v_exp_f32.
822 NumFullRateOps = 1;
823 } else if (IID == Intrinsic::exp10) {
824 // lowerFEXP10Unsafe: 3 fmul + 2 v_exp_f32 (double-exp2).
825 NumFullRateOps = 3;
826 NumTransOps = 2;
827 }
828 // Denorm scaling adds setcc + select + fadd + select + fmul.
829 if (HasFP32Denormals)
830 NumFullRateOps += 5;
831 }
832
833 InstructionCost Cost = NumFullRateOps * getFullRateInstrCost() +
834 NumTransOps * getTransInstrCost(CostKind);
835 return LT.first * NElts * Cost;
836 }
837
838 break;
839 }
840 case Intrinsic::log:
841 case Intrinsic::log2:
842 case Intrinsic::log10: {
843 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
844 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
845 unsigned NElts =
846 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
847
848 if (SLT == MVT::f32) {
849 unsigned NumFullRateOps = 0;
850
851 if (IID == Intrinsic::log2) {
852 // LowerFLOG2: just v_log_f32.
853 } else if (ICA.getFlags().approxFunc()) {
854 // LowerFLOGUnsafe: v_log_f32 + fmul (base conversion).
855 NumFullRateOps = 1;
856 } else {
857 // LowerFLOGCommon non-AFN: v_log_f32 + extended-precision
858 // multiply + finite check.
859 NumFullRateOps = ST->hasFastFMAF32() ? 8 : 11;
860 }
861
862 if (HasFP32Denormals)
863 NumFullRateOps += 5;
864
866 NumFullRateOps * getFullRateInstrCost() + getTransInstrCost(CostKind);
867 return LT.first * NElts * Cost;
868 }
869
870 break;
871 }
872 case Intrinsic::sin:
873 case Intrinsic::cos: {
874 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
875 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
876 unsigned NElts =
877 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
878
879 if (SLT == MVT::f32) {
880 // LowerTrig: fmul(1/2pi) + v_sin/v_cos.
881 unsigned NumFullRateOps = ST->hasTrigReducedRange() ? 2 : 1;
882
884 NumFullRateOps * getFullRateInstrCost() + getTransInstrCost(CostKind);
885 return LT.first * NElts * Cost;
886 }
887
888 break;
889 }
890 case Intrinsic::sqrt: {
891 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
892 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
893 unsigned NElts =
894 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
895
896 if (SLT == MVT::f32) {
897 unsigned NumFullRateOps = 0;
898
899 if (!ICA.getFlags().approxFunc()) {
900 // lowerFSQRTF32 non-AFN: v_sqrt_f32 + refinement + scale fixup.
901 NumFullRateOps = HasFP32Denormals ? 17 : 16;
902 }
903
905 NumFullRateOps * getFullRateInstrCost() + getTransInstrCost(CostKind);
906 return LT.first * NElts * Cost;
907 }
908
909 break;
910 }
911 default:
912 break;
913 }
914
916 return BaseT::getIntrinsicInstrCost(ICA, CostKind);
917
918 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
919 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
920 unsigned NElts = LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
921
922 if ((ST->hasVOP3PInsts() &&
923 (SLT == MVT::f16 || SLT == MVT::i16 ||
924 (SLT == MVT::bf16 && ST->hasBF16PackedInsts()))) ||
925 (ST->hasAnyPackedFP64Ops() && SLT == MVT::f64) ||
926 (ST->hasAnyPackedU64Ops() && SLT == MVT::i64)) {
927 NElts = (NElts + 1) / 2;
928 } else if (SLT == MVT::f32) {
929 bool HasPk2FP32Op = ST->hasAnyPackedFP32Ops() &&
930 IID != Intrinsic::minimumnum &&
931 IID != Intrinsic::maximumnum;
932 NElts = HasPk2FP32Op ? (NElts + 1) / 2 : NElts;
933 }
934
935 // TODO: Get more refined intrinsic costs?
936 unsigned InstRate = getQuarterRateInstrCost(CostKind);
937
938 switch (ICA.getID()) {
939 case Intrinsic::fma:
940 case Intrinsic::fmuladd:
941 if (SLT == MVT::f64) {
942 InstRate = get64BitInstrCost(CostKind);
943 break;
944 }
945
946 if ((SLT == MVT::f32 && ST->hasFastFMAF32()) || SLT == MVT::f16)
947 InstRate = getFullRateInstrCost();
948 else {
949 InstRate = ST->hasFastFMAF32() ? getHalfRateInstrCost(CostKind)
950 : getQuarterRateInstrCost(CostKind);
951 }
952 break;
953 case Intrinsic::copysign:
954 return NElts * getFullRateInstrCost();
955 case Intrinsic::minimumnum:
956 case Intrinsic::maximumnum: {
957 // Instruction + 2 canonicalizes. For cases that need type promotion, we the
958 // promotion takes the place of the canonicalize.
959 unsigned NumOps = 3;
960 if (const IntrinsicInst *II = ICA.getInst()) {
961 // Directly legal with ieee=0
962 // TODO: Not directly legal with strictfp
964 NumOps = 1;
965 }
966
967 unsigned BaseRate =
968 SLT == MVT::f64 ? get64BitInstrCost(CostKind) : getFullRateInstrCost();
969 InstRate = BaseRate * NumOps;
970 break;
971 }
972 case Intrinsic::canonicalize: {
973 InstRate =
974 SLT == MVT::f64 ? get64BitInstrCost(CostKind) : getFullRateInstrCost();
975 break;
976 }
977 case Intrinsic::uadd_sat:
978 case Intrinsic::usub_sat:
979 case Intrinsic::sadd_sat:
980 case Intrinsic::ssub_sat: {
981 if (SLT == MVT::i16 || SLT == MVT::i32)
982 InstRate = getFullRateInstrCost();
983
984 static const auto ValidSatTys = {MVT::v2i16, MVT::v4i16};
985 if (any_of(ValidSatTys, equal_to(LT.second)))
986 NElts = 1;
987 break;
988 }
989 case Intrinsic::abs:
990 // Expansion takes 2 instructions for VALU
991 if (SLT == MVT::i16 || SLT == MVT::i32)
992 InstRate = 2 * getFullRateInstrCost();
993 break;
994 default:
995 break;
996 }
997
998 return LT.first * NElts * InstRate;
999}
1000
1002 TTI::TargetCostKind CostKind,
1003 const Instruction *I) const {
1004 assert((I == nullptr || I->getOpcode() == Opcode) &&
1005 "Opcode should reflect passed instruction.");
1006 const bool SCost =
1007 (CostKind == TTI::TCK_CodeSize || CostKind == TTI::TCK_SizeAndLatency);
1008 const int CBrCost = SCost ? 5 : 7;
1009 switch (Opcode) {
1010 case Instruction::UncondBr:
1011 // Branch instruction takes about 4 slots on gfx900.
1012 return SCost ? 1 : 4;
1013 case Instruction::CondBr:
1014 // Suppose conditional branch takes additional 3 exec manipulations
1015 // instructions in average.
1016 return CBrCost;
1017 case Instruction::Switch: {
1018 const auto *SI = dyn_cast_or_null<SwitchInst>(I);
1019 // Each case (including default) takes 1 cmp + 1 cbr instructions in
1020 // average.
1021 return (SI ? (SI->getNumCases() + 1) : 4) * (CBrCost + 1);
1022 }
1023 case Instruction::Ret:
1024 return SCost ? 1 : 10;
1025 }
1026 return BaseT::getCFInstrCost(Opcode, CostKind, I);
1027}
1028
1030 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
1032 TTI::OperandValueInfo Op2Info, const Instruction *I) const {
1033 // For size and latency cost kinds, return a low cost independent of vector
1034 // width to enable SimplifyCFG's speculativelyExecuteBB optimization.
1035 if (CostKind == TTI::TCK_SizeAndLatency)
1036 return 1;
1037
1038 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
1039 Op1Info, Op2Info, I);
1040}
1041
1042// Measured packing cost of i1 for gfx9-12 is 4.0 to 4.8, up to 5.4 with
1043// true16; unpacking is 2.6 to 2.9.
1044static constexpr unsigned MaskPackCostPerElt = 4;
1045static constexpr unsigned MaskUnpackCostPerElt = 3;
1046
1047static std::optional<unsigned> getNumberOfPackedMaskElts(Type *Ty) {
1048 auto *FVT = dyn_cast<FixedVectorType>(Ty);
1049 if (FVT && FVT->getElementType()->isIntegerTy(1) && FVT->getNumElements() > 1)
1050 return FVT->getNumElements();
1051 return std::nullopt;
1052}
1053
1055 Type *Src,
1057 TTI::TargetCostKind CostKind,
1058 const Instruction *I) const {
1059 // A bitcast between a vector of i1 and an integer packs or unpacks a mask.
1060 if (Opcode == Instruction::BitCast) {
1061 if (std::optional<unsigned> Elts = getNumberOfPackedMaskElts(Src);
1062 Elts && Dst->isIntegerTy(*Elts))
1063 return InstructionCost(MaskPackCostPerElt) * *Elts *
1064 getFullRateInstrCost();
1065 if (std::optional<unsigned> Elts = getNumberOfPackedMaskElts(Dst);
1066 Elts && Src->isIntegerTy(*Elts))
1067 return InstructionCost(MaskUnpackCostPerElt) * *Elts *
1068 getFullRateInstrCost();
1069 }
1070
1071 // Each f32 lane is rounded and the halves are packed in pairs. A packed
1072 // conversion rounds a pair at once and true16 writes either half.
1073 if (auto *SrcVTy = dyn_cast<FixedVectorType>(Src);
1074 SrcVTy && Opcode == Instruction::FPTrunc && ST->has16BitInsts() &&
1075 SrcVTy->getElementType()->isFloatTy() &&
1076 Dst->getScalarType()->isHalfTy()) {
1077 const unsigned NElts = SrcVTy->getNumElements();
1078 const unsigned Ops = ST->hasCvtPkF16F32Inst() ? divideCeil(NElts, 2)
1079 : ST->useRealTrue16Insts() ? NElts
1080 : NElts + NElts / 2;
1081 return InstructionCost(Ops) * getFullRateInstrCost();
1082 }
1083
1084 const int ISD = TLI->InstructionOpcodeToISD(Opcode);
1085 switch (ISD) {
1086 case ISD::SINT_TO_FP:
1087 case ISD::UINT_TO_FP:
1088 case ISD::FP_TO_SINT:
1089 case ISD::FP_TO_UINT:
1090 break;
1091 default:
1092 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1093 }
1094
1095 const bool IsIntToFP = ISD == ISD::SINT_TO_FP || ISD == ISD::UINT_TO_FP;
1096 Type *FPTy = (IsIntToFP ? Dst : Src)->getScalarType();
1097 if (!FPTy->isHalfTy() && !FPTy->isBFloatTy() && !FPTy->isFloatTy() &&
1098 !FPTy->isDoubleTy())
1099 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1100
1101 unsigned NElts = 1;
1102 if (auto *VT = dyn_cast<FixedVectorType>(Src))
1103 NElts = VT->getNumElements();
1104
1105 const unsigned SrcBits = Src->getScalarSizeInBits();
1106 const unsigned DstBits = Dst->getScalarSizeInBits();
1107 const bool IsSigned = ISD == ISD::SINT_TO_FP || ISD == ISD::FP_TO_SINT;
1108 const unsigned IntBits = IsIntToFP ? SrcBits : DstBits;
1109 const bool UsesInt64 = IntBits > 32 && IntBits <= 64;
1110
1111 auto Scale = [&](unsigned FullRateOps,
1112 unsigned FP64Ops = 0) -> InstructionCost {
1113 return NElts * (InstructionCost(FullRateOps) * getFullRateInstrCost() +
1114 InstructionCost(FP64Ops) * get64BitInstrCost(CostKind));
1115 };
1116
1117 if (IsIntToFP) {
1118 // A scalar load of a whole number of bytes that is not a power of two is
1119 // split and its high part load extends the source. A constant address
1120 // space or invariant global load aligned to 4 bytes may be widened instead
1121 // and then still needs the extension. So does a buffer fat pointer load.
1122 const auto *Load =
1123 I && Src->isIntegerTy() && I->getOperand(0)->getType() == Src
1124 ? dyn_cast<LoadInst>(I->getOperand(0))
1125 : nullptr;
1126 const unsigned AS = Load ? Load->getPointerAddressSpace() : 0;
1127 const bool LoadMayWiden =
1128 Load && Load->getAlign() >= Align(4) &&
1131 (AS == AMDGPUAS::GLOBAL_ADDRESS &&
1132 Load->hasMetadata(LLVMContext::MD_invariant_load)));
1133 const bool LoadExtends = Load && Load->isSimple() && Load->hasOneUse() &&
1134 !LoadMayWiden &&
1137 SrcBits % 8 == 0 && !isPowerOf2_32(SrcBits);
1138 const unsigned ExtOps =
1139 UsesInt64 && SrcBits < 64 && !LoadExtends ? (IsSigned ? 2 : 1) : 0;
1140 if (FPTy->isBFloatTy()) {
1141 if (SrcBits < 8 || (SrcBits > 32 && !UsesInt64))
1142 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1143
1144 // Each integer is converted to f32 first.
1145 InstructionCost FloatCost =
1146 Scale(UsesInt64 ? ExtOps + (IsSigned ? 12 : 8) : 1);
1147 if (SrcBits < 32)
1148 FloatCost = getCastInstrCost(
1149 Opcode, Dst->getWithNewType(Type::getFloatTy(Dst->getContext())),
1150 Src, CCH, CostKind, I);
1151
1152 // Native rounding can convert a pair. With 16 bit instructions the
1153 // expansion extracts the low significand bit, adds the rounding bias,
1154 // preserves NaNs and shifts the result. Without gfx9 instructions the two
1155 // additions cannot use v_add3_u32.
1156 InstructionCost RoundCost =
1157 ST->hasBF16ConversionInsts()
1158 ? InstructionCost(divideCeil(NElts, 2)) * getFullRateInstrCost()
1159 : Scale(!ST->has16BitInsts() ? 1
1160 : ST->hasGFX9Insts() ? 6
1161 : 7);
1162 return FloatCost + RoundCost;
1163 }
1164
1165 // No instruction converts from a 64 bit integer.
1166 if (UsesInt64) {
1167 if (FPTy->isDoubleTy()) {
1168 // Two conversions, ldexp and add, all using the FP64 rate.
1169 return Scale(ExtOps, 4);
1170 }
1171 if (FPTy->isFloatTy())
1172 return Scale(ExtOps + (IsSigned ? 12 : 8));
1173 return Scale(ExtOps + (IsSigned ? 13 : 9));
1174 }
1175
1176 // A narrow vector source is converted lane by lane.
1177 if (SrcBits >= 8 && SrcBits < 32 && isa<FixedVectorType>(Src)) {
1178 if (FPTy->isDoubleTy())
1179 return Scale(1 + (SrcBits < 16 && IsSigned && ST->has16BitInsts()), 1);
1180 if (FPTy->isHalfTy()) {
1181 const InstructionCost PairCost =
1182 InstructionCost(NElts / 2) * getFullRateInstrCost();
1183 // Lanes wider than 16 bits, and every lane without 16 bit instructions,
1184 // are converted to f32 first. With the packed conversion each pair is
1185 // then converted at once. Otherwise each lane is converted, and without
1186 // real true16 each pair of halves is packed.
1187 if (!ST->has16BitInsts() || SrcBits > 16) {
1188 auto *FloatTy =
1189 FixedVectorType::get(Type::getFloatTy(Dst->getContext()), NElts);
1190 const InstructionCost FloatCost =
1191 getCastInstrCost(Opcode, FloatTy, Src, CCH, CostKind);
1192 if (ST->has16BitInsts() && ST->hasCvtPkF16F32Inst())
1193 return FloatCost + InstructionCost(divideCeil(NElts, 2)) *
1194 getFullRateInstrCost();
1195 const unsigned PackOps =
1196 !ST->has16BitInsts() ? 2 : !ST->useRealTrue16Insts();
1197 return FloatCost + Scale(1) + PackOps * PairCost;
1198 }
1199 // Each lane is converted from a 16 bit subword. Lanes narrower than 16
1200 // bits are extended lane by lane, except bytes with SDWA. Signed bytes
1201 // are sign extended a pair at a time. Real true16 reads the high
1202 // subword in place, so only signed lanes narrower than 16 bits pay per
1203 // pair. Otherwise wider lanes shift the high subword of each pair down
1204 // without SDWA, and each pair of halves is packed.
1205 const unsigned PerElt =
1206 1 + (SrcBits == 8 ? !ST->hasSDWA() : SrcBits < 16);
1207 const bool RealTrue16 = ST->useRealTrue16Insts();
1208 const unsigned PerPair =
1209 !RealTrue16 + (SrcBits == 8 || RealTrue16 ? SrcBits < 16 && IsSigned
1210 : !ST->hasSDWA());
1211 return Scale(PerElt) + PerPair * PairCost;
1212 }
1213 // An unsigned byte is converted straight out of its register.
1214 if (SrcBits == 8 && !IsSigned)
1215 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1216 if (SrcBits < 16 && !IsSigned)
1217 return Scale(2);
1218 unsigned PerElt = ST->hasSDWA() && SrcBits <= 16 ? 1 : 2;
1219 if (SrcBits < 16 && ST->has16BitInsts())
1220 ++PerElt;
1221 return Scale(PerElt);
1222 }
1223
1224 // A narrow scalar source is extended before the conversion. An unsigned
1225 // byte is converted straight out of its register, and a signed one with
1226 // SDWA. A source wider than a byte but narrower than 16 bits is masked
1227 // or sign extended first. Without 16 bit instructions a half result is
1228 // rounded from f32.
1229 if (SrcBits >= 8 && SrcBits < 32) {
1230 if (LoadExtends) {
1231 if (FPTy->isDoubleTy())
1232 return Scale(0, 1);
1233 return Scale(FPTy->isHalfTy() ? 2 : 1);
1234 }
1235 const bool Narrow = SrcBits > 8 && SrcBits < 16;
1236 const bool SignExtend16 = IsSigned && Narrow && ST->has16BitInsts();
1237 if (FPTy->isDoubleTy())
1238 return Scale(1 + 2 * SignExtend16, 1);
1239 if (SrcBits > 16)
1240 return Scale(FPTy->isHalfTy() ? 3 : 2);
1241 if (FPTy->isHalfTy() && ST->has16BitInsts())
1242 return Scale(Narrow ? (IsSigned ? 3 : 2)
1243 : SrcBits == 8 && !ST->hasSDWA() ? 2
1244 : 1);
1245 const InstructionCost FloatCost =
1246 SignExtend16 ? Scale(ST->hasSDWA() ? 3 : 4)
1247 : Narrow ? Scale(2)
1248 : SrcBits == 8 && !IsSigned ? Scale(1)
1249 : Scale(ST->hasSDWA() ? 1 : 2);
1250 return FPTy->isHalfTy() ? FloatCost + Scale(1) : FloatCost;
1251 }
1252
1253 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1254 }
1255
1256 // No instruction converts to a 64 bit integer.
1257 if (UsesInt64) {
1258 const bool IsSigned64 = IsSigned || (DstBits < 64 && NElts == 1);
1259 if (FPTy->isDoubleTy()) {
1260 // With native trunc/floor there are six FP64 operations. The expanded
1261 // rounding sequence has seven, plus integer operations and constants.
1262 return ST->haveRoundOpsF64() ? Scale(1, 6) : Scale(22, 7);
1263 }
1264 // The f32 expansion has one fma, which is quarter rate without fast FMA.
1265 const InstructionCost SlowFMACost =
1266 ST->hasFastFMAF32() ? 0
1267 : NElts * (getQuarterRateInstrCost(CostKind) -
1268 getFullRateInstrCost());
1269 if (FPTy->isFloatTy())
1270 return Scale(IsSigned64 ? 13 : 6) + SlowFMACost;
1271 if (FPTy->isBFloatTy()) {
1272 // Unlike half, bf16 does not fit in i32. Extend to f32 and use the full
1273 // i64 expansion.
1274 return Scale(1 + (IsSigned64 ? 13 : 6)) + SlowFMACost;
1275 }
1276 return Scale(3);
1277 }
1278
1279 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1280}
1281
1284 std::optional<FastMathFlags> FMF,
1285 TTI::TargetCostKind CostKind) const {
1287 return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
1288
1289 // An add or xor reduction over a vector of i1 becomes a bit count over the
1290 // packed mask; the generic model prices a shuffle tree and misses that.
1291 if (Opcode == Instruction::Add || Opcode == Instruction::Xor) {
1292 if (std::optional<unsigned> Elts = getNumberOfPackedMaskElts(Ty))
1293 return InstructionCost(MaskPackCostPerElt) * *Elts *
1294 getFullRateInstrCost();
1295 }
1296
1297 EVT OrigTy = TLI->getValueType(DL, Ty);
1298
1299 // Computes cost on targets that have packed math instructions(which support
1300 // 16-bit types only).
1301 if (!ST->hasVOP3PInsts() || OrigTy.getScalarSizeInBits() != 16)
1302 return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
1303
1304 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
1305 return LT.first * getFullRateInstrCost();
1306}
1307
1310 FastMathFlags FMF,
1311 TTI::TargetCostKind CostKind) const {
1312 EVT OrigTy = TLI->getValueType(DL, Ty);
1313
1314 // Computes cost on targets that have packed math instructions(which support
1315 // 16-bit types only).
1316 if (!ST->hasVOP3PInsts() || OrigTy.getScalarSizeInBits() != 16)
1317 return BaseT::getMinMaxReductionCost(IID, Ty, FMF, CostKind);
1318
1319 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
1320 return LT.first * getHalfRateInstrCost(CostKind);
1321}
1322
1324 unsigned Opcode, Type *ValTy, TTI::TargetCostKind CostKind, unsigned Index,
1325 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
1326 switch (Opcode) {
1327 case Instruction::ExtractElement:
1328 case Instruction::InsertElement: {
1329 TypeSize EltSize =
1330 DL.getTypeSizeInBits(cast<VectorType>(ValTy)->getElementType());
1331 // Dynamic indexing isn't free and is best avoided.
1332 if (Index == ~0u)
1333 return 2;
1334 if (EltSize < 32) {
1335 if (EltSize == 16 && Index == 0 && ST->has16BitInsts())
1336 return 0;
1337 // Inserts of booleans are free.
1338 // TODO: Extracts are free too.
1339 if (EltSize == 1 && Opcode == Instruction::InsertElement)
1341 // Extract element sequences of consecutive i8 values that match a
1342 // register size are free most likely. It is not possible to know
1343 // if this extract is part of a consecutive sequence so this may
1344 // apply more generally.
1345 if (Opcode == Instruction::ExtractElement && EltSize == 8) {
1346 if (auto *FVTy = dyn_cast<FixedVectorType>(ValTy)) {
1347 unsigned NumElts = FVTy->getNumElements();
1348 if (NumElts >= 4 && isPowerOf2_32(NumElts))
1349 return 0;
1350 }
1351 }
1352 return BaseT::getVectorInstrCost(Opcode, ValTy, CostKind, Index, Op0, Op1,
1353 VIC);
1354 }
1355
1356 // Packed f32 pair formation for v_pk_*_f32. A constant-index insert writes
1357 // one subregister, so a lane holding a computed value costs at most one
1358 // v_mov_b32 at any width. A loaded lane lands in place, and arguments and
1359 // constants are already in a register, so both are free. SLP prices a
1360 // buildvector root with the insertelements themselves as Op1, and those
1361 // lanes need no packing either. Only throughput sees the move; size-based
1362 // users such as the inliner and the unroller keep inserts free.
1363 auto *VecTy = dyn_cast<FixedVectorType>(ValTy);
1364 const auto *InsertedInst = dyn_cast_or_null<Instruction>(Op1);
1365 if (Opcode == Instruction::InsertElement && EltSize == 32 &&
1366 CostKind == TTI::TCK_RecipThroughput && ST->hasAnyPackedFP32Ops() &&
1367 InsertedInst && VecTy && VecTy->getElementType()->isFloatTy() &&
1368 !isa<LoadInst, InsertElementInst>(InsertedInst))
1369 return getFullRateInstrCost();
1370
1371 // Extracts are just reads of a subregister, so are free. Inserts are
1372 // considered free because we don't want to have any cost for scalarizing
1373 // operations, and we don't have to copy into a different register class.
1374 return 0;
1375 }
1376 default:
1377 return BaseT::getVectorInstrCost(Opcode, ValTy, CostKind, Index, Op0, Op1,
1378 VIC);
1379 }
1380}
1381
1382/// Analyze if the results of inline asm are divergent. If \p Indices is empty,
1383/// this is analyzing the collective result of all output registers. Otherwise,
1384/// this is only querying a specific result index if this returns multiple
1385/// registers in a struct.
1387 const CallBase *CB, ArrayRef<unsigned> Indices) const {
1388 // TODO: Handle complex extract indices
1389 if (Indices.size() > 1)
1390 return true;
1391
1392 const DataLayout &DL = CB->getDataLayout();
1393 const SIRegisterInfo *TRI = ST->getRegisterInfo();
1394 TargetLowering::AsmOperandInfoVector TargetConstraints =
1395 TLI->ParseConstraints(DL, ST->getRegisterInfo(), *CB);
1396
1397 const int TargetOutputIdx = Indices.empty() ? -1 : Indices[0];
1398
1399 int OutputIdx = 0;
1400 for (auto &TC : TargetConstraints) {
1401 if (TC.Type != InlineAsm::isOutput)
1402 continue;
1403
1404 // Skip outputs we don't care about.
1405 if (TargetOutputIdx != -1 && TargetOutputIdx != OutputIdx++)
1406 continue;
1407
1408 TLI->ComputeConstraintToUse(TC, SDValue());
1409
1410 const TargetRegisterClass *RC = TLI->getRegForInlineAsmConstraint(
1411 TRI, TC.ConstraintCode, TC.ConstraintVT).second;
1412
1413 // For AGPR constraints null is returned on subtargets without AGPRs, so
1414 // assume divergent for null.
1415 if (!RC || !TRI->isSGPRClass(RC))
1416 return true;
1417 }
1418
1419 return false;
1420}
1421
1423 const IntrinsicInst *ReadReg) const {
1424 Metadata *MD =
1425 cast<MetadataAsValue>(ReadReg->getArgOperand(0))->getMetadata();
1427 cast<MDString>(cast<MDNode>(MD)->getOperand(0))->getString();
1428
1429 // Special case registers that look like VCC.
1430 MVT VT = MVT::getVT(ReadReg->getType());
1431 if (VT == MVT::i1)
1432 return true;
1433
1434 // Special case scalar registers that start with 'v'.
1435 if (RegName.starts_with("vcc") || RegName.empty())
1436 return false;
1437
1438 // VGPR or AGPR is divergent. There aren't any specially named vector
1439 // registers.
1440 return RegName[0] == 'v' || RegName[0] == 'a';
1441}
1442
1443/// \returns true if the result of the value could potentially be
1444/// different across workitems in a wavefront.
1445bool GCNTTIImpl::isSourceOfDivergence(const Value *V) const {
1446 if (const Argument *A = dyn_cast<Argument>(V))
1448
1449 // Loads from the private and flat address spaces are divergent, because
1450 // threads can execute the load instruction with the same inputs and get
1451 // different results.
1452 //
1453 // All other loads are not divergent, because if threads issue loads with the
1454 // same arguments, they will always get the same result.
1455 if (const LoadInst *Load = dyn_cast<LoadInst>(V))
1456 return Load->getPointerAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS ||
1457 Load->getPointerAddressSpace() == AMDGPUAS::FLAT_ADDRESS;
1458
1459 // Atomics are divergent because they are executed sequentially: when an
1460 // atomic operation refers to the same address in each thread, then each
1461 // thread after the first sees the value written by the previous thread as
1462 // original value.
1464 return true;
1465
1467 Intrinsic::ID IID = Intrinsic->getIntrinsicID();
1468 switch (IID) {
1469 case Intrinsic::read_register:
1471 case Intrinsic::amdgcn_workitem_id_y:
1472 case Intrinsic::amdgcn_workitem_id_z: {
1473 const Function *F = Intrinsic->getFunction();
1474 bool HasUniformYZ =
1475 ST->hasWavefrontsEvenlySplittingXDim(*F, /*RequiresUniformYZ=*/true);
1476 std::optional<unsigned> ThisDimSize = ST->getReqdWorkGroupSize(
1477 *F, IID == Intrinsic::amdgcn_workitem_id_y ? 1 : 2);
1478 return !HasUniformYZ && (!ThisDimSize || *ThisDimSize != 1);
1479 }
1480 default:
1482 }
1483 }
1484
1485 // Assume all function calls are a source of divergence.
1486 if (const CallBase *CB = dyn_cast<CallBase>(V)) {
1487 if (CB->isInlineAsm())
1489 return true;
1490 }
1491
1492 // Assume all function calls are a source of divergence.
1493 if (isa<InvokeInst>(V))
1494 return true;
1495
1496 // If the target supports globally addressable scratch, the mapping from
1497 // scratch memory to the flat aperture changes therefore an address space cast
1498 // is no longer uniform.
1499 if (auto *CastI = dyn_cast<AddrSpaceCastInst>(V)) {
1500 return CastI->getSrcAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS &&
1501 CastI->getDestAddressSpace() == AMDGPUAS::FLAT_ADDRESS &&
1502 ST->hasGloballyAddressableScratch();
1503 }
1504
1505 return false;
1506}
1507
1508bool GCNTTIImpl::isAlwaysUniform(const Value *V) const {
1509 if (const IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(V))
1510 return AMDGPU::isIntrinsicAlwaysUniform(Intrinsic->getIntrinsicID());
1511
1512 if (const CallBase *CB = dyn_cast<CallBase>(V)) {
1513 if (CB->isInlineAsm())
1515 return false;
1516 }
1517
1518 // In most cases TID / wavefrontsize is uniform.
1519 //
1520 // However, if a kernel has uneven dimesions we can have a value of
1521 // workitem-id-x divided by the wavefrontsize non-uniform. For example
1522 // dimensions (65, 2) will have workitems with address (64, 0) and (0, 1)
1523 // packed into a same wave which gives 1 and 0 after the division by 64
1524 // respectively.
1525 //
1526 // The X dimension doesn't reset within a wave if either both the Y
1527 // and Z dimensions are of length 1, or if the X dimension's required
1528 // size is a power of 2. Note, however, if the X dimension's maximum
1529 // size is a power of 2 < the wavefront size, division by the wavefront
1530 // size is guaranteed to yield 0, so this is also a no-reset case.
1531 bool XDimDoesntResetWithinWaves = false;
1532 if (auto *I = dyn_cast<Instruction>(V)) {
1533 const Function *F = I->getFunction();
1534 XDimDoesntResetWithinWaves = ST->hasWavefrontsEvenlySplittingXDim(*F);
1535 }
1536 using namespace llvm::PatternMatch;
1537 uint64_t C;
1538 auto MatchTidXCall = m_Intrinsic<Intrinsic::amdgcn_workitem_id_x>();
1539 auto MaybeMaskedTidX =
1540 m_CombineOr(m_c_And(MatchTidXCall, m_Constant()), MatchTidXCall);
1541 auto MaybeCastTidX = m_CastOrSelf(MaybeMaskedTidX);
1542 auto MaybeMaskedCastTidX =
1543 m_CombineOr(m_c_And(MaybeCastTidX, m_Constant()), MaybeCastTidX);
1544 if (match(V, m_LShr(MaybeMaskedCastTidX, m_ConstantInt(C))))
1545 return C >= ST->getWavefrontSizeLog2() && XDimDoesntResetWithinWaves;
1546
1547 Constant *Mask;
1548 if (match(V, m_c_And(
1550 m_Constant(Mask)))) {
1551 return computeKnownBits(Mask, DL).countMinTrailingZeros() >=
1552 ST->getWavefrontSizeLog2() &&
1553 XDimDoesntResetWithinWaves;
1554 }
1555
1556 const ExtractValueInst *ExtValue = dyn_cast<ExtractValueInst>(V);
1557 if (!ExtValue)
1558 return false;
1559
1560 const CallBase *CB = dyn_cast<CallBase>(ExtValue->getOperand(0));
1561 if (!CB)
1562 return false;
1563
1564 if (const IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(CB)) {
1565 switch (Intrinsic->getIntrinsicID()) {
1566 default:
1567 return false;
1568 case Intrinsic::amdgcn_if:
1569 case Intrinsic::amdgcn_else: {
1570 ArrayRef<unsigned> Indices = ExtValue->getIndices();
1571 return Indices.size() == 1 && Indices[0] == 1;
1572 }
1573 }
1574 }
1575
1576 // If we have inline asm returning mixed SGPR and VGPR results, we inferred
1577 // divergent for the overall struct return. We need to override it in the
1578 // case we're extracting an SGPR component here.
1579 if (CB->isInlineAsm())
1580 return !isInlineAsmSourceOfDivergence(CB, ExtValue->getIndices());
1581
1582 return false;
1583}
1584
1586 Intrinsic::ID IID) const {
1587 switch (IID) {
1588 case Intrinsic::amdgcn_is_shared:
1589 case Intrinsic::amdgcn_is_private:
1590 case Intrinsic::amdgcn_flat_atomic_fmax_num:
1591 case Intrinsic::amdgcn_flat_atomic_fmin_num:
1592 case Intrinsic::amdgcn_load_to_lds:
1593 case Intrinsic::amdgcn_make_buffer_rsrc:
1594 OpIndexes.push_back(0);
1595 return true;
1596 default:
1597 return false;
1598 }
1599}
1600
1602 Value *OldV,
1603 Value *NewV) const {
1604 auto IntrID = II->getIntrinsicID();
1605 switch (IntrID) {
1606 case Intrinsic::amdgcn_is_shared:
1607 case Intrinsic::amdgcn_is_private: {
1608 unsigned TrueAS = IntrID == Intrinsic::amdgcn_is_shared ?
1610 unsigned NewAS = NewV->getType()->getPointerAddressSpace();
1611 LLVMContext &Ctx = NewV->getType()->getContext();
1612 ConstantInt *NewVal = (TrueAS == NewAS) ?
1614 return NewVal;
1615 }
1616 case Intrinsic::amdgcn_flat_atomic_fmax_num:
1617 case Intrinsic::amdgcn_flat_atomic_fmin_num: {
1618 Type *DestTy = II->getType();
1619 Type *SrcTy = NewV->getType();
1620 unsigned NewAS = SrcTy->getPointerAddressSpace();
1622 return nullptr;
1623 Module *M = II->getModule();
1625 M, II->getIntrinsicID(), {DestTy, SrcTy, DestTy});
1626 II->setArgOperand(0, NewV);
1627 II->setCalledFunction(NewDecl);
1628 return II;
1629 }
1630 case Intrinsic::amdgcn_load_to_lds: {
1631 Type *SrcTy = NewV->getType();
1632 Module *M = II->getModule();
1633 Function *NewDecl =
1634 Intrinsic::getOrInsertDeclaration(M, II->getIntrinsicID(), {SrcTy});
1635 II->setArgOperand(0, NewV);
1636 II->setCalledFunction(NewDecl);
1637 return II;
1638 }
1639 case Intrinsic::amdgcn_make_buffer_rsrc: {
1640 Type *SrcTy = NewV->getType();
1641 Type *DstTy = II->getType();
1642 Type *NumRecordsTy = II->getArgOperand(2)->getType();
1643 Module *M = II->getModule();
1645 M, II->getIntrinsicID(), {DstTy, SrcTy, NumRecordsTy});
1646 II->setArgOperand(0, NewV);
1647 II->setCalledFunction(NewDecl);
1648 return II;
1649 }
1650 default:
1651 return nullptr;
1652 }
1653}
1654
1656 TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
1657 TTI::TargetCostKind CostKind, ArrayRef<int> Mask, int Index,
1658 VectorType *SubTp, ArrayRef<const Value *> Args, const Instruction *CtxI,
1659 TTI::VectorInstrContext VIC) const {
1660 if (!isa<FixedVectorType>(SrcTy))
1661 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
1662 SubTp);
1663
1664 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1665
1666 TypeSize ScalarSize = DL.getTypeSizeInBits(SrcTy->getElementType());
1667
1668 // A v_pk_*_f32 operand is an aligned register pair. A lane already in its
1669 // half of a source pair is read in place, and a splat of the low half is an
1670 // op_sel_hi. Every other lane costs a v_mov_b32 to move it into place.
1671 if (ScalarSize == 32 && CostKind == TTI::TCK_RecipThroughput &&
1672 ST->hasAnyPackedFP32Ops() && SrcTy->getElementType()->isFloatTy() &&
1673 !Mask.empty()) {
1674 const int NumSrcElts = cast<FixedVectorType>(SrcTy)->getNumElements();
1675 // Source pairs of the second operand are numbered after the first.
1676 auto GetPair = [&](int Idx) {
1677 return Idx < NumSrcElts ? Idx / 2 : NumSrcElts + (Idx - NumSrcElts) / 2;
1678 };
1679 auto GetHalf = [&](int Idx) {
1680 return Idx < NumSrcElts ? Idx % 2 : (Idx - NumSrcElts) % 2;
1681 };
1682 unsigned Cost = 0;
1683 for (unsigned DstIdx = 0; DstIdx < Mask.size(); DstIdx += 2) {
1684 const int Lo = Mask[DstIdx];
1685 const int Hi =
1686 DstIdx + 1 < Mask.size() ? Mask[DstIdx + 1] : PoisonMaskElem;
1687 const bool LoInPlace = Lo != PoisonMaskElem && GetHalf(Lo) == 0;
1688 const bool HiInPlace = Hi != PoisonMaskElem && GetHalf(Hi) == 1;
1689 if (Lo != PoisonMaskElem && Lo == Hi && LoInPlace)
1690 continue;
1691 if (LoInPlace && HiInPlace)
1692 Cost += GetPair(Lo) != GetPair(Hi);
1693 else
1694 Cost += (Lo != PoisonMaskElem && !LoInPlace) +
1695 (Hi != PoisonMaskElem && !HiInPlace);
1696 }
1697 return Cost;
1698 }
1699
1700 if (ST->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS &&
1701 (ScalarSize == 16 || ScalarSize == 8)) {
1702 // Larger vector widths may require additional instructions, but are
1703 // typically cheaper than scalarized versions.
1704 //
1705 // We assume that shuffling at a register granularity can be done for free.
1706 // This is not true for vectors fed into memory instructions, but it is
1707 // effectively true for all other shuffling. The emphasis of the logic here
1708 // is to assist generic transform in cleaning up / canonicalizing those
1709 // shuffles.
1710
1711 // With op_sel VOP3P instructions freely can access the low half or high
1712 // half of a register, so any swizzle of two elements is free.
1713 if (auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcTy)) {
1714 unsigned NumSrcElts = SrcVecTy->getNumElements();
1715 if (ST->hasVOP3PInsts() && ScalarSize == 16 && NumSrcElts == 2 &&
1716 (Kind == TTI::SK_Broadcast || Kind == TTI::SK_Reverse ||
1717 Kind == TTI::SK_PermuteSingleSrc))
1718 return 0;
1719 }
1720
1721 unsigned EltsPerReg = 32 / static_cast<unsigned>(ScalarSize);
1722 switch (Kind) {
1723 case TTI::SK_Broadcast:
1724 // A single v_perm_b32 can be re-used for all destination registers.
1725 return 1;
1726 case TTI::SK_Reverse:
1727 // One instruction per register.
1728 if (auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy))
1729 return divideCeil(DstVecTy->getNumElements(), EltsPerReg);
1732 if (Index % EltsPerReg == 0)
1733 return 0; // Shuffling at register granularity
1734 if (auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy))
1735 return divideCeil(DstVecTy->getNumElements(), EltsPerReg);
1738 auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy);
1739 if (!DstVecTy)
1741 unsigned NumDstElts = DstVecTy->getNumElements();
1742 unsigned NumInsertElts = cast<FixedVectorType>(SubTp)->getNumElements();
1743 unsigned EndIndex = Index + NumInsertElts;
1744 unsigned BeginSubIdx = Index % EltsPerReg;
1745 unsigned EndSubIdx = EndIndex % EltsPerReg;
1747
1748 if (BeginSubIdx != 0) {
1749 // Need to shift the inserted vector into place. The cost is the number
1750 // of destination registers overlapped by the inserted vector.
1751 Cost = divideCeil(EndIndex, EltsPerReg) - (Index / EltsPerReg);
1752 }
1753
1754 // If the last register overlap is partial, there may be three source
1755 // registers feeding into it; that takes an extra instruction.
1756 if (EndIndex < NumDstElts && BeginSubIdx < EndSubIdx)
1757 Cost += 1;
1758
1759 return Cost;
1760 }
1761 case TTI::SK_Splice: {
1762 auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy);
1763 if (!DstVecTy)
1765 unsigned NumElts = DstVecTy->getNumElements();
1766 assert(NumElts == cast<FixedVectorType>(SrcTy)->getNumElements());
1767 // Determine the sub-region of the result vector that requires
1768 // sub-register shuffles / mixing.
1769 unsigned EltsFromLHS = NumElts - Index;
1770 bool LHSIsAligned = (Index % EltsPerReg) == 0;
1771 bool RHSIsAligned = (EltsFromLHS % EltsPerReg) == 0;
1772 if (LHSIsAligned && RHSIsAligned)
1773 return 0;
1774 if (LHSIsAligned && !RHSIsAligned)
1775 return divideCeil(NumElts, EltsPerReg) - (EltsFromLHS / EltsPerReg);
1776 if (!LHSIsAligned && RHSIsAligned)
1777 return divideCeil(EltsFromLHS, EltsPerReg);
1778 return divideCeil(NumElts, EltsPerReg);
1779 }
1780 default:
1781 break;
1782 }
1783
1784 if (!Mask.empty()) {
1785 unsigned NumSrcElts = cast<FixedVectorType>(SrcTy)->getNumElements();
1786
1787 // Generically estimate the cost by assuming that each destination
1788 // register is derived from sources via v_perm_b32 instructions if it
1789 // can't be copied as-is.
1790 //
1791 // For each destination register, derive the cost of obtaining it based
1792 // on the number of source registers that feed into it.
1794 for (unsigned DstIdx = 0; DstIdx < Mask.size(); DstIdx += EltsPerReg) {
1796 bool Aligned = true;
1797 for (unsigned I = 0; I < EltsPerReg && DstIdx + I < Mask.size(); ++I) {
1798 int SrcIdx = Mask[DstIdx + I];
1799 if (SrcIdx == -1)
1800 continue;
1801 int Reg;
1802 if (SrcIdx < (int)NumSrcElts) {
1803 Reg = SrcIdx / EltsPerReg;
1804 if (SrcIdx % EltsPerReg != I)
1805 Aligned = false;
1806 } else {
1807 Reg = NumSrcElts + (SrcIdx - NumSrcElts) / EltsPerReg;
1808 if ((SrcIdx - NumSrcElts) % EltsPerReg != I)
1809 Aligned = false;
1810 }
1811 if (!llvm::is_contained(Regs, Reg))
1812 Regs.push_back(Reg);
1813 }
1814 if (Regs.size() >= 2)
1815 Cost += Regs.size() - 1;
1816 else if (!Aligned)
1817 Cost += 1;
1818 }
1819 return Cost;
1820 }
1821 }
1822
1823 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
1824 SubTp);
1825}
1826
1827/// Whether it is profitable to sink the operands of an
1828/// Instruction I to the basic block of I.
1829/// This helps using several modifiers (like abs and neg) more often.
1831 SmallVectorImpl<Use *> &Ops) const {
1832 using namespace PatternMatch;
1833
1834 // The cost model prices this fmul as free assuming it fuses with its
1835 // fadd/fsub user, which needs them in one block. Sink a stranded
1836 // loop-invariant fmul back to the user when they would fuse. Single use only,
1837 // so this stays a move.
1838 if (I->getOpcode() == Instruction::FAdd ||
1839 I->getOpcode() == Instruction::FSub) {
1840 const Instruction *FMul = getFusedFMul(*TLI, I->getType(), I);
1841 if (FMul && FMul->getParent() != I->getParent())
1842 Ops.push_back(&I->getOperandUse(I->getOperand(0) == FMul ? 0 : 1));
1843 }
1844
1845 for (auto &Op : I->operands()) {
1846 // Ensure we are not already sinking this operand.
1847 if (any_of(Ops, [&](Use *U) { return U->get() == Op.get(); }))
1848 continue;
1849
1850 // TODO: Confirm whether m_FNegOrFSubNegZero is correct.
1851 if (match(&Op, m_FAbs(m_Value())) ||
1853 Ops.push_back(&Op);
1854 continue;
1855 }
1856
1857 // Check for zero-cost multiple use InsertElement/ExtractElement
1858 // instructions
1859 if (Instruction *OpInst = dyn_cast<Instruction>(Op.get())) {
1860 if (OpInst->getType()->isVectorTy() && OpInst->getNumOperands() > 1) {
1861 Instruction *VecOpInst = dyn_cast<Instruction>(OpInst->getOperand(0));
1862 if (VecOpInst && VecOpInst->hasOneUse())
1863 continue;
1864
1865 if (getVectorInstrCost(OpInst->getOpcode(), OpInst->getType(),
1867 OpInst->getOperand(0),
1868 OpInst->getOperand(1)) == 0) {
1869 Ops.push_back(&Op);
1870 continue;
1871 }
1872 }
1873 }
1874
1875 if (auto *Shuffle = dyn_cast<ShuffleVectorInst>(Op.get())) {
1876
1877 TypeSize EltSize = DL.getTypeSizeInBits(
1878 cast<VectorType>(Shuffle->getType())->getElementType());
1879
1880 // For i32 (or greater) shufflevectors, these will be lowered into a
1881 // series of insert / extract elements, which will be coalesced away.
1882 if (EltSize < 16 || !ST->has16BitInsts())
1883 continue;
1884
1885 int NumSubElts, SubIndex;
1886 if (Shuffle->changesLength()) {
1887 if (Shuffle->increasesLength() && Shuffle->isIdentityWithPadding()) {
1888 Ops.push_back(&Op);
1889 continue;
1890 }
1891
1892 if ((Shuffle->isExtractSubvectorMask(SubIndex) ||
1893 Shuffle->isInsertSubvectorMask(NumSubElts, SubIndex)) &&
1894 !(SubIndex & 0x1)) {
1895 Ops.push_back(&Op);
1896 continue;
1897 }
1898 }
1899
1900 if (Shuffle->isReverse() || Shuffle->isZeroEltSplat() ||
1901 Shuffle->isSingleSource()) {
1902 Ops.push_back(&Op);
1903 continue;
1904 }
1905 }
1906 }
1907
1908 return !Ops.empty();
1909}
1910
1912 const Function *Callee) const {
1913 const TargetMachine &TM = getTLI()->getTargetMachine();
1914 const GCNSubtarget *CallerST
1915 = static_cast<const GCNSubtarget *>(TM.getSubtargetImpl(*Caller));
1916 const GCNSubtarget *CalleeST
1917 = static_cast<const GCNSubtarget *>(TM.getSubtargetImpl(*Callee));
1918
1919 if (!BaseT::areInlineCompatible(Caller, Callee))
1920 return false;
1921
1922 // FIXME: dx10_clamp can just take the caller setting, but there seems to be
1923 // no way to support merge for backend defined attributes.
1924 SIModeRegisterDefaults CallerMode(*Caller, *CallerST);
1925 SIModeRegisterDefaults CalleeMode(*Callee, *CalleeST);
1926 if (!CallerMode.isInlineCompatible(CalleeMode))
1927 return false;
1928
1929 if (Callee->hasFnAttribute(Attribute::AlwaysInline) ||
1930 Callee->hasFnAttribute(Attribute::InlineHint))
1931 return true;
1932
1933 // Hack to make compile times reasonable.
1934 if (InlineMaxBB) {
1935 // Single BB does not increase total BB amount.
1936 if (Callee->size() == 1)
1937 return true;
1938 size_t BBSize = Caller->size() + Callee->size() - 1;
1939 if (BBSize > InlineMaxBB) {
1940 LLVM_DEBUG(dbgs() << "AMDGPU inline max-BB rejected inlining "
1941 << Callee->getName() << " into " << Caller->getName()
1942 << ": caller BBs=" << Caller->size() << ", callee BBs="
1943 << Callee->size() << ", combined BBs=" << BBSize
1944 << ", max BBs=" << InlineMaxBB << '\n');
1945 return false;
1946 }
1947 }
1948
1949 return true;
1950}
1951
1953 const SITargetLowering *TLI,
1954 const GCNTTIImpl *TTIImpl) {
1955 const int NrOfSGPRUntilSpill = 26;
1956 const int NrOfVGPRUntilSpill = 32;
1957
1958 const DataLayout &DL = TTIImpl->getDataLayout();
1959
1960 unsigned adjustThreshold = 0;
1961 int SGPRsInUse = 0;
1962 int VGPRsInUse = 0;
1963 for (const Use &A : CB->args()) {
1964 SmallVector<EVT, 4> ValueVTs;
1965 ComputeValueVTs(*TLI, DL, A.get()->getType(), ValueVTs);
1966 for (auto ArgVT : ValueVTs) {
1967 unsigned CCRegNum = TLI->getNumRegistersForCallingConv(
1968 CB->getContext(), CB->getCallingConv(), ArgVT);
1970 SGPRsInUse += CCRegNum;
1971 else
1972 VGPRsInUse += CCRegNum;
1973 }
1974 }
1975
1976 // The cost of passing function arguments through the stack:
1977 // 1 instruction to put a function argument on the stack in the caller.
1978 // 1 instruction to take a function argument from the stack in callee.
1979 // 1 instruction is explicitly take care of data dependencies in callee
1980 // function.
1981 InstructionCost ArgStackCost(1);
1982 ArgStackCost += const_cast<GCNTTIImpl *>(TTIImpl)->getMemoryOpCost(
1983 Instruction::Store, Type::getInt32Ty(CB->getContext()), Align(4),
1985 ArgStackCost += const_cast<GCNTTIImpl *>(TTIImpl)->getMemoryOpCost(
1986 Instruction::Load, Type::getInt32Ty(CB->getContext()), Align(4),
1988
1989 // The penalty cost is computed relative to the cost of instructions and does
1990 // not model any storage costs.
1991 adjustThreshold += static_cast<unsigned>(
1992 std::max(0, SGPRsInUse - NrOfSGPRUntilSpill) * ArgStackCost.getValue() *
1994 adjustThreshold += static_cast<unsigned>(
1995 std::max(0, VGPRsInUse - NrOfVGPRUntilSpill) * ArgStackCost.getValue() *
1997 return adjustThreshold;
1998}
1999
2001 const DataLayout &DL) {
2002 // If we have a pointer to a private array passed into a function
2003 // it will not be optimized out, leaving scratch usage.
2004 // This function calculates the total size in bytes of the memory that would
2005 // end in scratch if the call was not inlined.
2006 TypeSize AllocaSize = TypeSize::getFixed(0);
2008 for (Value *PtrArg : CB->args()) {
2009 PointerType *Ty = dyn_cast<PointerType>(PtrArg->getType());
2010 if (!Ty)
2011 continue;
2012
2013 unsigned AddrSpace = Ty->getAddressSpace();
2014 if (AddrSpace != AMDGPUAS::FLAT_ADDRESS &&
2015 AddrSpace != AMDGPUAS::PRIVATE_ADDRESS)
2016 continue;
2017
2019 if (!AI || !AI->isStaticAlloca() || !AIVisited.insert(AI).second)
2020 continue;
2021
2022 if (auto Size = AI->getAllocationSize(DL))
2023 AllocaSize += *Size;
2024 }
2025 return AllocaSize;
2026}
2027
2032
2034 unsigned Threshold = adjustInliningThresholdUsingCallee(CB, TLI, this);
2035
2036 // Private object passed as arguments may end up in scratch usage if the call
2037 // is not inlined. Increase the inline threshold to promote inlining.
2038 TypeSize AllocaSize = getCallArgsTotalAllocaSize(CB, DL);
2039 if (AllocaSize.getFixedValue() > 0)
2040 Threshold += ArgAllocaCost;
2041 return Threshold;
2042}
2043
2045 const AllocaInst *AI) const {
2046
2047 // Below the cutoff, assume that the private memory objects would be
2048 // optimized
2049 auto AllocaSize = getCallArgsTotalAllocaSize(CB, DL).getFixedValue();
2050 if (AllocaSize <= ArgAllocaCutoff)
2051 return 0;
2052
2053 // Above the cutoff, we give a cost to each private memory object
2054 // depending its size. If the array can be optimized by SROA this cost is not
2055 // added to the total-cost in the inliner cost analysis.
2056 //
2057 // We choose the total cost of the alloca such that their sum cancels the
2058 // bonus given in the threshold (ArgAllocaCost).
2059 //
2060 // Cost_Alloca_0 + ... + Cost_Alloca_N == ArgAllocaCost
2061 //
2062 // Awkwardly, the ArgAllocaCost bonus is multiplied by threshold-multiplier,
2063 // the single-bb bonus and the vector-bonus.
2064 //
2065 // We compensate the first two multipliers, by repeating logic from the
2066 // inliner-cost in here. The vector-bonus is 0 on AMDGPU.
2067 static_assert(InlinerVectorBonusPercent == 0, "vector bonus assumed to be 0");
2068 unsigned Threshold = ArgAllocaCost * getInliningThresholdMultiplier();
2069
2070 bool SingleBB = none_of(*CB->getCalledFunction(), [](const BasicBlock &BB) {
2071 return BB.getTerminator()->getNumSuccessors() > 1;
2072 });
2073 if (SingleBB) {
2074 Threshold += Threshold / 2;
2075 }
2076
2077 auto ArgAllocaSize = AI->getAllocationSize(DL);
2078 if (!ArgAllocaSize)
2079 return 0;
2080
2081 // Attribute the bonus proportionally to the alloca size
2082 unsigned AllocaThresholdBonus = static_cast<unsigned>(
2083 (Threshold * ArgAllocaSize->getFixedValue()) / AllocaSize);
2084
2085 return AllocaThresholdBonus;
2086}
2087
2090 OptimizationRemarkEmitter *ORE) const {
2091 CommonTTI.getUnrollingPreferences(L, SE, UP, ORE);
2092}
2093
2095 TTI::PeelingPreferences &PP) const {
2096 CommonTTI.getPeelingPreferences(L, SE, PP);
2097}
2098
2099int GCNTTIImpl::getTransInstrCost(TTI::TargetCostKind CostKind) const {
2100 return getQuarterRateInstrCost(CostKind);
2101}
2102
2103int GCNTTIImpl::get64BitInstrCost(TTI::TargetCostKind CostKind) const {
2104 return ST->hasFullRate64Ops()
2105 ? getFullRateInstrCost()
2106 : ST->hasHalfRate64Ops() ? getHalfRateInstrCost(CostKind)
2107 : getQuarterRateInstrCost(CostKind);
2108}
2109
2110std::pair<InstructionCost, MVT>
2111GCNTTIImpl::getTypeLegalizationCost(Type *Ty) const {
2112 std::pair<InstructionCost, MVT> Cost = BaseT::getTypeLegalizationCost(Ty);
2113 auto Size = DL.getTypeSizeInBits(Ty);
2114 // Maximum load or store can handle 8 dwords for scalar and 4 for
2115 // vector ALU. Let's assume anything above 8 dwords is expensive
2116 // even if legal.
2117 if (Size <= 256)
2118 return Cost;
2119
2120 Cost.first += (Size + 255) / 256;
2121 return Cost;
2122}
2123
2125 if (ST->hasVmemPrefInsts() || ST->hasSmemPrefetchInsts())
2126 return ST->getDataCacheLineSize();
2127 return 0;
2128}
2129
2131 return ST->hasPrefetch() ? 128 : 0;
2132}
2133
2136}
2137
2139 const Function &F,
2140 SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const {
2142 LB.push_back({"amdgpu-max-num-workgroups[0]", MaxNumWorkgroups[0]});
2143 LB.push_back({"amdgpu-max-num-workgroups[1]", MaxNumWorkgroups[1]});
2144 LB.push_back({"amdgpu-max-num-workgroups[2]", MaxNumWorkgroups[2]});
2145 std::pair<unsigned, unsigned> FlatWorkGroupSize =
2146 ST->getFlatWorkGroupSizes(F);
2147 LB.push_back({"amdgpu-flat-work-group-size[0]", FlatWorkGroupSize.first});
2148 LB.push_back({"amdgpu-flat-work-group-size[1]", FlatWorkGroupSize.second});
2149 std::pair<unsigned, unsigned> WavesPerEU = ST->getWavesPerEU(F);
2150 LB.push_back({"amdgpu-waves-per-eu[0]", WavesPerEU.first});
2151 LB.push_back({"amdgpu-waves-per-eu[1]", WavesPerEU.second});
2152}
2153
2156 if (!ST->hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
2157 return KnownIEEEMode::On; // Only mode on gfx1170+
2158
2159 const Function *F = I.getFunction();
2160 if (!F)
2162
2163 Attribute IEEEAttr = F->getFnAttribute("amdgpu-ieee");
2164 if (IEEEAttr.isValid())
2166
2167 return AMDGPU::isShader(F->getCallingConv()) ? KnownIEEEMode::Off
2169}
2170
2172 Align Alignment,
2173 unsigned AddressSpace,
2174 TTI::TargetCostKind CostKind,
2175 TTI::OperandValueInfo OpInfo,
2176 const Instruction *I) const {
2177 if (VectorType *VecTy = dyn_cast<VectorType>(Src)) {
2178 if ((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
2179 CostKind != TTI::TCK_Latency &&
2180 VecTy->getElementType()->isIntegerTy(8)) {
2181 return divideCeil(DL.getTypeSizeInBits(VecTy) - 1,
2183 }
2184 }
2185 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace, CostKind,
2186 OpInfo, I);
2187}
2188
2190 if (VectorType *VecTy = dyn_cast<VectorType>(Tp)) {
2191 if (VecTy->getElementType()->isIntegerTy(8)) {
2192 unsigned ElementCount = VecTy->getElementCount().getFixedValue();
2193 return divideCeil(ElementCount - 1, 4);
2194 }
2195 }
2196 return BaseT::getNumberOfParts(Tp);
2197}
2198
2201 switch (Intrinsic->getIntrinsicID()) {
2202 case Intrinsic::amdgcn_wave_shuffle:
2204 default:
2205 break;
2206 }
2207 }
2208
2209 if (isAlwaysUniform(V))
2211
2212 if (isSourceOfDivergence(V))
2214
2216}
2217
2219 StackOffset BaseOffset,
2220 bool HasBaseReg, int64_t Scale,
2221 unsigned AddrSpace) const {
2222 if (HasBaseReg && Scale != 0) {
2223 // gfx1250+ can fold base+scale*index when scale matches the memory access
2224 // size (scale_offset bit). Supported for flat/global/constant/scratch
2225 // (VMEM, max 128 bits) and constant_32bit (SMRD, capped to 128 bits here).
2226 if (getST()->hasScaleOffset() && Ty && Ty->isSized() &&
2228 AddrSpace == AMDGPUAS::FLAT_ADDRESS ||
2229 AddrSpace == AMDGPUAS::PRIVATE_ADDRESS)) {
2230 TypeSize StoreSize = getDataLayout().getTypeStoreSize(Ty);
2231 if (TypeSize::isKnownLE(StoreSize, TypeSize::getFixed(16)) &&
2232 static_cast<int64_t>(StoreSize.getFixedValue()) == Scale)
2233 return 0;
2234 }
2235 return 1;
2236 }
2237 return BaseT::getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, Scale,
2238 AddrSpace);
2239}
2240
2242 const TTI::LSRCost &B) const {
2243 // Favor lower per-iteration work over preheader/setup costs.
2244 // AMDGPU lacks rich addressing modes, so ScaleCost is folded into the
2245 // effective instruction count (base+scale*index requires a separate ADD).
2246 unsigned EffInsnsA = A.Insns + A.ScaleCost;
2247 unsigned EffInsnsB = B.Insns + B.ScaleCost;
2248
2249 return std::tie(EffInsnsA, A.NumIVMuls, A.AddRecCost, A.NumBaseAdds,
2250 A.SetupCost, A.ImmCost, A.NumRegs) <
2251 std::tie(EffInsnsB, B.NumIVMuls, B.AddRecCost, B.NumBaseAdds,
2252 B.SetupCost, B.ImmCost, B.NumRegs);
2253}
2254
2256 // isLSRCostLess de-prioritizes register count; keep consistent.
2257 return false;
2258}
2259
2261 // Prefer the baseline when LSR cannot clearly reduce per-iteration work.
2262 return true;
2263}
2264
2266 const SmallBitVector &UniformArgs) const {
2268 switch (Intrinsic->getIntrinsicID()) {
2269 case Intrinsic::amdgcn_wave_shuffle:
2270 // wave_shuffle(Value, Index): result is uniform when either Value or Index
2271 // is uniform.
2272 return UniformArgs[0] || UniformArgs[1];
2273 default:
2274 llvm_unreachable("unexpected intrinsic in isUniform");
2275 }
2276}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
uint64_t uint64_t
Provides AMDGPU specific target descriptions.
Rewrite undef for PHI
Base class for AMDGPU specific classes of TargetSubtarget.
The AMDGPU TargetMachine interface definition for hw codegen targets.
static constexpr unsigned MaskPackCostPerElt
static cl::opt< unsigned > MemcpyLoopUnroll("amdgpu-memcpy-loop-unroll", cl::desc("Unroll factor (affecting 4x32-bit operations) to use for memory " "operations when lowering statically-sized memcpy, memmove, or" "memset as a loop"), cl::init(16), cl::Hidden)
static cl::opt< unsigned > UnrollThresholdIf("amdgpu-unroll-threshold-if", cl::desc("Unroll threshold increment for AMDGPU for each if statement inside loop"), cl::init(200), cl::Hidden)
static TypeSize getCallArgsTotalAllocaSize(const CallBase *CB, const DataLayout &DL)
static cl::opt< unsigned > ArgAllocaCost("amdgpu-inline-arg-alloca-cost", cl::Hidden, cl::init(4000), cl::desc("Cost of alloca argument"))
static bool canFuseFMulWithFAddSub(const SITargetLowering &TLI, Type *Ty, const Instruction *FMul, const Instruction *FAddSub)
static bool dependsOnLocalPhi(const Loop *L, const Value *Cond, unsigned Depth=0)
static cl::opt< bool > UnrollRuntimeLocal("amdgpu-unroll-runtime-local", cl::desc("Allow runtime unroll for AMDGPU if local memory used in a loop"), cl::init(true), cl::Hidden)
static unsigned adjustInliningThresholdUsingCallee(const CallBase *CB, const SITargetLowering *TLI, const GCNTTIImpl *TTIImpl)
static cl::opt< unsigned > ArgAllocaCutoff("amdgpu-inline-arg-alloca-cutoff", cl::Hidden, cl::init(256), cl::desc("Maximum alloca size to use for inline cost"))
static cl::opt< size_t > InlineMaxBB("amdgpu-inline-max-bb", cl::Hidden, cl::init(1100), cl::desc("Maximum number of BBs allowed in a function after inlining" " (compile time constraint)"))
static bool isFusedFMul(const SITargetLowering &TLI, Type *Ty, const Instruction *FMul, const Instruction *FAddSub)
static std::optional< unsigned > getNumberOfPackedMaskElts(Type *Ty)
static constexpr unsigned MaskUnpackCostPerElt
static const Instruction * getFusedFMul(const SITargetLowering &TLI, Type *Ty, const Instruction *FAddSub)
An fma holds one multiply, so only one fmul operand fuses with FAddSub.
static bool intrinsicHasPackedVectorBenefit(Intrinsic::ID ID)
static cl::opt< unsigned > UnrollMaxBlockToAnalyze("amdgpu-unroll-max-block-to-analyze", cl::desc("Inner loop block size threshold to analyze in unroll for AMDGPU"), cl::init(32), cl::Hidden)
static cl::opt< unsigned > UnrollThresholdPrivate("amdgpu-unroll-threshold-private", cl::desc("Unroll threshold for AMDGPU if private memory used in a loop"), cl::init(2700), cl::Hidden)
static cl::opt< unsigned > UnrollThresholdLocal("amdgpu-unroll-threshold-local", cl::desc("Unroll threshold for AMDGPU if local memory used in a loop"), cl::init(1000), cl::Hidden)
This file a TargetTransformInfoImplBase conforming object specific to the AMDGPU target machine.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Hexagon Common GEP
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
SmallVector< MachineOperand, 4 > Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file implements the SmallBitVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
std::optional< unsigned > getReqdWorkGroupSize(const Function &F, unsigned Dim) const
bool hasWavefrontsEvenlySplittingXDim(const Function &F, bool RequiresUniformYZ=false) const
uint64_t getMaxMemIntrinsicInlineSizeThreshold() const override
AMDGPUTTIImpl(const AMDGPUTargetMachine *TM, const Function &F)
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
an instruction to allocate memory on the stack
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
LLVM_ABI bool getValueAsBool() const
Return the attribute's value as a boolean.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:262
LLVM Basic Block Representation.
Definition BasicBlock.h:62
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
unsigned getNumberOfParts(Type *Tp) const override
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
bool areInlineCompatible(const Function *Caller, const Function *Callee) 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 getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) const override
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) 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 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
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
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
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
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
Value * getArgOperand(unsigned i) const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
Conditional Branch instruction.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition Constants.h:174
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
TypeSize getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type.
Definition DataLayout.h:579
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:317
ArrayRef< unsigned > getIndices() const
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
bool approxFunc() const
Definition FMF.h:70
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
GCNTTIImpl(const AMDGPUTargetMachine *TM, const Function &F)
unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const override
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) const override
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
Account for loads of i8 vector types to have reduced cost.
void collectKernelLaunchBounds(const Function &F, SmallVectorImpl< std::pair< StringRef, int64_t > > &LB) const override
bool isUniform(const Instruction *I, const SmallBitVector &UniformArgs) const override
bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const override
bool isReadRegisterSourceOfDivergence(const IntrinsicInst *ReadReg) const
unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const override
unsigned getNumberOfRegisters(unsigned RCID) const override
bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const override
unsigned getCacheLineSize() const override
Data cache line size for LoopDataPrefetch pass. Has no use before GFX12.
unsigned getStoreVectorFactor(unsigned VF, unsigned StoreSize, unsigned ChainSizeInBytes, VectorType *VecTy) const override
bool isLegalToVectorizeMemChain(unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const
bool isLSRCostLess(const TTI::LSRCost &A, const TTI::LSRCost &B) const override
bool shouldPrefetchAddressSpace(unsigned AS) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *ValTy, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool hasBranchDivergence(const Function *F=nullptr) const override
Value * rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV, Value *NewV) 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
unsigned getCallerAllocaCost(const CallBase *CB, const AllocaInst *AI) 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
void getMemcpyLoopResidualLoweringType(SmallVectorImpl< Type * > &OpsOut, LLVMContext &Context, unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace, Align SrcAlign, Align DestAlign, std::optional< uint32_t > AtomicCpySize) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, 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.
unsigned getInliningThresholdMultiplier() const override
unsigned getLoadVectorFactor(unsigned VF, unsigned LoadSize, unsigned ChainSizeInBytes, VectorType *VecTy) const override
unsigned getPrefetchDistance() const override
How much before a load we should place the prefetch instruction.
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
KnownIEEEMode fpenvIEEEMode(const Instruction &I) const
Return KnownIEEEMode::On if we know if the use context can assume "amdgpu-ieee"="true" and KnownIEEEM...
unsigned adjustInliningThreshold(const CallBase *CB) const override
bool isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) const override
Whether it is profitable to sink the operands of an Instruction I to the basic block of I.
bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const override
bool areInlineCompatible(const Function *Caller, const Function *Callee) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr) 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.
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
bool shouldDropLSRSolutionIfLessProfitable() const override
unsigned getMaxInterleaveFactor(ElementCount VF, bool HasUnorderedReductions) const override
int getInliningLastCallToStaticBonus() const override
bool isInlineAsmSourceOfDivergence(const CallBase *CB, ArrayRef< unsigned > Indices={}) const
Analyze if the results of inline asm are divergent.
bool collectFlatAddressOperands(SmallVectorImpl< int > &OpIndexes, Intrinsic::ID IID) const override
ValueUniformity getValueUniformity(const Value *V) const override
unsigned getNumberOfParts(Type *Tp) const override
When counting parts on AMD GPUs, account for i8s being grouped together under a single i32 value.
bool preferSLPInstCountCheck() const override
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) const override
unsigned getMinVectorRegisterBitWidth() const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind Vector) const override
bool isNumRegsMajorCostOfLSR() const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
Type * getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length, unsigned SrcAddrSpace, unsigned DestAddrSpace, Align SrcAlign, Align DestAlign, std::optional< uint32_t > AtomicElementSize) const override
uint64_t getMaxMemIntrinsicInlineSizeThreshold() const override
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static InstructionCost getInvalid(CostType Val=0)
CostType getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI bool hasApproxFunc() const LLVM_READONLY
Determine whether the approximate-math-functions flag is set.
user_iterator user_begin()
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool hasAllowContract() const LLVM_READONLY
Determine whether the allow-contract flag is set.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
const IntrinsicInst * getInst() const
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
An instruction for reading from memory.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1081
Machine Value Type.
static LLVM_ABI MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Root of the metadata hierarchy.
Definition Metadata.h:64
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
The optimization diagnostic interface.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
bool isFMADLegal(const SelectionDAG &DAG, const SDNode *N) const override
Returns true if be combined with to form an ISD::FMAD.
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain targets require unusual breakdowns of certain types.
The main scalar evolution driver.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:31
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::vector< AsmOperandInfo > AsmOperandInfoVector
Primary interface to the complete machine description for the target machine.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual const DataLayout & getDataLayout() const
virtual void getMemcpyLoopResidualLoweringType(SmallVectorImpl< Type * > &OpsOut, LLVMContext &Context, unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace, Align SrcAlign, Align DestAlign, std::optional< uint32_t > AtomicCpySize) const
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
@ TCK_SizeAndLatency
The weighted sum of size and latency.
@ 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_Free
Expected to fold away in lowering.
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_InsertSubvector
InsertSubvector. Index indicates start offset.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ 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_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.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:352
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:355
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
Definition Type.h:147
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
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Definition Type.cpp:298
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
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
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:303
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:276
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
op_range operands()
Definition User.h:267
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
Base class of all SIMD vector types.
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:231
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ BUFFER_STRIDED_POINTER
Address space for 192-bit fat buffer pointers with an additional index.
@ REGION_ADDRESS
Address space for region memory. (GDS)
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ FLAT_ADDRESS
Address space for flat memory.
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
@ BUFFER_FAT_POINTER
Address space for 160-bit buffer fat pointers.
@ PRIVATE_ADDRESS
Address space for private memory.
@ BUFFER_RESOURCE
Address space for 128-bit buffer resources.
LLVM_READNONE constexpr bool isShader(CallingConv::ID CC)
bool isFlatGlobalAddrSpace(unsigned AS)
bool isArgPassedInSGPR(const Argument *A)
bool isIntrinsicAlwaysUniform(unsigned IntrID)
bool isIntrinsicSourceOfDivergence(unsigned IntrID)
SmallVector< unsigned > getMaxNumWorkGroups(const Function &F)
bool isExtendedGlobalAddrSpace(unsigned AS)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:26
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:906
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:420
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:952
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
LLVM_ABI int getInstrCost()
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_combine_or< CastInst_match< OpTy, CastInst >, OpTy > m_CastOrSelf(const OpTy &Op)
Matches any cast or self. Used to ignore casts.
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
auto m_Constant()
Match an arbitrary Constant and ignore it.
specific_fpval m_FPOne()
Match a float 1.0 or vector with all elements equal to 1.0.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
FNeg_match< OpTy, true > m_FNegOrFSubNegZero(const OpTy &X)
Match fneg X or fsub -0.0, X.
auto m_FAbs(const Opnd0 &Op0)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
Definition Metadata.h:694
This is an optimization pass for GlobalISel generic memory operations.
@ Length
Definition DWP.cpp:577
InstructionCost Cost
LLVM_ABI void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Definition Analysis.cpp:121
bool isValidAtomicOrdering(Int I)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI MDNode * findOptionMDForLoop(const Loop *TheLoop, StringRef Name)
Find string metadata for a loop.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
Definition STLExtras.h:2189
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
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
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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
AtomicOrdering
Atomic ordering for LLVM's memory model.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:389
@ FMul
Product of floats.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
ValueUniformity
Enum describing how values behave with respect to uniformity and divergence, to answer the question: ...
Definition Uniformity.h:18
@ AlwaysUniform
The result value is always uniform.
Definition Uniformity.h:23
@ NeverUniform
The result value can never be assumed to be uniform.
Definition Uniformity.h:26
@ Default
The result value is uniform if and only if all operands are uniform.
Definition Uniformity.h:20
@ Custom
The result value requires a custom uniformity check.
Definition Uniformity.h:31
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static constexpr DenormalMode getPreserveSign()
Extended Value Type.
Definition ValueTypes.h:35
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
Information about a load/store intrinsic defined by the target.
bool isInlineCompatible(SIModeRegisterDefaults CalleeMode) const
Parameters that control the generic loop unrolling transformation.
unsigned Threshold
The cost threshold for the unrolled loop.
bool UnrollVectorizedLoop
Disable runtime unrolling by default for vectorized loops.
unsigned MaxIterationsCountToAnalyze
Don't allow loop unrolling to simulate more than this number of iterations when checking full unroll ...
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...