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
38static bool dependsOnLocalPhi(const Loop *L, const Value *Cond,
39 unsigned Depth = 0) {
41 if (!I)
42 return false;
43
44 if (!L->contains(I))
45 return false;
46 for (const Value *V : I->operand_values()) {
47 if (const PHINode *PHI = dyn_cast<PHINode>(V)) {
48 if (llvm::none_of(L->getSubLoops(), [PHI](const Loop* SubLoop) {
49 return SubLoop->contains(PHI); }))
50 return true;
51 } else if (Depth < 10 && dependsOnLocalPhi(L, V, Depth+1))
52 return true;
53 }
54 return false;
55}
56
58 : BaseT(TM, F.getDataLayout()), CLOpts(TM->getCLOpts()),
59 TargetTriple(F.getParent()->getTargetTriple()),
60 ST(static_cast<const GCNSubtarget *>(TM->getSubtargetImpl(F))),
61 TLI(ST->getTargetLowering()) {}
62
65 OptimizationRemarkEmitter *ORE) const {
66 const Function &F = *L->getHeader()->getParent();
67 UP.Threshold = static_cast<unsigned>(
68 F.getFnAttributeAsParsedInteger("amdgpu-unroll-threshold", 300));
69 UP.PartialThreshold = static_cast<unsigned>(
70 F.getFnAttributeAsParsedInteger("amdgpu-partial-unroll-threshold", 150));
71 UP.MaxCount = std::numeric_limits<unsigned>::max();
72 UP.Partial = true;
73
74 // Conditional branch in a loop back edge needs 3 additional exec
75 // manipulations in average.
76 UP.BEInsns += 3;
77
78 // We want to run unroll even for the loops which have been vectorized.
79 UP.UnrollVectorizedLoop = true;
80
81 // Enable runtime unrolling for loops whose trip count is not known at
82 // compile time.
83 UP.Runtime = true;
84
85 // Maximum alloca size than can fit registers. Reserve 16 registers.
86 const unsigned MaxAlloca = (256 - 16) * 4;
87 unsigned ThresholdPrivate = CLOpts.unroll_threshold_private;
88 unsigned ThresholdLocal = CLOpts.unroll_threshold_local;
89
90 // If this loop has the amdgpu.loop.unroll.threshold metadata we will use the
91 // provided threshold value as the default for Threshold
92 if (MDNode *LoopUnrollThreshold =
93 findOptionMDForLoop(L, "amdgpu.loop.unroll.threshold")) {
94 if (LoopUnrollThreshold->getNumOperands() == 2) {
96 LoopUnrollThreshold->getOperand(1));
97 if (MetaThresholdValue) {
98 // We will also use the supplied value for PartialThreshold for now.
99 // We may introduce additional metadata if it becomes necessary in the
100 // future.
101 UP.Threshold =
102 static_cast<unsigned>(MetaThresholdValue->getSExtValue());
104 ThresholdPrivate = std::min(ThresholdPrivate, UP.Threshold);
105 ThresholdLocal = std::min(ThresholdLocal, UP.Threshold);
106 }
107 }
108 }
109
110 unsigned MaxBoost = std::max(ThresholdPrivate, ThresholdLocal);
111 for (const BasicBlock *BB : L->getBlocks()) {
112 const DataLayout &DL = BB->getDataLayout();
113 unsigned LocalGEPsSeen = 0;
114
115 if (llvm::any_of(L->getSubLoops(), [BB](const Loop* SubLoop) {
116 return SubLoop->contains(BB); }))
117 continue; // Block belongs to an inner loop.
118
119 for (const Instruction &I : *BB) {
120 // Unroll a loop which contains an "if" statement whose condition
121 // defined by a PHI belonging to the loop. This may help to eliminate
122 // if region and potentially even PHI itself, saving on both divergence
123 // and registers used for the PHI.
124 // Add a small bonus for each of such "if" statements.
125 if (const CondBrInst *Br = dyn_cast<CondBrInst>(&I)) {
126 if (UP.Threshold < MaxBoost) {
127 BasicBlock *Succ0 = Br->getSuccessor(0);
128 BasicBlock *Succ1 = Br->getSuccessor(1);
129 if ((L->contains(Succ0) && L->isLoopExiting(Succ0)) ||
130 (L->contains(Succ1) && L->isLoopExiting(Succ1)))
131 continue;
132 if (dependsOnLocalPhi(L, Br->getCondition())) {
133 UP.Threshold += CLOpts.unroll_threshold_if;
134 LLVM_DEBUG(dbgs() << "Set unroll threshold " << UP.Threshold
135 << " for loop:\n"
136 << *L << " due to " << *Br << '\n');
137 if (UP.Threshold >= MaxBoost)
138 return;
139 }
140 }
141 continue;
142 }
143
145 if (!GEP)
146 continue;
147
148 unsigned AS = GEP->getAddressSpace();
149 unsigned Threshold = 0;
151 Threshold = ThresholdPrivate;
153 Threshold = ThresholdLocal;
154 else
155 continue;
156
157 if (UP.Threshold >= Threshold)
158 continue;
159
160 if (AS == AMDGPUAS::PRIVATE_ADDRESS) {
161 const Value *Ptr = GEP->getPointerOperand();
162 const AllocaInst *Alloca =
164 if (!Alloca || !Alloca->isStaticAlloca())
165 continue;
166 auto AllocaSize = Alloca->getAllocationSize(DL);
167 if (!AllocaSize || AllocaSize->getFixedValue() > MaxAlloca)
168 continue;
169 } else if (AS == AMDGPUAS::LOCAL_ADDRESS ||
171 LocalGEPsSeen++;
172 // Inhibit unroll for local memory if we have seen addressing not to
173 // a variable, most likely we will be unable to combine it.
174 // Do not unroll too deep inner loops for local memory to give a chance
175 // to unroll an outer loop for a more important reason.
176 if (LocalGEPsSeen > 1 || L->getLoopDepth() > 2 ||
177 (!isa<GlobalVariable>(GEP->getPointerOperand()) &&
178 !isa<Argument>(GEP->getPointerOperand())))
179 continue;
180 LLVM_DEBUG(dbgs() << "Allow unroll runtime for loop:\n"
181 << *L << " due to LDS use.\n");
182 UP.Runtime = CLOpts.unroll_runtime_local;
183 }
184
185 // Check if GEP depends on a value defined by this loop itself.
186 bool HasLoopDef = false;
187 for (const Value *Op : GEP->operands()) {
188 const Instruction *Inst = dyn_cast<Instruction>(Op);
189 if (!Inst || L->isLoopInvariant(Op))
190 continue;
191
192 if (llvm::any_of(L->getSubLoops(), [Inst](const Loop* SubLoop) {
193 return SubLoop->contains(Inst); }))
194 continue;
195 HasLoopDef = true;
196 break;
197 }
198 if (!HasLoopDef)
199 continue;
200
201 // We want to do whatever we can to limit the number of alloca
202 // instructions that make it through to the code generator. allocas
203 // require us to use indirect addressing, which is slow and prone to
204 // compiler bugs. If this loop does an address calculation on an
205 // alloca ptr, then we want to use a higher than normal loop unroll
206 // threshold. This will give SROA a better chance to eliminate these
207 // allocas.
208 //
209 // We also want to have more unrolling for local memory to let ds
210 // instructions with different offsets combine.
211 //
212 // Don't use the maximum allowed value here as it will make some
213 // programs way too big.
214 UP.Threshold = Threshold;
215 LLVM_DEBUG(dbgs() << "Set unroll threshold " << Threshold
216 << " for loop:\n"
217 << *L << " due to " << *GEP << '\n');
218 if (UP.Threshold >= MaxBoost)
219 return;
220 }
221
222 // If we got a GEP in a small BB from inner loop then increase max trip
223 // count to analyze for better estimation cost in unroll
224 if (L->isInnermost() && BB->size() < CLOpts.unroll_max_block_to_analyze)
226 }
227}
228
233
235 return 1024;
236}
237
239 : BaseT(TM, F.getDataLayout()), CLOpts(TM->getCLOpts()),
240 ST(static_cast<const GCNSubtarget *>(TM->getSubtargetImpl(F))),
241 TLI(ST->getTargetLowering()), CommonTTI(TM, F),
242 IsGraphics(AMDGPU::isGraphics(F.getCallingConv())) {
244 HasFP32Denormals = Mode.FP32Denormals != DenormalMode::getPreserveSign();
245}
246
248 return !F || !ST->isSingleLaneExecution(*F);
249}
250
251unsigned GCNTTIImpl::getNumberOfRegisters(unsigned RCID) const {
252 // NB: RCID is not an RCID. In fact it is 0 or 1 for scalar or vector
253 // registers. See getRegisterClassForType for the implementation.
254 // In this case vector registers are not vector in terms of
255 // VGPRs, but those which can hold multiple values.
256
257 // This is really the number of registers to fill when vectorizing /
258 // interleaving loops, so we lie to avoid trying to use all registers.
259 return 4;
260}
261
264 switch (K) {
266 return TypeSize::getFixed(32);
268 return TypeSize::getFixed(
269 (ST->hasAnyPackedFP64Ops() || ST->hasAnyPackedU64Ops()) ? 128
270 : ST->hasAnyPackedFP32Ops() ? 64
271 : 32);
273 return TypeSize::getScalable(0);
274 }
275 llvm_unreachable("Unsupported register kind");
276}
277
279 return 32;
280}
281
282unsigned GCNTTIImpl::getMaximumVF(unsigned ElemWidth, unsigned Opcode) const {
283 if (Opcode == Instruction::Load || Opcode == Instruction::Store)
284 return 32 * 4 / ElemWidth;
285 // For a given width return the max 0number of elements that can be combined
286 // into a wider bit value:
287 return (ElemWidth == 8 && ST->has16BitInsts()) ? 4
288 : (ElemWidth == 16 && ST->has16BitInsts()) ? 2
289 : (ElemWidth == 32 && ST->hasAnyPackedFP32Ops()) ? 2
290 : (ElemWidth == 64 &&
291 (ST->hasAnyPackedFP64Ops() || ST->hasAnyPackedU64Ops()))
292 ? 2
293 : 1;
294}
295
297 // The integer inst-count heuristic causes regressions on gfx94x and gfx950
298 // because 2-element vector trees that pass the scalar/vector instruction
299 // count comparison still widen scalar moves (e.g. v_mov_b32 to v_mov_b64)
300 // after codegen, increasing register pressure and throughput cost without
301 // reducing the total instruction count.
302 return !ST->hasGFX940Insts() && !ST->hasGFX950Insts();
303}
304
305unsigned GCNTTIImpl::getLoadVectorFactor(unsigned VF, unsigned LoadSize,
306 unsigned ChainSizeInBytes,
307 VectorType *VecTy) const {
308 unsigned VecRegBitWidth = VF * LoadSize;
309 if (VecRegBitWidth > 128 && VecTy->getScalarSizeInBits() < 32)
310 // TODO: Support element-size less than 32bit?
311 return 128 / LoadSize;
312
313 return VF;
314}
315
316unsigned GCNTTIImpl::getStoreVectorFactor(unsigned VF, unsigned StoreSize,
317 unsigned ChainSizeInBytes,
318 VectorType *VecTy) const {
319 unsigned VecRegBitWidth = VF * StoreSize;
320 if (VecRegBitWidth > 128)
321 return 128 / StoreSize;
322
323 return VF;
324}
325
326unsigned GCNTTIImpl::getLoadStoreVecRegBitWidth(unsigned AddrSpace) const {
327 if (AddrSpace == AMDGPUAS::GLOBAL_ADDRESS ||
328 AddrSpace == AMDGPUAS::CONSTANT_ADDRESS ||
330 AddrSpace == AMDGPUAS::BUFFER_FAT_POINTER ||
331 AddrSpace == AMDGPUAS::BUFFER_RESOURCE ||
333 return 512;
334 }
335
336 if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS)
337 return 8 * ST->getMaxPrivateElementSize();
338
339 // Common to flat, global, local and region. Assume for unknown addrspace.
340 return 128;
341}
342
343bool GCNTTIImpl::isLegalToVectorizeMemChain(unsigned ChainSizeInBytes,
344 Align Alignment,
345 unsigned AddrSpace) const {
346 // We allow vectorization of flat stores, even though we may need to decompose
347 // them later if they may access private memory. We don't have enough context
348 // here, and legalization can handle it.
349 if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS) {
350 return (Alignment >= 4 || ST->hasUnalignedScratchAccessEnabled()) &&
351 ChainSizeInBytes <= ST->getMaxPrivateElementSize();
352 }
353 return true;
354}
355
356bool GCNTTIImpl::isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,
357 Align Alignment,
358 unsigned AddrSpace) const {
359 return isLegalToVectorizeMemChain(ChainSizeInBytes, Alignment, AddrSpace);
360}
361
362bool GCNTTIImpl::isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,
363 Align Alignment,
364 unsigned AddrSpace) const {
365 return isLegalToVectorizeMemChain(ChainSizeInBytes, Alignment, AddrSpace);
366}
367
369 return 1024;
370}
371
373 LLVMContext &Context, Value *Length, unsigned SrcAddrSpace,
374 unsigned DestAddrSpace, Align SrcAlign, Align DestAlign,
375 std::optional<uint32_t> AtomicElementSize) const {
376
377 if (AtomicElementSize)
378 return Type::getIntNTy(Context, *AtomicElementSize * 8);
379
380 // 16-byte accesses achieve the highest copy throughput.
381 // If the operation has a fixed known length that is large enough, it is
382 // worthwhile to return an even wider type and let legalization lower it into
383 // multiple accesses, effectively unrolling the memcpy loop.
384 // We also rely on legalization to decompose into smaller accesses for
385 // subtargets and address spaces where it is necessary.
386 //
387 // Don't unroll if Length is not a constant, since unrolling leads to worse
388 // performance for length values that are smaller or slightly larger than the
389 // total size of the type returned here. Mitigating that would require a more
390 // complex lowering for variable-length memcpy and memmove.
391 unsigned I32EltsInVector = 4;
392 if (CLOpts.memcpy_loop_unroll > 0 && isa<ConstantInt>(Length))
394 CLOpts.memcpy_loop_unroll * I32EltsInVector);
395
396 return FixedVectorType::get(Type::getInt32Ty(Context), I32EltsInVector);
397}
398
400 SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
401 unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
402 Align SrcAlign, Align DestAlign,
403 std::optional<uint32_t> AtomicCpySize) const {
404
405 if (AtomicCpySize)
407 OpsOut, Context, RemainingBytes, SrcAddrSpace, DestAddrSpace, SrcAlign,
408 DestAlign, AtomicCpySize);
409
410 Type *I32x4Ty = FixedVectorType::get(Type::getInt32Ty(Context), 4);
411 while (RemainingBytes >= 16) {
412 OpsOut.push_back(I32x4Ty);
413 RemainingBytes -= 16;
414 }
415
416 Type *I64Ty = Type::getInt64Ty(Context);
417 while (RemainingBytes >= 8) {
418 OpsOut.push_back(I64Ty);
419 RemainingBytes -= 8;
420 }
421
422 Type *I32Ty = Type::getInt32Ty(Context);
423 while (RemainingBytes >= 4) {
424 OpsOut.push_back(I32Ty);
425 RemainingBytes -= 4;
426 }
427
428 Type *I16Ty = Type::getInt16Ty(Context);
429 while (RemainingBytes >= 2) {
430 OpsOut.push_back(I16Ty);
431 RemainingBytes -= 2;
432 }
433
434 Type *I8Ty = Type::getInt8Ty(Context);
435 while (RemainingBytes) {
436 OpsOut.push_back(I8Ty);
437 --RemainingBytes;
438 }
439}
440
442 bool HasUnorderedReductions) const {
443 // Disable unrolling if the loop is not vectorized.
444 // TODO: Enable this again.
445 if (VF.isScalar())
446 return 1;
447
448 return 8;
449}
450
452 MemIntrinsicInfo &Info) const {
453 switch (Inst->getIntrinsicID()) {
454 case Intrinsic::amdgcn_ds_ordered_add:
455 case Intrinsic::amdgcn_ds_ordered_swap: {
456 auto *Ordering = dyn_cast<ConstantInt>(Inst->getArgOperand(2));
457 auto *Volatile = dyn_cast<ConstantInt>(Inst->getArgOperand(4));
458 if (!Ordering || !Volatile)
459 return false; // Invalid.
460
461 uint64_t OrderingVal = Ordering->getZExtValue();
462 if (!isValidAtomicOrdering(OrderingVal))
463 return false;
464
465 Info.PtrVal = Inst->getArgOperand(0);
466 Info.Ordering = static_cast<AtomicOrdering>(OrderingVal);
467 Info.ReadMem = true;
468 Info.WriteMem = true;
469 Info.IsVolatile = !Volatile->isZero();
470 return true;
471 }
472 default:
473 return false;
474 }
475}
476
477/// \returns true if \p FMul and its single fadd/fsub user \p FAddSub are
478/// expected to fuse during instruction selection. \p Ty is the type the fused
479/// operation runs on.
481 const Instruction *FMul,
482 const Instruction *FAddSub) {
483 assert((FAddSub->getOpcode() == Instruction::FAdd ||
484 FAddSub->getOpcode() == Instruction::FSub) &&
485 "Expected an fadd or an fsub");
486
487 // The mad forms fuse exactly without fast-math flags but flush denormals.
488 // An fma forms only when it is not slower than the separate operations.
489 const Function &F = *FAddSub->getFunction();
490 const bool HasFMAD = TLI.isFMADLegal(F, Ty);
491 const bool HasFMA = TLI.isFMAFasterThanFMulAndFAdd(F, Ty);
492 if (!HasFMAD && !HasFMA)
493 return false;
494
495 // Without a mad the pair fuses only when both carry contract.
496 return HasFMAD || (FAddSub->hasAllowContract() && FMul->hasAllowContract());
497}
498
499/// An fma holds one multiply, so only one fmul operand fuses with \p FAddSub.
501 const Instruction *FAddSub) {
502 for (const Value *Op : FAddSub->operands()) {
503 const auto *FMul = dyn_cast<Instruction>(Op);
504 if (FMul && FMul->getOpcode() == Instruction::FMul && FMul->hasOneUse() &&
505 canFuseFMulWithFAddSub(TLI, Ty, FMul, FAddSub))
506 return FMul;
507 }
508 return nullptr;
509}
510
511static bool isFusedFMul(const SITargetLowering &TLI, Type *Ty,
512 const Instruction *FMul, const Instruction *FAddSub) {
513 const Instruction *Fused = getFusedFMul(TLI, Ty, FAddSub);
514 if (Fused == FMul)
515 return true;
516 // (a * b + c * d) + e becomes fma(a, b, fma(c, d, e)) if the outer fadd has
517 // reassoc.
518 if (!Fused || FAddSub->getOpcode() != Instruction::FAdd ||
519 !FAddSub->hasOneUse())
520 return false;
521 const auto *Outer = dyn_cast<BinaryOperator>(*FAddSub->user_begin());
522 return Outer && Outer->getOpcode() == Instruction::FAdd &&
523 Outer->hasAllowReassoc() &&
524 canFuseFMulWithFAddSub(TLI, Ty, FMul, Outer);
525}
526
528 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
530 ArrayRef<const Value *> Args, const Instruction *CtxI) const {
531
532 // Legalize the type.
533 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
534 int ISD = TLI->InstructionOpcodeToISD(Opcode);
535
536 // Because we don't have any legal vector operations, but the legal types, we
537 // need to account for split vectors.
538 unsigned NElts = LT.second.isVector() ?
539 LT.second.getVectorNumElements() : 1;
540
541 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
542
543 switch (ISD) {
544 case ISD::SHL:
545 case ISD::SRL:
546 case ISD::SRA:
547 if (SLT == MVT::i64)
548 return get64BitInstrCost(CostKind) * LT.first * NElts;
549
550 if (ST->has16BitInsts() && SLT == MVT::i16)
551 NElts = (NElts + 1) / 2;
552
553 // i32
554 return getFullRateInstrCost() * LT.first * NElts;
555 case ISD::ADD:
556 case ISD::SUB:
557 if (SLT == MVT::i64 && ST->hasAnyPackedU64Ops())
558 NElts = (NElts + 1) / 2;
559 [[fallthrough]];
560 case ISD::AND:
561 case ISD::OR:
562 case ISD::XOR:
563 if (SLT == MVT::i64) {
564 // and, or and xor are typically split into 2 VALU instructions.
565 return 2 * getFullRateInstrCost() * LT.first * NElts;
566 }
567
568 if (ST->has16BitInsts() && SLT == MVT::i16)
569 NElts = (NElts + 1) / 2;
570
571 return LT.first * NElts * getFullRateInstrCost();
572 case ISD::MUL: {
573 const int QuarterRateCost = getQuarterRateInstrCost(CostKind);
574 if (SLT == MVT::i64) {
575 const int FullRateCost = getFullRateInstrCost();
576 return (4 * QuarterRateCost + (2 * 2) * FullRateCost) * LT.first * NElts;
577 }
578
579 if (ST->has16BitInsts() && SLT == MVT::i16)
580 NElts = (NElts + 1) / 2;
581
582 // i32
583 return QuarterRateCost * NElts * LT.first;
584 }
585 case ISD::FMUL:
586 // Check possible fuse {fadd|fsub}(a,fmul(b,c)) and return zero cost for
587 // fmul(b,c) supposing the fadd|fsub will get estimated cost for the whole
588 // fused operation. A vector fmul priced with a scalar context fuses with
589 // the scalar fadd|fsub only when it is emitted lane by lane.
590 if (CtxI && CtxI->hasOneUse() &&
591 (CtxI->getType() == Ty ||
592 getMaximumVF(Ty->getScalarSizeInBits(), Opcode) == 1)) {
593 const auto *FAddSub = dyn_cast<BinaryOperator>(*CtxI->user_begin());
594 if (FAddSub &&
595 (FAddSub->getOpcode() == Instruction::FAdd ||
596 FAddSub->getOpcode() == Instruction::FSub) &&
597 isFusedFMul(*TLI, Ty, CtxI, FAddSub))
599 }
600 [[fallthrough]];
601 case ISD::FADD:
602 case ISD::FSUB:
603 if (ST->hasAnyPackedFP32Ops() && SLT == MVT::f32)
604 NElts = (NElts + 1) / 2;
605 if (ST->hasBF16PackedInsts() && SLT == MVT::bf16)
606 NElts = (NElts + 1) / 2;
607 if (SLT == MVT::f64) {
608 if (ST->hasAnyPackedFP64Ops())
609 NElts = (NElts + 1) / 2;
610 return LT.first * NElts * get64BitInstrCost(CostKind);
611 }
612
613 if (ST->has16BitInsts() && SLT == MVT::f16)
614 NElts = (NElts + 1) / 2;
615
616 if (SLT == MVT::f32 || SLT == MVT::f16 || SLT == MVT::bf16)
617 return LT.first * NElts * getFullRateInstrCost();
618 break;
619 case ISD::FDIV:
620 case ISD::FREM:
621 // FIXME: frem should be handled separately. The fdiv in it is most of it,
622 // but the current lowering is also not entirely correct.
623 if (SLT == MVT::f64) {
624 int Cost = 7 * get64BitInstrCost(CostKind) +
625 getQuarterRateInstrCost(CostKind) +
626 3 * getHalfRateInstrCost(CostKind);
627 // Add cost of workaround.
628 if (!ST->hasUsableDivScaleConditionOutput())
629 Cost += 3 * getFullRateInstrCost();
630
631 return LT.first * Cost * NElts;
632 }
633
634 if (!Args.empty() && match(Args[0], PatternMatch::m_FPOne())) {
635 // TODO: This is more complicated, unsafe flags etc.
636 if ((SLT == MVT::f32 && !HasFP32Denormals) ||
637 (SLT == MVT::f16 && ST->has16BitInsts())) {
638 return LT.first * getTransInstrCost(CostKind) * NElts;
639 }
640 }
641
642 if (SLT == MVT::f16 && ST->has16BitInsts()) {
643 // 2 x v_cvt_f32_f16
644 // f32 rcp
645 // f32 fmul
646 // v_cvt_f16_f32
647 // f16 div_fixup
648 int Cost = 4 * getFullRateInstrCost() + 2 * getTransInstrCost(CostKind);
649 return LT.first * Cost * NElts;
650 }
651
652 if (SLT == MVT::f32 && (CtxI && CtxI->hasApproxFunc())) {
653 // Fast unsafe fdiv lowering:
654 // f32 rcp
655 // f32 fmul
656 int Cost = getTransInstrCost(CostKind) + getFullRateInstrCost();
657 return LT.first * Cost * NElts;
658 }
659
660 if (SLT == MVT::f32 || SLT == MVT::f16) {
661 // 4 more v_cvt_* insts without f16 insts support
662 int Cost = (SLT == MVT::f16 ? 14 : 10) * getFullRateInstrCost() +
663 1 * getTransInstrCost(CostKind);
664
665 if (!HasFP32Denormals) {
666 // FP mode switches.
667 Cost += 2 * getFullRateInstrCost();
668 }
669
670 return LT.first * NElts * Cost;
671 }
672 break;
673 case ISD::FNEG:
674 // Use the backend' estimation. If fneg is not free each element will cost
675 // one additional instruction.
676 return TLI->isFNegFree(SLT) ? 0 : NElts;
677 default:
678 break;
679 }
680
681 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
682 Args, CtxI);
683}
684
685// Return true if there's a potential benefit from using v2f16/v2i16
686// instructions for an intrinsic, even if it requires nontrivial legalization.
688 switch (ID) {
689 case Intrinsic::fma:
690 case Intrinsic::fmuladd:
691 case Intrinsic::copysign:
692 case Intrinsic::minimumnum:
693 case Intrinsic::maximumnum:
694 case Intrinsic::canonicalize:
695 // There's a small benefit to using vector ops in the legalized code.
696 case Intrinsic::round:
697 case Intrinsic::uadd_sat:
698 case Intrinsic::usub_sat:
699 case Intrinsic::sadd_sat:
700 case Intrinsic::ssub_sat:
701 case Intrinsic::abs:
702 return true;
703 default:
704 return false;
705 }
706}
707
710 TTI::TargetCostKind CostKind) const {
711 switch (ICA.getID()) {
712 case Intrinsic::fabs:
713 // Free source modifier in the common case.
714 return 0;
715 case Intrinsic::amdgcn_workitem_id_x:
716 case Intrinsic::amdgcn_workitem_id_y:
717 case Intrinsic::amdgcn_workitem_id_z:
718 // TODO: If hasPackedTID, or if the calling context is not an entry point
719 // there may be a bit instruction.
720 return 0;
721 case Intrinsic::amdgcn_workgroup_id_x:
722 case Intrinsic::amdgcn_workgroup_id_y:
723 case Intrinsic::amdgcn_workgroup_id_z:
724 case Intrinsic::amdgcn_lds_kernel_id:
725 case Intrinsic::amdgcn_dispatch_ptr:
726 case Intrinsic::amdgcn_dispatch_id:
727 case Intrinsic::amdgcn_implicitarg_ptr:
728 case Intrinsic::amdgcn_queue_ptr:
729 // Read from an argument register.
730 return 0;
731 default:
732 break;
733 }
734
735 Type *RetTy = ICA.getReturnType();
736
737 Intrinsic::ID IID = ICA.getID();
738 switch (IID) {
739 case Intrinsic::exp:
740 case Intrinsic::exp2:
741 case Intrinsic::exp10: {
742 // Legalize the type.
743 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
744 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
745 unsigned NElts =
746 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
747
748 if (SLT == MVT::f64) {
749 unsigned NumOps = 20;
750 if (IID == Intrinsic::exp)
751 ++NumOps;
752 else if (IID == Intrinsic::exp10)
753 NumOps += 3;
754
755 return LT.first * NElts * NumOps * get64BitInstrCost(CostKind);
756 }
757
758 if (SLT == MVT::f32) {
759 unsigned NumFullRateOps = 0;
760 // v_exp_f32 (transcendental).
761 unsigned NumTransOps = 1;
762
763 if (!ICA.getFlags().approxFunc() && IID != Intrinsic::exp2) {
764 // Non-AFN exp/exp10: range reduction + v_exp_f32 + ldexp +
765 // overflow/underflow checks (lowerFEXP). Denorm is also handled.
766 // FMA preamble: ~13 full-rate ops; non-FMA: ~17.
767 NumFullRateOps = ST->hasFastFMAF32() ? 13 : 17;
768 } else {
769 if (IID == Intrinsic::exp) {
770 // lowerFEXPUnsafe: fmul (base conversion) + v_exp_f32.
771 NumFullRateOps = 1;
772 } else if (IID == Intrinsic::exp10) {
773 // lowerFEXP10Unsafe: 3 fmul + 2 v_exp_f32 (double-exp2).
774 NumFullRateOps = 3;
775 NumTransOps = 2;
776 }
777 // Denorm scaling adds setcc + select + fadd + select + fmul.
778 if (HasFP32Denormals)
779 NumFullRateOps += 5;
780 }
781
782 InstructionCost Cost = NumFullRateOps * getFullRateInstrCost() +
783 NumTransOps * getTransInstrCost(CostKind);
784 return LT.first * NElts * Cost;
785 }
786
787 break;
788 }
789 case Intrinsic::log:
790 case Intrinsic::log2:
791 case Intrinsic::log10: {
792 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
793 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
794 unsigned NElts =
795 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
796
797 if (SLT == MVT::f32) {
798 unsigned NumFullRateOps = 0;
799
800 if (IID == Intrinsic::log2) {
801 // LowerFLOG2: just v_log_f32.
802 } else if (ICA.getFlags().approxFunc()) {
803 // LowerFLOGUnsafe: v_log_f32 + fmul (base conversion).
804 NumFullRateOps = 1;
805 } else {
806 // LowerFLOGCommon non-AFN: v_log_f32 + extended-precision
807 // multiply + finite check.
808 NumFullRateOps = ST->hasFastFMAF32() ? 8 : 11;
809 }
810
811 if (HasFP32Denormals)
812 NumFullRateOps += 5;
813
815 NumFullRateOps * getFullRateInstrCost() + getTransInstrCost(CostKind);
816 return LT.first * NElts * Cost;
817 }
818
819 break;
820 }
821 case Intrinsic::sin:
822 case Intrinsic::cos: {
823 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
824 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
825 unsigned NElts =
826 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
827
828 if (SLT == MVT::f32) {
829 // LowerTrig: fmul(1/2pi) + v_sin/v_cos.
830 unsigned NumFullRateOps = ST->hasTrigReducedRange() ? 2 : 1;
831
833 NumFullRateOps * getFullRateInstrCost() + getTransInstrCost(CostKind);
834 return LT.first * NElts * Cost;
835 }
836
837 break;
838 }
839 case Intrinsic::sqrt: {
840 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
841 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
842 unsigned NElts =
843 LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
844
845 if (SLT == MVT::f32) {
846 unsigned NumFullRateOps = 0;
847
848 if (!ICA.getFlags().approxFunc()) {
849 // lowerFSQRTF32 non-AFN: v_sqrt_f32 + refinement + scale fixup.
850 NumFullRateOps = HasFP32Denormals ? 17 : 16;
851 }
852
854 NumFullRateOps * getFullRateInstrCost() + getTransInstrCost(CostKind);
855 return LT.first * NElts * Cost;
856 }
857
858 break;
859 }
860 default:
861 break;
862 }
863
865 return BaseT::getIntrinsicInstrCost(ICA, CostKind);
866
867 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(RetTy);
868 MVT::SimpleValueType SLT = LT.second.getScalarType().SimpleTy;
869 unsigned NElts = LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
870
871 if ((ST->hasVOP3PInsts() &&
872 (SLT == MVT::f16 || SLT == MVT::i16 ||
873 (SLT == MVT::bf16 && ST->hasBF16PackedInsts()))) ||
874 (ST->hasAnyPackedFP64Ops() && SLT == MVT::f64) ||
875 (ST->hasAnyPackedU64Ops() && SLT == MVT::i64)) {
876 NElts = (NElts + 1) / 2;
877 } else if (SLT == MVT::f32) {
878 bool HasPk2FP32Op = ST->hasAnyPackedFP32Ops() &&
879 IID != Intrinsic::minimumnum &&
880 IID != Intrinsic::maximumnum;
881 NElts = HasPk2FP32Op ? (NElts + 1) / 2 : NElts;
882 }
883
884 // TODO: Get more refined intrinsic costs?
885 unsigned InstRate = getQuarterRateInstrCost(CostKind);
886
887 switch (ICA.getID()) {
888 case Intrinsic::fma:
889 case Intrinsic::fmuladd:
890 if (SLT == MVT::f64) {
891 InstRate = get64BitInstrCost(CostKind);
892 break;
893 }
894
895 if ((SLT == MVT::f32 && ST->hasFastFMAF32()) || SLT == MVT::f16)
896 InstRate = getFullRateInstrCost();
897 else {
898 InstRate = ST->hasFastFMAF32() ? getHalfRateInstrCost(CostKind)
899 : getQuarterRateInstrCost(CostKind);
900 }
901 break;
902 case Intrinsic::copysign:
903 return NElts * getFullRateInstrCost();
904 case Intrinsic::minimumnum:
905 case Intrinsic::maximumnum: {
906 // Instruction + 2 canonicalizes. For cases that need type promotion, we the
907 // promotion takes the place of the canonicalize.
908 unsigned NumOps = 3;
909 if (const IntrinsicInst *II = ICA.getInst()) {
910 // Directly legal with ieee=0
911 // TODO: Not directly legal with strictfp
913 NumOps = 1;
914 }
915
916 unsigned BaseRate =
917 SLT == MVT::f64 ? get64BitInstrCost(CostKind) : getFullRateInstrCost();
918 InstRate = BaseRate * NumOps;
919 break;
920 }
921 case Intrinsic::canonicalize: {
922 InstRate =
923 SLT == MVT::f64 ? get64BitInstrCost(CostKind) : getFullRateInstrCost();
924 break;
925 }
926 case Intrinsic::uadd_sat:
927 case Intrinsic::usub_sat:
928 case Intrinsic::sadd_sat:
929 case Intrinsic::ssub_sat: {
930 if (SLT == MVT::i16 || SLT == MVT::i32)
931 InstRate = getFullRateInstrCost();
932
933 static const auto ValidSatTys = {MVT::v2i16, MVT::v4i16};
934 if (any_of(ValidSatTys, equal_to(LT.second)))
935 NElts = 1;
936 break;
937 }
938 case Intrinsic::abs:
939 // Expansion takes 2 instructions for VALU
940 if (SLT == MVT::i16 || SLT == MVT::i32)
941 InstRate = 2 * getFullRateInstrCost();
942 break;
943 default:
944 break;
945 }
946
947 return LT.first * NElts * InstRate;
948}
949
951 TTI::TargetCostKind CostKind,
952 const Instruction *I) const {
953 assert((I == nullptr || I->getOpcode() == Opcode) &&
954 "Opcode should reflect passed instruction.");
955 const bool SCost =
956 (CostKind == TTI::TCK_CodeSize || CostKind == TTI::TCK_SizeAndLatency);
957 const int CBrCost = SCost ? 5 : 7;
958 switch (Opcode) {
959 case Instruction::UncondBr:
960 // Branch instruction takes about 4 slots on gfx900.
961 return SCost ? 1 : 4;
962 case Instruction::CondBr:
963 // Suppose conditional branch takes additional 3 exec manipulations
964 // instructions in average.
965 return CBrCost;
966 case Instruction::Switch: {
967 const auto *SI = dyn_cast_or_null<SwitchInst>(I);
968 // Each case (including default) takes 1 cmp + 1 cbr instructions in
969 // average.
970 return (SI ? (SI->getNumCases() + 1) : 4) * (CBrCost + 1);
971 }
972 case Instruction::Ret:
973 return SCost ? 1 : 10;
974 }
975 return BaseT::getCFInstrCost(Opcode, CostKind, I);
976}
977
979 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
981 TTI::OperandValueInfo Op2Info, const Instruction *I) const {
982 // For size and latency cost kinds, return a low cost independent of vector
983 // width to enable SimplifyCFG's speculativelyExecuteBB optimization.
984 if (CostKind == TTI::TCK_SizeAndLatency)
985 return 1;
986
987 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
988 Op1Info, Op2Info, I);
989}
990
991// Measured packing cost of i1 for gfx9-12 is 4.0 to 4.8, up to 5.4 with
992// true16; unpacking is 2.6 to 2.9.
993static constexpr unsigned MaskPackCostPerElt = 4;
994static constexpr unsigned MaskUnpackCostPerElt = 3;
995
996static std::optional<unsigned> getNumberOfPackedMaskElts(Type *Ty) {
997 auto *FVT = dyn_cast<FixedVectorType>(Ty);
998 if (FVT && FVT->getElementType()->isIntegerTy(1) && FVT->getNumElements() > 1)
999 return FVT->getNumElements();
1000 return std::nullopt;
1001}
1002
1004 Type *Src,
1006 TTI::TargetCostKind CostKind,
1007 const Instruction *I) const {
1008 // A bitcast between a vector of i1 and an integer packs or unpacks a mask.
1009 if (Opcode == Instruction::BitCast) {
1010 if (std::optional<unsigned> Elts = getNumberOfPackedMaskElts(Src);
1011 Elts && Dst->isIntegerTy(*Elts))
1012 return InstructionCost(MaskPackCostPerElt) * *Elts *
1013 getFullRateInstrCost();
1014 if (std::optional<unsigned> Elts = getNumberOfPackedMaskElts(Dst);
1015 Elts && Src->isIntegerTy(*Elts))
1016 return InstructionCost(MaskUnpackCostPerElt) * *Elts *
1017 getFullRateInstrCost();
1018 }
1019
1020 // Each f32 lane is rounded and the halves are packed in pairs. A packed
1021 // conversion rounds a pair at once and true16 writes either half.
1022 if (auto *SrcVTy = dyn_cast<FixedVectorType>(Src);
1023 SrcVTy && Opcode == Instruction::FPTrunc && ST->has16BitInsts() &&
1024 SrcVTy->getElementType()->isFloatTy() &&
1025 Dst->getScalarType()->isHalfTy()) {
1026 const unsigned NElts = SrcVTy->getNumElements();
1027 const unsigned Ops = ST->hasCvtPkF16F32Inst() ? divideCeil(NElts, 2)
1028 : ST->useRealTrue16Insts() ? NElts
1029 : NElts + NElts / 2;
1030 return InstructionCost(Ops) * getFullRateInstrCost();
1031 }
1032
1033 const int ISD = TLI->InstructionOpcodeToISD(Opcode);
1034 switch (ISD) {
1035 case ISD::SINT_TO_FP:
1036 case ISD::UINT_TO_FP:
1037 case ISD::FP_TO_SINT:
1038 case ISD::FP_TO_UINT:
1039 break;
1040 default:
1041 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1042 }
1043
1044 const bool IsIntToFP = ISD == ISD::SINT_TO_FP || ISD == ISD::UINT_TO_FP;
1045 Type *FPTy = (IsIntToFP ? Dst : Src)->getScalarType();
1046 if (!FPTy->isHalfTy() && !FPTy->isBFloatTy() && !FPTy->isFloatTy() &&
1047 !FPTy->isDoubleTy())
1048 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1049
1050 unsigned NElts = 1;
1051 if (auto *VT = dyn_cast<FixedVectorType>(Src))
1052 NElts = VT->getNumElements();
1053
1054 const unsigned SrcBits = Src->getScalarSizeInBits();
1055 const unsigned DstBits = Dst->getScalarSizeInBits();
1056 const bool IsSigned = ISD == ISD::SINT_TO_FP || ISD == ISD::FP_TO_SINT;
1057 const unsigned IntBits = IsIntToFP ? SrcBits : DstBits;
1058 const bool UsesInt64 = IntBits > 32 && IntBits <= 64;
1059
1060 auto Scale = [&](unsigned FullRateOps,
1061 unsigned FP64Ops = 0) -> InstructionCost {
1062 return NElts * (InstructionCost(FullRateOps) * getFullRateInstrCost() +
1063 InstructionCost(FP64Ops) * get64BitInstrCost(CostKind));
1064 };
1065
1066 if (IsIntToFP) {
1067 // A scalar load of a whole number of bytes that is not a power of two is
1068 // split and its high part load extends the source. A constant address
1069 // space or invariant global load aligned to 4 bytes may be widened instead
1070 // and then still needs the extension. So does a buffer fat pointer load.
1071 const auto *Load =
1072 I && Src->isIntegerTy() && I->getOperand(0)->getType() == Src
1073 ? dyn_cast<LoadInst>(I->getOperand(0))
1074 : nullptr;
1075 const unsigned AS = Load ? Load->getPointerAddressSpace() : 0;
1076 const bool LoadMayWiden =
1077 Load && Load->getAlign() >= Align(4) &&
1080 (AS == AMDGPUAS::GLOBAL_ADDRESS &&
1081 Load->hasMetadata(LLVMContext::MD_invariant_load)));
1082 const bool LoadExtends = Load && Load->isSimple() && Load->hasOneUse() &&
1083 !LoadMayWiden &&
1086 SrcBits % 8 == 0 && !isPowerOf2_32(SrcBits);
1087 const unsigned ExtOps =
1088 UsesInt64 && SrcBits < 64 && !LoadExtends ? (IsSigned ? 2 : 1) : 0;
1089 if (FPTy->isBFloatTy()) {
1090 if (SrcBits < 8 || (SrcBits > 32 && !UsesInt64))
1091 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1092
1093 // Each integer is converted to f32 first.
1094 InstructionCost FloatCost =
1095 Scale(UsesInt64 ? ExtOps + (IsSigned ? 12 : 8) : 1);
1096 if (SrcBits < 32)
1097 FloatCost = getCastInstrCost(
1098 Opcode, Dst->getWithNewType(Type::getFloatTy(Dst->getContext())),
1099 Src, CCH, CostKind, I);
1100
1101 // Native rounding can convert a pair. With 16 bit instructions the
1102 // expansion extracts the low significand bit, adds the rounding bias,
1103 // preserves NaNs and shifts the result. Without gfx9 instructions the two
1104 // additions cannot use v_add3_u32.
1105 InstructionCost RoundCost =
1106 ST->hasBF16ConversionInsts()
1107 ? InstructionCost(divideCeil(NElts, 2)) * getFullRateInstrCost()
1108 : Scale(!ST->has16BitInsts() ? 1
1109 : ST->hasGFX9Insts() ? 6
1110 : 7);
1111 return FloatCost + RoundCost;
1112 }
1113
1114 // No instruction converts from a 64 bit integer.
1115 if (UsesInt64) {
1116 if (FPTy->isDoubleTy()) {
1117 // Two conversions, ldexp and add, all using the FP64 rate.
1118 return Scale(ExtOps, 4);
1119 }
1120 if (FPTy->isFloatTy())
1121 return Scale(ExtOps + (IsSigned ? 12 : 8));
1122 return Scale(ExtOps + (IsSigned ? 13 : 9));
1123 }
1124
1125 // A narrow vector source is converted lane by lane.
1126 if (SrcBits >= 8 && SrcBits < 32 && isa<FixedVectorType>(Src)) {
1127 if (FPTy->isDoubleTy())
1128 return Scale(1 + (SrcBits < 16 && IsSigned && ST->has16BitInsts()), 1);
1129 if (FPTy->isHalfTy()) {
1130 const InstructionCost PairCost =
1131 InstructionCost(NElts / 2) * getFullRateInstrCost();
1132 // Lanes wider than 16 bits, and every lane without 16 bit instructions,
1133 // are converted to f32 first. With the packed conversion each pair is
1134 // then converted at once. Otherwise each lane is converted, and without
1135 // real true16 each pair of halves is packed.
1136 if (!ST->has16BitInsts() || SrcBits > 16) {
1137 auto *FloatTy =
1138 FixedVectorType::get(Type::getFloatTy(Dst->getContext()), NElts);
1139 const InstructionCost FloatCost =
1140 getCastInstrCost(Opcode, FloatTy, Src, CCH, CostKind);
1141 if (ST->has16BitInsts() && ST->hasCvtPkF16F32Inst())
1142 return FloatCost + InstructionCost(divideCeil(NElts, 2)) *
1143 getFullRateInstrCost();
1144 const unsigned PackOps =
1145 !ST->has16BitInsts() ? 2 : !ST->useRealTrue16Insts();
1146 return FloatCost + Scale(1) + PackOps * PairCost;
1147 }
1148 // Each lane is converted from a 16 bit subword. Lanes narrower than 16
1149 // bits are extended lane by lane, except bytes with SDWA. Signed bytes
1150 // are sign extended a pair at a time. Real true16 reads the high
1151 // subword in place, so only signed lanes narrower than 16 bits pay per
1152 // pair. Otherwise wider lanes shift the high subword of each pair down
1153 // without SDWA, and each pair of halves is packed.
1154 const unsigned PerElt =
1155 1 + (SrcBits == 8 ? !ST->hasSDWA() : SrcBits < 16);
1156 const bool RealTrue16 = ST->useRealTrue16Insts();
1157 const unsigned PerPair =
1158 !RealTrue16 + (SrcBits == 8 || RealTrue16 ? SrcBits < 16 && IsSigned
1159 : !ST->hasSDWA());
1160 return Scale(PerElt) + PerPair * PairCost;
1161 }
1162 // An unsigned byte is converted straight out of its register.
1163 if (SrcBits == 8 && !IsSigned)
1164 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1165 if (SrcBits < 16 && !IsSigned)
1166 return Scale(2);
1167 unsigned PerElt = ST->hasSDWA() && SrcBits <= 16 ? 1 : 2;
1168 if (SrcBits < 16 && ST->has16BitInsts())
1169 ++PerElt;
1170 return Scale(PerElt);
1171 }
1172
1173 // A narrow scalar source is extended before the conversion. An unsigned
1174 // byte is converted straight out of its register, and a signed one with
1175 // SDWA. A source wider than a byte but narrower than 16 bits is masked
1176 // or sign extended first. Without 16 bit instructions a half result is
1177 // rounded from f32.
1178 if (SrcBits >= 8 && SrcBits < 32) {
1179 if (LoadExtends) {
1180 if (FPTy->isDoubleTy())
1181 return Scale(0, 1);
1182 return Scale(FPTy->isHalfTy() ? 2 : 1);
1183 }
1184 const bool Narrow = SrcBits > 8 && SrcBits < 16;
1185 const bool SignExtend16 = IsSigned && Narrow && ST->has16BitInsts();
1186 if (FPTy->isDoubleTy())
1187 return Scale(1 + 2 * SignExtend16, 1);
1188 if (SrcBits > 16)
1189 return Scale(FPTy->isHalfTy() ? 3 : 2);
1190 if (FPTy->isHalfTy() && ST->has16BitInsts())
1191 return Scale(Narrow ? (IsSigned ? 3 : 2)
1192 : SrcBits == 8 && !ST->hasSDWA() ? 2
1193 : 1);
1194 const InstructionCost FloatCost =
1195 SignExtend16 ? Scale(ST->hasSDWA() ? 3 : 4)
1196 : Narrow ? Scale(2)
1197 : SrcBits == 8 && !IsSigned ? Scale(1)
1198 : Scale(ST->hasSDWA() ? 1 : 2);
1199 return FPTy->isHalfTy() ? FloatCost + Scale(1) : FloatCost;
1200 }
1201
1202 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1203 }
1204
1205 // No instruction converts to a 64 bit integer.
1206 if (UsesInt64) {
1207 const bool IsSigned64 = IsSigned || (DstBits < 64 && NElts == 1);
1208 if (FPTy->isDoubleTy()) {
1209 // With native trunc/floor there are six FP64 operations. The expanded
1210 // rounding sequence has seven, plus integer operations and constants.
1211 return ST->haveRoundOpsF64() ? Scale(1, 6) : Scale(22, 7);
1212 }
1213 // The f32 expansion has one fma, which is quarter rate without fast FMA.
1214 const InstructionCost SlowFMACost =
1215 ST->hasFastFMAF32() ? 0
1216 : NElts * (getQuarterRateInstrCost(CostKind) -
1217 getFullRateInstrCost());
1218 if (FPTy->isFloatTy())
1219 return Scale(IsSigned64 ? 13 : 6) + SlowFMACost;
1220 if (FPTy->isBFloatTy()) {
1221 // Unlike half, bf16 does not fit in i32. Extend to f32 and use the full
1222 // i64 expansion.
1223 return Scale(1 + (IsSigned64 ? 13 : 6)) + SlowFMACost;
1224 }
1225 return Scale(3);
1226 }
1227
1228 return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1229}
1230
1233 std::optional<FastMathFlags> FMF,
1234 TTI::TargetCostKind CostKind) const {
1236 return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
1237
1238 // An add or xor reduction over a vector of i1 becomes a bit count over the
1239 // packed mask; the generic model prices a shuffle tree and misses that.
1240 if (Opcode == Instruction::Add || Opcode == Instruction::Xor) {
1241 if (std::optional<unsigned> Elts = getNumberOfPackedMaskElts(Ty))
1242 return InstructionCost(MaskPackCostPerElt) * *Elts *
1243 getFullRateInstrCost();
1244 }
1245
1246 EVT OrigTy = TLI->getValueType(DL, Ty);
1247
1248 // Computes cost on targets that have packed math instructions(which support
1249 // 16-bit types only).
1250 if (!ST->hasVOP3PInsts() || OrigTy.getScalarSizeInBits() != 16)
1251 return BaseT::getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
1252
1253 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
1254 return LT.first * getFullRateInstrCost();
1255}
1256
1259 FastMathFlags FMF,
1260 TTI::TargetCostKind CostKind) const {
1261 EVT OrigTy = TLI->getValueType(DL, Ty);
1262
1263 // Computes cost on targets that have packed math instructions(which support
1264 // 16-bit types only).
1265 if (!ST->hasVOP3PInsts() || OrigTy.getScalarSizeInBits() != 16)
1266 return BaseT::getMinMaxReductionCost(IID, Ty, FMF, CostKind);
1267
1268 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
1269 return LT.first * getHalfRateInstrCost(CostKind);
1270}
1271
1273 unsigned Opcode, Type *ValTy, TTI::TargetCostKind CostKind, unsigned Index,
1274 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
1275 switch (Opcode) {
1276 case Instruction::ExtractElement:
1277 case Instruction::InsertElement: {
1278 TypeSize EltSize =
1279 DL.getTypeSizeInBits(cast<VectorType>(ValTy)->getElementType());
1280 // Dynamic indexing isn't free and is best avoided.
1281 if (Index == ~0u)
1282 return 2;
1283 if (EltSize < 32) {
1284 if (EltSize == 16 && Index == 0 && ST->has16BitInsts())
1285 return 0;
1286 // Inserts of booleans are free.
1287 // TODO: Extracts are free too.
1288 if (EltSize == 1 && Opcode == Instruction::InsertElement)
1290 // Extract element sequences of consecutive i8 values that match a
1291 // register size are free most likely. It is not possible to know
1292 // if this extract is part of a consecutive sequence so this may
1293 // apply more generally.
1294 if (Opcode == Instruction::ExtractElement && EltSize == 8) {
1295 if (auto *FVTy = dyn_cast<FixedVectorType>(ValTy)) {
1296 unsigned NumElts = FVTy->getNumElements();
1297 if (NumElts >= 4 && isPowerOf2_32(NumElts))
1298 return 0;
1299 }
1300 }
1301 return BaseT::getVectorInstrCost(Opcode, ValTy, CostKind, Index, Op0, Op1,
1302 VIC);
1303 }
1304
1305 // Packed f32 pair formation for v_pk_*_f32. A constant-index insert writes
1306 // one subregister, so a lane holding a computed value costs at most one
1307 // v_mov_b32 at any width. A loaded lane lands in place, and arguments and
1308 // constants are already in a register, so both are free. SLP prices a
1309 // buildvector root with the insertelements themselves as Op1, and those
1310 // lanes need no packing either. Only throughput sees the move; size-based
1311 // users such as the inliner and the unroller keep inserts free.
1312 auto *VecTy = dyn_cast<FixedVectorType>(ValTy);
1313 const auto *InsertedInst = dyn_cast_or_null<Instruction>(Op1);
1314 if (Opcode == Instruction::InsertElement && EltSize == 32 &&
1315 CostKind == TTI::TCK_RecipThroughput && ST->hasAnyPackedFP32Ops() &&
1316 InsertedInst && VecTy && VecTy->getElementType()->isFloatTy() &&
1317 !isa<LoadInst, InsertElementInst>(InsertedInst))
1318 return getFullRateInstrCost();
1319
1320 // Extracts are just reads of a subregister, so are free. Inserts are
1321 // considered free because we don't want to have any cost for scalarizing
1322 // operations, and we don't have to copy into a different register class.
1323 return 0;
1324 }
1325 default:
1326 return BaseT::getVectorInstrCost(Opcode, ValTy, CostKind, Index, Op0, Op1,
1327 VIC);
1328 }
1329}
1330
1331/// Analyze if the results of inline asm are divergent. If \p Indices is empty,
1332/// this is analyzing the collective result of all output registers. Otherwise,
1333/// this is only querying a specific result index if this returns multiple
1334/// registers in a struct.
1336 const CallBase *CB, ArrayRef<unsigned> Indices) const {
1337 // TODO: Handle complex extract indices
1338 if (Indices.size() > 1)
1339 return true;
1340
1341 const DataLayout &DL = CB->getDataLayout();
1342 const SIRegisterInfo *TRI = ST->getRegisterInfo();
1343 TargetLowering::AsmOperandInfoVector TargetConstraints =
1344 TLI->ParseConstraints(DL, ST->getRegisterInfo(), *CB);
1345
1346 const int TargetOutputIdx = Indices.empty() ? -1 : Indices[0];
1347
1348 int OutputIdx = 0;
1349 for (auto &TC : TargetConstraints) {
1350 if (TC.Type != InlineAsm::isOutput)
1351 continue;
1352
1353 // Skip outputs we don't care about.
1354 if (TargetOutputIdx != -1 && TargetOutputIdx != OutputIdx++)
1355 continue;
1356
1357 TLI->ComputeConstraintToUse(TC, SDValue());
1358
1359 const TargetRegisterClass *RC = TLI->getRegForInlineAsmConstraint(
1360 TRI, TC.ConstraintCode, TC.ConstraintVT).second;
1361
1362 // For AGPR constraints null is returned on subtargets without AGPRs, so
1363 // assume divergent for null.
1364 if (!RC || !TRI->isSGPRClass(RC))
1365 return true;
1366 }
1367
1368 return false;
1369}
1370
1372 const IntrinsicInst *ReadReg) const {
1373 Metadata *MD =
1374 cast<MetadataAsValue>(ReadReg->getArgOperand(0))->getMetadata();
1376 cast<MDString>(cast<MDNode>(MD)->getOperand(0))->getString();
1377
1378 // Special case registers that look like VCC.
1379 MVT VT = MVT::getVT(ReadReg->getType());
1380 if (VT == MVT::i1)
1381 return true;
1382
1383 // Special case scalar registers that start with 'v'.
1384 if (RegName.starts_with("vcc") || RegName.empty())
1385 return false;
1386
1387 // VGPR or AGPR is divergent. There aren't any specially named vector
1388 // registers.
1389 return RegName[0] == 'v' || RegName[0] == 'a';
1390}
1391
1392/// \returns true if the result of the value could potentially be
1393/// different across workitems in a wavefront.
1394bool GCNTTIImpl::isSourceOfDivergence(const Value *V) const {
1395 if (const Argument *A = dyn_cast<Argument>(V))
1397
1398 // Loads from the private and flat address spaces are divergent, because
1399 // threads can execute the load instruction with the same inputs and get
1400 // different results.
1401 //
1402 // All other loads are not divergent, because if threads issue loads with the
1403 // same arguments, they will always get the same result.
1404 if (const LoadInst *Load = dyn_cast<LoadInst>(V))
1405 return Load->getPointerAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS ||
1406 Load->getPointerAddressSpace() == AMDGPUAS::FLAT_ADDRESS;
1407
1408 // Atomics are divergent because they are executed sequentially: when an
1409 // atomic operation refers to the same address in each thread, then each
1410 // thread after the first sees the value written by the previous thread as
1411 // original value.
1413 return true;
1414
1416 Intrinsic::ID IID = Intrinsic->getIntrinsicID();
1417 switch (IID) {
1418 case Intrinsic::read_register:
1420 case Intrinsic::amdgcn_workitem_id_y:
1421 case Intrinsic::amdgcn_workitem_id_z: {
1422 const Function *F = Intrinsic->getFunction();
1423 bool HasUniformYZ =
1424 ST->hasWavefrontsEvenlySplittingXDim(*F, /*RequiresUniformYZ=*/true);
1425 std::optional<unsigned> ThisDimSize = ST->getReqdWorkGroupSize(
1426 *F, IID == Intrinsic::amdgcn_workitem_id_y ? 1 : 2);
1427 return !HasUniformYZ && (!ThisDimSize || *ThisDimSize != 1);
1428 }
1429 default:
1431 }
1432 }
1433
1434 // Assume all function calls are a source of divergence.
1435 if (const CallBase *CB = dyn_cast<CallBase>(V)) {
1436 if (CB->isInlineAsm())
1438 return true;
1439 }
1440
1441 // Assume all function calls are a source of divergence.
1442 if (isa<InvokeInst>(V))
1443 return true;
1444
1445 // If the target supports globally addressable scratch, the mapping from
1446 // scratch memory to the flat aperture changes therefore an address space cast
1447 // is no longer uniform.
1448 if (auto *CastI = dyn_cast<AddrSpaceCastInst>(V)) {
1449 return CastI->getSrcAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS &&
1450 CastI->getDestAddressSpace() == AMDGPUAS::FLAT_ADDRESS &&
1451 ST->hasGloballyAddressableScratch();
1452 }
1453
1454 return false;
1455}
1456
1457bool GCNTTIImpl::isAlwaysUniform(const Value *V) const {
1458 if (const IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(V))
1459 return AMDGPU::isIntrinsicAlwaysUniform(Intrinsic->getIntrinsicID());
1460
1461 if (const CallBase *CB = dyn_cast<CallBase>(V)) {
1462 if (CB->isInlineAsm())
1464 return false;
1465 }
1466
1467 // In most cases TID / wavefrontsize is uniform.
1468 //
1469 // However, if a kernel has uneven dimesions we can have a value of
1470 // workitem-id-x divided by the wavefrontsize non-uniform. For example
1471 // dimensions (65, 2) will have workitems with address (64, 0) and (0, 1)
1472 // packed into a same wave which gives 1 and 0 after the division by 64
1473 // respectively.
1474 //
1475 // The X dimension doesn't reset within a wave if either both the Y
1476 // and Z dimensions are of length 1, or if the X dimension's required
1477 // size is a power of 2. Note, however, if the X dimension's maximum
1478 // size is a power of 2 < the wavefront size, division by the wavefront
1479 // size is guaranteed to yield 0, so this is also a no-reset case.
1480 bool XDimDoesntResetWithinWaves = false;
1481 if (auto *I = dyn_cast<Instruction>(V)) {
1482 const Function *F = I->getFunction();
1483 XDimDoesntResetWithinWaves = ST->hasWavefrontsEvenlySplittingXDim(*F);
1484 }
1485 using namespace llvm::PatternMatch;
1486 uint64_t C;
1487 auto MatchTidXCall = m_Intrinsic<Intrinsic::amdgcn_workitem_id_x>();
1488 auto MaybeMaskedTidX =
1489 m_CombineOr(m_c_And(MatchTidXCall, m_Constant()), MatchTidXCall);
1490 auto MaybeCastTidX = m_CastOrSelf(MaybeMaskedTidX);
1491 auto MaybeMaskedCastTidX =
1492 m_CombineOr(m_c_And(MaybeCastTidX, m_Constant()), MaybeCastTidX);
1493 if (match(V, m_LShr(MaybeMaskedCastTidX, m_ConstantInt(C))))
1494 return C >= ST->getWavefrontSizeLog2() && XDimDoesntResetWithinWaves;
1495
1496 Constant *Mask;
1497 if (match(V, m_c_And(
1499 m_Constant(Mask)))) {
1500 return computeKnownBits(Mask, DL).countMinTrailingZeros() >=
1501 ST->getWavefrontSizeLog2() &&
1502 XDimDoesntResetWithinWaves;
1503 }
1504
1505 const ExtractValueInst *ExtValue = dyn_cast<ExtractValueInst>(V);
1506 if (!ExtValue)
1507 return false;
1508
1509 const CallBase *CB = dyn_cast<CallBase>(ExtValue->getOperand(0));
1510 if (!CB)
1511 return false;
1512
1513 if (const IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(CB)) {
1514 switch (Intrinsic->getIntrinsicID()) {
1515 default:
1516 return false;
1517 case Intrinsic::amdgcn_if:
1518 case Intrinsic::amdgcn_else: {
1519 ArrayRef<unsigned> Indices = ExtValue->getIndices();
1520 return Indices.size() == 1 && Indices[0] == 1;
1521 }
1522 }
1523 }
1524
1525 // If we have inline asm returning mixed SGPR and VGPR results, we inferred
1526 // divergent for the overall struct return. We need to override it in the
1527 // case we're extracting an SGPR component here.
1528 if (CB->isInlineAsm())
1529 return !isInlineAsmSourceOfDivergence(CB, ExtValue->getIndices());
1530
1531 return false;
1532}
1533
1535 Intrinsic::ID IID) const {
1536 switch (IID) {
1537 case Intrinsic::amdgcn_is_shared:
1538 case Intrinsic::amdgcn_is_private:
1539 case Intrinsic::amdgcn_flat_atomic_fmax_num:
1540 case Intrinsic::amdgcn_flat_atomic_fmin_num:
1541 case Intrinsic::amdgcn_load_to_lds:
1542 case Intrinsic::amdgcn_make_buffer_rsrc:
1543 case Intrinsic::amdgcn_flat_prefetch:
1544 OpIndexes.push_back(0);
1545 return true;
1546 default:
1547 return false;
1548 }
1549}
1550
1552 Value *OldV,
1553 Value *NewV) const {
1554 auto IntrID = II->getIntrinsicID();
1555 switch (IntrID) {
1556 case Intrinsic::amdgcn_is_shared:
1557 case Intrinsic::amdgcn_is_private: {
1558 unsigned TrueAS = IntrID == Intrinsic::amdgcn_is_shared ?
1560 unsigned NewAS = NewV->getType()->getPointerAddressSpace();
1561 LLVMContext &Ctx = NewV->getType()->getContext();
1562 ConstantInt *NewVal = (TrueAS == NewAS) ?
1564 return NewVal;
1565 }
1566 case Intrinsic::amdgcn_flat_atomic_fmax_num:
1567 case Intrinsic::amdgcn_flat_atomic_fmin_num: {
1568 Type *DestTy = II->getType();
1569 Type *SrcTy = NewV->getType();
1570 unsigned NewAS = SrcTy->getPointerAddressSpace();
1572 return nullptr;
1573 Module *M = II->getModule();
1575 M, II->getIntrinsicID(), {DestTy, SrcTy, DestTy});
1576 II->setArgOperand(0, NewV);
1577 II->setCalledFunction(NewDecl);
1578 return II;
1579 }
1580 case Intrinsic::amdgcn_load_to_lds: {
1581 Type *SrcTy = NewV->getType();
1582 Module *M = II->getModule();
1583 Function *NewDecl =
1584 Intrinsic::getOrInsertDeclaration(M, II->getIntrinsicID(), {SrcTy});
1585 II->setArgOperand(0, NewV);
1586 II->setCalledFunction(NewDecl);
1587 return II;
1588 }
1589 case Intrinsic::amdgcn_make_buffer_rsrc: {
1590 Type *SrcTy = NewV->getType();
1591 Type *DstTy = II->getType();
1592 Type *NumRecordsTy = II->getArgOperand(2)->getType();
1593 Module *M = II->getModule();
1595 M, II->getIntrinsicID(), {DstTy, SrcTy, NumRecordsTy});
1596 II->setArgOperand(0, NewV);
1597 II->setCalledFunction(NewDecl);
1598 return II;
1599 }
1600 case Intrinsic::amdgcn_flat_prefetch: {
1601 unsigned NewAS = NewV->getType()->getPointerAddressSpace();
1603 return nullptr;
1604 // llvm.amdgcn.global.prefetch only takes a global pointer.
1605 if (NewAS != AMDGPUAS::GLOBAL_ADDRESS)
1606 NewV = IRBuilder<>(II).CreateAddrSpaceCast(
1607 NewV, PointerType::get(II->getContext(), AMDGPUAS::GLOBAL_ADDRESS));
1609 II->getModule(), Intrinsic::amdgcn_global_prefetch);
1610 II->setArgOperand(0, NewV);
1611 II->setCalledFunction(NewDecl);
1612 return II;
1613 }
1614 default:
1615 return nullptr;
1616 }
1617}
1618
1620 TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
1621 TTI::TargetCostKind CostKind, ArrayRef<int> Mask, int Index,
1622 VectorType *SubTp, ArrayRef<const Value *> Args, const Instruction *CtxI,
1623 TTI::VectorInstrContext VIC) const {
1624 if (!isa<FixedVectorType>(SrcTy))
1625 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
1626 SubTp);
1627
1628 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1629
1630 TypeSize ScalarSize = DL.getTypeSizeInBits(SrcTy->getElementType());
1631
1632 // A v_pk_*_f32 operand is an aligned register pair. A lane already in its
1633 // half of a source pair is read in place, and a splat of the low half is an
1634 // op_sel_hi. Every other lane costs a v_mov_b32 to move it into place.
1635 if (ScalarSize == 32 && CostKind == TTI::TCK_RecipThroughput &&
1636 ST->hasAnyPackedFP32Ops() && SrcTy->getElementType()->isFloatTy() &&
1637 !Mask.empty()) {
1638 const int NumSrcElts = cast<FixedVectorType>(SrcTy)->getNumElements();
1639 // Source pairs of the second operand are numbered after the first.
1640 auto GetPair = [&](int Idx) {
1641 return Idx < NumSrcElts ? Idx / 2 : NumSrcElts + (Idx - NumSrcElts) / 2;
1642 };
1643 auto GetHalf = [&](int Idx) {
1644 return Idx < NumSrcElts ? Idx % 2 : (Idx - NumSrcElts) % 2;
1645 };
1646 unsigned Cost = 0;
1647 for (unsigned DstIdx = 0; DstIdx < Mask.size(); DstIdx += 2) {
1648 const int Lo = Mask[DstIdx];
1649 const int Hi =
1650 DstIdx + 1 < Mask.size() ? Mask[DstIdx + 1] : PoisonMaskElem;
1651 const bool LoInPlace = Lo != PoisonMaskElem && GetHalf(Lo) == 0;
1652 const bool HiInPlace = Hi != PoisonMaskElem && GetHalf(Hi) == 1;
1653 if (Lo != PoisonMaskElem && Lo == Hi && LoInPlace)
1654 continue;
1655 if (LoInPlace && HiInPlace)
1656 Cost += GetPair(Lo) != GetPair(Hi);
1657 else
1658 Cost += (Lo != PoisonMaskElem && !LoInPlace) +
1659 (Hi != PoisonMaskElem && !HiInPlace);
1660 }
1661 return Cost;
1662 }
1663
1664 if (ST->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS &&
1665 (ScalarSize == 16 || ScalarSize == 8)) {
1666 // Larger vector widths may require additional instructions, but are
1667 // typically cheaper than scalarized versions.
1668 //
1669 // We assume that shuffling at a register granularity can be done for free.
1670 // This is not true for vectors fed into memory instructions, but it is
1671 // effectively true for all other shuffling. The emphasis of the logic here
1672 // is to assist generic transform in cleaning up / canonicalizing those
1673 // shuffles.
1674
1675 // With op_sel VOP3P instructions freely can access the low half or high
1676 // half of a register, so any swizzle of two elements is free.
1677 if (auto *SrcVecTy = dyn_cast<FixedVectorType>(SrcTy)) {
1678 unsigned NumSrcElts = SrcVecTy->getNumElements();
1679 if (ST->hasVOP3PInsts() && ScalarSize == 16 && NumSrcElts == 2 &&
1680 (Kind == TTI::SK_Broadcast || Kind == TTI::SK_Reverse ||
1681 Kind == TTI::SK_PermuteSingleSrc))
1682 return 0;
1683 }
1684
1685 unsigned EltsPerReg = 32 / static_cast<unsigned>(ScalarSize);
1686 switch (Kind) {
1687 case TTI::SK_Broadcast:
1688 // A single v_perm_b32 can be re-used for all destination registers.
1689 return 1;
1690 case TTI::SK_Reverse:
1691 // One instruction per register.
1692 if (auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy))
1693 return divideCeil(DstVecTy->getNumElements(), EltsPerReg);
1696 if (Index % EltsPerReg == 0)
1697 return 0; // Shuffling at register granularity
1698 if (auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy))
1699 return divideCeil(DstVecTy->getNumElements(), EltsPerReg);
1702 auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy);
1703 if (!DstVecTy)
1705 unsigned NumDstElts = DstVecTy->getNumElements();
1706 unsigned NumInsertElts = cast<FixedVectorType>(SubTp)->getNumElements();
1707 unsigned EndIndex = Index + NumInsertElts;
1708 unsigned BeginSubIdx = Index % EltsPerReg;
1709 unsigned EndSubIdx = EndIndex % EltsPerReg;
1711
1712 if (BeginSubIdx != 0) {
1713 // Need to shift the inserted vector into place. The cost is the number
1714 // of destination registers overlapped by the inserted vector.
1715 Cost = divideCeil(EndIndex, EltsPerReg) - (Index / EltsPerReg);
1716 }
1717
1718 // If the last register overlap is partial, there may be three source
1719 // registers feeding into it; that takes an extra instruction.
1720 if (EndIndex < NumDstElts && BeginSubIdx < EndSubIdx)
1721 Cost += 1;
1722
1723 return Cost;
1724 }
1725 case TTI::SK_Splice: {
1726 auto *DstVecTy = dyn_cast<FixedVectorType>(DstTy);
1727 if (!DstVecTy)
1729 unsigned NumElts = DstVecTy->getNumElements();
1730 assert(NumElts == cast<FixedVectorType>(SrcTy)->getNumElements());
1731 // Determine the sub-region of the result vector that requires
1732 // sub-register shuffles / mixing.
1733 unsigned EltsFromLHS = NumElts - Index;
1734 bool LHSIsAligned = (Index % EltsPerReg) == 0;
1735 bool RHSIsAligned = (EltsFromLHS % EltsPerReg) == 0;
1736 if (LHSIsAligned && RHSIsAligned)
1737 return 0;
1738 if (LHSIsAligned && !RHSIsAligned)
1739 return divideCeil(NumElts, EltsPerReg) - (EltsFromLHS / EltsPerReg);
1740 if (!LHSIsAligned && RHSIsAligned)
1741 return divideCeil(EltsFromLHS, EltsPerReg);
1742 return divideCeil(NumElts, EltsPerReg);
1743 }
1744 default:
1745 break;
1746 }
1747
1748 if (!Mask.empty()) {
1749 unsigned NumSrcElts = cast<FixedVectorType>(SrcTy)->getNumElements();
1750
1751 // Generically estimate the cost by assuming that each destination
1752 // register is derived from sources via v_perm_b32 instructions if it
1753 // can't be copied as-is.
1754 //
1755 // For each destination register, derive the cost of obtaining it based
1756 // on the number of source registers that feed into it.
1758 for (unsigned DstIdx = 0; DstIdx < Mask.size(); DstIdx += EltsPerReg) {
1760 bool Aligned = true;
1761 for (unsigned I = 0; I < EltsPerReg && DstIdx + I < Mask.size(); ++I) {
1762 int SrcIdx = Mask[DstIdx + I];
1763 if (SrcIdx == -1)
1764 continue;
1765 int Reg;
1766 if (SrcIdx < (int)NumSrcElts) {
1767 Reg = SrcIdx / EltsPerReg;
1768 if (SrcIdx % EltsPerReg != I)
1769 Aligned = false;
1770 } else {
1771 Reg = NumSrcElts + (SrcIdx - NumSrcElts) / EltsPerReg;
1772 if ((SrcIdx - NumSrcElts) % EltsPerReg != I)
1773 Aligned = false;
1774 }
1775 if (!llvm::is_contained(Regs, Reg))
1776 Regs.push_back(Reg);
1777 }
1778 if (Regs.size() >= 2)
1779 Cost += Regs.size() - 1;
1780 else if (!Aligned)
1781 Cost += 1;
1782 }
1783 return Cost;
1784 }
1785 }
1786
1787 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
1788 SubTp);
1789}
1790
1791/// Whether it is profitable to sink the operands of an
1792/// Instruction I to the basic block of I.
1793/// This helps using several modifiers (like abs and neg) more often.
1795 SmallVectorImpl<Use *> &Ops) const {
1796 using namespace PatternMatch;
1797
1798 // The cost model prices this fmul as free assuming it fuses with its
1799 // fadd/fsub user, which needs them in one block. Sink a stranded
1800 // loop-invariant fmul back to the user when they would fuse. Single use only,
1801 // so this stays a move.
1802 if (I->getOpcode() == Instruction::FAdd ||
1803 I->getOpcode() == Instruction::FSub) {
1804 const Instruction *FMul = getFusedFMul(*TLI, I->getType(), I);
1805 if (FMul && FMul->getParent() != I->getParent())
1806 Ops.push_back(&I->getOperandUse(I->getOperand(0) == FMul ? 0 : 1));
1807 }
1808
1809 for (auto &Op : I->operands()) {
1810 // Ensure we are not already sinking this operand.
1811 if (any_of(Ops, [&](Use *U) { return U->get() == Op.get(); }))
1812 continue;
1813
1814 // TODO: Confirm whether m_FNegOrFSubNegZero is correct.
1815 if (match(&Op, m_FAbs(m_Value())) ||
1817 Ops.push_back(&Op);
1818 continue;
1819 }
1820
1821 // Check for zero-cost multiple use InsertElement/ExtractElement
1822 // instructions
1823 if (Instruction *OpInst = dyn_cast<Instruction>(Op.get())) {
1824 if (OpInst->getType()->isVectorTy() && OpInst->getNumOperands() > 1) {
1825 Instruction *VecOpInst = dyn_cast<Instruction>(OpInst->getOperand(0));
1826 if (VecOpInst && VecOpInst->hasOneUse())
1827 continue;
1828
1829 if (getVectorInstrCost(OpInst->getOpcode(), OpInst->getType(),
1831 OpInst->getOperand(0),
1832 OpInst->getOperand(1)) == 0) {
1833 Ops.push_back(&Op);
1834 continue;
1835 }
1836 }
1837 }
1838
1839 if (auto *Shuffle = dyn_cast<ShuffleVectorInst>(Op.get())) {
1840
1841 TypeSize EltSize = DL.getTypeSizeInBits(
1842 cast<VectorType>(Shuffle->getType())->getElementType());
1843
1844 // For i32 (or greater) shufflevectors, these will be lowered into a
1845 // series of insert / extract elements, which will be coalesced away.
1846 if (EltSize < 16 || !ST->has16BitInsts())
1847 continue;
1848
1849 int NumSubElts, SubIndex;
1850 if (Shuffle->changesLength()) {
1851 if (Shuffle->increasesLength() && Shuffle->isIdentityWithPadding()) {
1852 Ops.push_back(&Op);
1853 continue;
1854 }
1855
1856 if ((Shuffle->isExtractSubvectorMask(SubIndex) ||
1857 Shuffle->isInsertSubvectorMask(NumSubElts, SubIndex)) &&
1858 !(SubIndex & 0x1)) {
1859 Ops.push_back(&Op);
1860 continue;
1861 }
1862 }
1863
1864 if (Shuffle->isReverse() || Shuffle->isZeroEltSplat() ||
1865 Shuffle->isSingleSource()) {
1866 Ops.push_back(&Op);
1867 continue;
1868 }
1869 }
1870 }
1871
1872 return !Ops.empty();
1873}
1874
1876 const Function *Callee) const {
1877 const TargetMachine &TM = getTLI()->getTargetMachine();
1878 const GCNSubtarget *CallerST
1879 = static_cast<const GCNSubtarget *>(TM.getSubtargetImpl(*Caller));
1880 const GCNSubtarget *CalleeST
1881 = static_cast<const GCNSubtarget *>(TM.getSubtargetImpl(*Callee));
1882
1883 if (!BaseT::areInlineCompatible(Caller, Callee))
1884 return false;
1885
1886 // FIXME: dx10_clamp can just take the caller setting, but there seems to be
1887 // no way to support merge for backend defined attributes.
1888 SIModeRegisterDefaults CallerMode(*Caller, *CallerST);
1889 SIModeRegisterDefaults CalleeMode(*Callee, *CalleeST);
1890 if (!CallerMode.isInlineCompatible(CalleeMode))
1891 return false;
1892
1893 if (Callee->hasFnAttribute(Attribute::AlwaysInline) ||
1894 Callee->hasFnAttribute(Attribute::InlineHint))
1895 return true;
1896
1897 // Hack to make compile times reasonable.
1898 if (CLOpts.inline_max_bb) {
1899 // Single BB does not increase total BB amount.
1900 if (Callee->size() == 1)
1901 return true;
1902 size_t BBSize = Caller->size() + Callee->size() - 1;
1903 if (BBSize > CLOpts.inline_max_bb) {
1904 LLVM_DEBUG(dbgs() << "AMDGPU inline max-BB rejected inlining "
1905 << Callee->getName() << " into " << Caller->getName()
1906 << ": caller BBs=" << Caller->size() << ", callee BBs="
1907 << Callee->size() << ", combined BBs=" << BBSize
1908 << ", max BBs=" << CLOpts.inline_max_bb << '\n');
1909 return false;
1910 }
1911 }
1912
1913 return true;
1914}
1915
1917 const SITargetLowering *TLI,
1918 const GCNTTIImpl *TTIImpl) {
1919 const int NrOfSGPRUntilSpill = 26;
1920 const int NrOfVGPRUntilSpill = 32;
1921
1922 const DataLayout &DL = TTIImpl->getDataLayout();
1923
1924 unsigned adjustThreshold = 0;
1925 int SGPRsInUse = 0;
1926 int VGPRsInUse = 0;
1927 for (const Use &A : CB->args()) {
1928 SmallVector<EVT, 4> ValueVTs;
1929 ComputeValueVTs(*TLI, DL, A.get()->getType(), ValueVTs);
1930 for (auto ArgVT : ValueVTs) {
1931 unsigned CCRegNum = TLI->getNumRegistersForCallingConv(
1932 CB->getContext(), CB->getCallingConv(), ArgVT);
1934 SGPRsInUse += CCRegNum;
1935 else
1936 VGPRsInUse += CCRegNum;
1937 }
1938 }
1939
1940 // The cost of passing function arguments through the stack:
1941 // 1 instruction to put a function argument on the stack in the caller.
1942 // 1 instruction to take a function argument from the stack in callee.
1943 // 1 instruction is explicitly take care of data dependencies in callee
1944 // function.
1945 InstructionCost ArgStackCost(1);
1946 ArgStackCost += const_cast<GCNTTIImpl *>(TTIImpl)->getMemoryOpCost(
1947 Instruction::Store, Type::getInt32Ty(CB->getContext()), Align(4),
1949 ArgStackCost += const_cast<GCNTTIImpl *>(TTIImpl)->getMemoryOpCost(
1950 Instruction::Load, Type::getInt32Ty(CB->getContext()), Align(4),
1952
1953 // The penalty cost is computed relative to the cost of instructions and does
1954 // not model any storage costs.
1955 int InstrCost = InlineConstants::getInstrCost(CB->getContext());
1956 adjustThreshold +=
1957 static_cast<unsigned>(std::max(0, SGPRsInUse - NrOfSGPRUntilSpill) *
1958 ArgStackCost.getValue() * InstrCost);
1959 adjustThreshold +=
1960 static_cast<unsigned>(std::max(0, VGPRsInUse - NrOfVGPRUntilSpill) *
1961 ArgStackCost.getValue() * InstrCost);
1962 return adjustThreshold;
1963}
1964
1966 const DataLayout &DL) {
1967 // If we have a pointer to a private array passed into a function
1968 // it will not be optimized out, leaving scratch usage.
1969 // This function calculates the total size in bytes of the memory that would
1970 // end in scratch if the call was not inlined.
1971 TypeSize AllocaSize = TypeSize::getFixed(0);
1973 for (Value *PtrArg : CB->args()) {
1974 PointerType *Ty = dyn_cast<PointerType>(PtrArg->getType());
1975 if (!Ty)
1976 continue;
1977
1978 unsigned AddrSpace = Ty->getAddressSpace();
1979 if (AddrSpace != AMDGPUAS::FLAT_ADDRESS &&
1980 AddrSpace != AMDGPUAS::PRIVATE_ADDRESS)
1981 continue;
1982
1984 if (!AI || !AI->isStaticAlloca() || !AIVisited.insert(AI).second)
1985 continue;
1986
1987 if (auto Size = AI->getAllocationSize(DL))
1988 AllocaSize += *Size;
1989 }
1990 return AllocaSize;
1991}
1992
1997
1999 unsigned Threshold = adjustInliningThresholdUsingCallee(CB, TLI, this);
2000
2001 // Private object passed as arguments may end up in scratch usage if the call
2002 // is not inlined. Increase the inline threshold to promote inlining.
2003 TypeSize AllocaSize = getCallArgsTotalAllocaSize(CB, DL);
2004 if (AllocaSize.getFixedValue() > 0)
2005 Threshold += CLOpts.inline_arg_alloca_cost;
2006 return Threshold;
2007}
2008
2010 const AllocaInst *AI) const {
2011
2012 // Below the cutoff, assume that the private memory objects would be
2013 // optimized
2014 auto AllocaSize = getCallArgsTotalAllocaSize(CB, DL).getFixedValue();
2015 if (AllocaSize <= CLOpts.inline_arg_alloca_cutoff)
2016 return 0;
2017
2018 // Above the cutoff, we give a cost to each private memory object
2019 // depending its size. If the array can be optimized by SROA this cost is not
2020 // added to the total-cost in the inliner cost analysis.
2021 //
2022 // We choose the total cost of the alloca such that their sum cancels the
2023 // bonus given in the threshold (ArgAllocaCost).
2024 //
2025 // Cost_Alloca_0 + ... + Cost_Alloca_N == ArgAllocaCost
2026 //
2027 // Awkwardly, the ArgAllocaCost bonus is multiplied by threshold-multiplier,
2028 // the single-bb bonus and the vector-bonus.
2029 //
2030 // We compensate the first two multipliers, by repeating logic from the
2031 // inliner-cost in here. The vector-bonus is 0 on AMDGPU.
2032 static_assert(InlinerVectorBonusPercent == 0, "vector bonus assumed to be 0");
2033 unsigned Threshold =
2034 CLOpts.inline_arg_alloca_cost * getInliningThresholdMultiplier();
2035
2036 bool SingleBB = none_of(*CB->getCalledFunction(), [](const BasicBlock &BB) {
2037 return BB.getTerminator()->getNumSuccessors() > 1;
2038 });
2039 if (SingleBB) {
2040 Threshold += Threshold / 2;
2041 }
2042
2043 auto ArgAllocaSize = AI->getAllocationSize(DL);
2044 if (!ArgAllocaSize)
2045 return 0;
2046
2047 // Attribute the bonus proportionally to the alloca size
2048 unsigned AllocaThresholdBonus = static_cast<unsigned>(
2049 (Threshold * ArgAllocaSize->getFixedValue()) / AllocaSize);
2050
2051 return AllocaThresholdBonus;
2052}
2053
2056 OptimizationRemarkEmitter *ORE) const {
2057 CommonTTI.getUnrollingPreferences(L, SE, UP, ORE);
2058}
2059
2061 TTI::PeelingPreferences &PP) const {
2062 CommonTTI.getPeelingPreferences(L, SE, PP);
2063}
2064
2065int GCNTTIImpl::getTransInstrCost(TTI::TargetCostKind CostKind) const {
2066 return getQuarterRateInstrCost(CostKind);
2067}
2068
2069int GCNTTIImpl::get64BitInstrCost(TTI::TargetCostKind CostKind) const {
2070 return ST->hasFullRate64Ops()
2071 ? getFullRateInstrCost()
2072 : ST->hasHalfRate64Ops() ? getHalfRateInstrCost(CostKind)
2073 : getQuarterRateInstrCost(CostKind);
2074}
2075
2076std::pair<InstructionCost, MVT>
2077GCNTTIImpl::getTypeLegalizationCost(Type *Ty) const {
2078 std::pair<InstructionCost, MVT> Cost = BaseT::getTypeLegalizationCost(Ty);
2079 auto Size = DL.getTypeSizeInBits(Ty);
2080 // Maximum load or store can handle 8 dwords for scalar and 4 for
2081 // vector ALU. Let's assume anything above 8 dwords is expensive
2082 // even if legal.
2083 if (Size <= 256)
2084 return Cost;
2085
2086 Cost.first += (Size + 255) / 256;
2087 return Cost;
2088}
2089
2091 if (ST->hasVmemPrefInsts() || ST->hasSmemPrefetchInsts())
2092 return ST->getDataCacheLineSize();
2093 return 0;
2094}
2095
2097 return ST->hasPrefetch() ? 128 : 0;
2098}
2099
2102}
2103
2105 const Function &F,
2106 SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const {
2108 LB.push_back({"amdgpu-max-num-workgroups[0]", MaxNumWorkgroups[0]});
2109 LB.push_back({"amdgpu-max-num-workgroups[1]", MaxNumWorkgroups[1]});
2110 LB.push_back({"amdgpu-max-num-workgroups[2]", MaxNumWorkgroups[2]});
2111 std::pair<unsigned, unsigned> FlatWorkGroupSize =
2112 ST->getFlatWorkGroupSizes(F);
2113 LB.push_back({"amdgpu-flat-work-group-size[0]", FlatWorkGroupSize.first});
2114 LB.push_back({"amdgpu-flat-work-group-size[1]", FlatWorkGroupSize.second});
2115 std::pair<unsigned, unsigned> WavesPerEU = ST->getWavesPerEU(F);
2116 LB.push_back({"amdgpu-waves-per-eu[0]", WavesPerEU.first});
2117 LB.push_back({"amdgpu-waves-per-eu[1]", WavesPerEU.second});
2118}
2119
2122 if (!ST->hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
2123 return KnownIEEEMode::On; // Only mode on gfx1170+
2124
2125 const Function *F = I.getFunction();
2126 if (!F)
2128
2129 Attribute IEEEAttr = F->getFnAttribute("amdgpu-ieee");
2130 if (IEEEAttr.isValid())
2132
2133 return AMDGPU::isShader(F->getCallingConv()) ? KnownIEEEMode::Off
2135}
2136
2137static unsigned getNumMemoryInsts(unsigned Bytes, unsigned MaxBytes,
2138 bool HasDwordx3) {
2139 unsigned NumInsts = Bytes / MaxBytes;
2140 unsigned Rem = Bytes % MaxBytes;
2141 if (HasDwordx3 && Rem % 16 >= 12) {
2142 ++NumInsts;
2143 Rem -= 12;
2144 }
2145 return NumInsts + llvm::popcount(Rem);
2146}
2147
2148static unsigned getNumWidenedSMEMLoads(unsigned Bytes, uint64_t Alignment,
2149 unsigned EltBytes, unsigned MaxBytes,
2150 bool HasDwordx3) {
2151 unsigned MaxPiece = EltBytes == 1 ? 8 : MaxBytes;
2152 unsigned WideBytes = PowerOf2Ceil(Bytes);
2153 unsigned NumWide = 0, SmallBytes = 0;
2154 for (unsigned Off = 0; Off < Bytes;) {
2155 unsigned Rem = Bytes - Off;
2156 unsigned Span = Rem;
2157 if (Rem <= Alignment)
2158 Span = std::min<uint64_t>(Alignment, WideBytes - Off);
2159 unsigned Piece = std::min(llvm::bit_floor(Span), MaxPiece);
2160 if (Rem <= EltBytes)
2161 Piece = 4;
2162 if (Piece >= MaxBytes)
2163 ++NumWide;
2164 else
2165 SmallBytes += std::max(Piece, 4u);
2166 Off += Piece;
2167 }
2168 return NumWide + getNumMemoryInsts(SmallBytes, 32, HasDwordx3);
2169}
2170
2172 const auto *LI = dyn_cast_or_null<LoadInst>(I);
2173 if (!LI)
2174 return false;
2175 const Value *Ptr = LI->getPointerOperand();
2176 const DataLayout &DL = LI->getDataLayout();
2177 APInt Offset(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
2179 /*AllowNonInbounds=*/true);
2180 return AMDGPU::isTriviallyUniform(Ptr, LI);
2181}
2182
2183static std::pair<bool, bool> getKnownBufferOobProperties(const GCNSubtarget &ST,
2184 const DataLayout &DL,
2185 const Instruction *I,
2186 unsigned Bytes) {
2187 const Value *Ptr = I ? getLoadStorePointerOperand(I) : nullptr;
2188 if (!Ptr ||
2190 return {false, false};
2191 APInt Offset(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
2192 bool KnownOffset = true;
2193 while (const auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
2194 KnownOffset = KnownOffset && GEP->accumulateConstantOffset(DL, Offset);
2195 Ptr = GEP->getPointerOperand();
2196 }
2197 const auto *Cast = dyn_cast<AddrSpaceCastInst>(Ptr);
2198 if (Cast) {
2199 if (Cast->getSrcAddressSpace() != AMDGPUAS::BUFFER_RESOURCE)
2200 return {false, false};
2201 Ptr = Cast->getPointerOperand();
2202 }
2203 const auto *Rsrc = dyn_cast<IntrinsicInst>(Ptr);
2204 if (Rsrc && Rsrc->getIntrinsicID() != Intrinsic::amdgcn_make_buffer_rsrc)
2205 Rsrc = nullptr;
2206 if (!Cast && !Rsrc)
2207 return {false, false};
2208
2209 bool NoWrapFromMax =
2210 KnownOffset &&
2211 Offset.ule(APInt::getAllOnes(Offset.getBitWidth()) - Bytes);
2212 const auto *NumRecords =
2213 Rsrc ? dyn_cast<ConstantInt>(Rsrc->getArgOperand(2)) : nullptr;
2214 std::optional<unsigned> NumRecordsWidth =
2215 ST.getBufferResourceNumRecordsWidth();
2216 if (!NumRecords || !NumRecordsWidth)
2217 return {NoWrapFromMax, false};
2218 APInt Bound = NumRecords->getValue().zextOrTrunc(*NumRecordsWidth);
2219 if (Bound.isAllOnes())
2220 return {NoWrapFromMax, true};
2221 if (!KnownOffset)
2222 return {false, false};
2223 APInt BoundsDiff = Bound.zext(64) - Offset.zext(64);
2224 return {NoWrapFromMax, BoundsDiff.sge(Bytes) || BoundsDiff.isNonPositive()};
2225}
2226
2228 Align Alignment,
2229 unsigned AddressSpace,
2230 TTI::TargetCostKind CostKind,
2231 TTI::OperandValueInfo OpInfo,
2232 const Instruction *I) const {
2233 Type *EltTy = Src->getScalarType();
2234 if ((Opcode != Instruction::Load && Opcode != Instruction::Store) ||
2235 CostKind == TTI::TCK_Latency || isa<ScalableVectorType>(Src) ||
2236 (!EltTy->isIntOrPtrTy() && !EltTy->isFloatingPointTy()))
2237 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
2238 CostKind, OpInfo, I);
2239
2240 unsigned EltBits = std::max<unsigned>(8, DL.getTypeSizeInBits(EltTy));
2241
2242 auto *VecTy = dyn_cast<FixedVectorType>(Src);
2244 EltBits % 8 == 0 && !isPowerOf2_32(EltBits) &&
2245 !TLI->shouldCombineMemoryType(TLI->getValueType(DL, Src))) {
2246 Align EltAlign = commonAlignment(Alignment, EltBits / 8);
2247 return VecTy->getNumElements() * getMemoryOpCost(Opcode, EltTy, EltAlign,
2248 AddressSpace, CostKind,
2249 OpInfo);
2250 }
2251
2252 unsigned Bytes = DL.getTypeStoreSize(Src);
2253 if (Opcode == Instruction::Load &&
2256 Alignment >= std::min(Bytes, 4u) &&
2259 unsigned Dwords = divideCeil(Bytes, 4);
2260 unsigned MaxBytes = getLoadStoreVecRegBitWidth(AddressSpace) / 8;
2261 bool HasDwordx3 = ST->hasScalarDwordx3Loads();
2262 // The last byte of a 7-byte remainder is not widened into the scalar load.
2263 if (!VecTy && Bytes % 4)
2264 return getNumMemoryInsts(Dwords * 4, 32, HasDwordx3) + (Bytes % 8 == 7);
2265 if (Bytes % 4 || !TLI->isTypeLegal(EVT::getVectorVT(Src->getContext(),
2266 MVT::i32, Dwords))) {
2267 unsigned EltBytes = Bytes % 4 ? EltBits / 8 : 4;
2268 return getNumWidenedSMEMLoads(Bytes, Alignment.value(), EltBytes,
2269 MaxBytes, HasDwordx3);
2270 }
2271 if (!HasDwordx3 && Alignment >= 8 && Dwords % 4 == 3)
2272 ++Dwords;
2273 return getNumMemoryInsts(Dwords * 4, MaxBytes, HasDwordx3);
2274 }
2275
2276 unsigned MaxBytes =
2277 std::min(16u, getLoadStoreVecRegBitWidth(AddressSpace) / 8);
2279 !ST->hasMultiDwordFlatScratchAddressing())
2282 ST->hasLDSMisalignedBugInWGPMode())
2283 MaxBytes = std::clamp<uint64_t>(Alignment.value(), 4, MaxBytes);
2284 bool IsDS = AddressSpace == AMDGPUAS::LOCAL_ADDRESS ||
2286 bool HasDwordx3 = ST->hasDwordx3LoadStores();
2287 bool HasUnalignedAccess = ST->hasUnalignedBufferAccessEnabled();
2290 HasUnalignedAccess = ST->hasUnalignedScratchAccessEnabled();
2291 else if (IsDS) {
2292 HasUnalignedAccess = ST->hasUnalignedDSAccessEnabled();
2293 if ((Alignment >= 4 || ST->hasLDSMisalignedBugInWGPMode()) && Alignment < 8)
2294 MaxBytes = 8;
2295 HasDwordx3 = HasDwordx3 &&
2296 (Alignment >= 16 || (Alignment < 4 && HasUnalignedAccess));
2297 }
2299 auto [NoWrapFromMax, NoPartialOOB] =
2300 getKnownBufferOobProperties(*ST, DL, I, Bytes);
2301 MaxBytes = ST->getMaxBufferIntrinsicWidth(DL, Src, Alignment, NoWrapFromMax,
2302 NoPartialOOB) /
2303 8;
2304 }
2305 if (Alignment < 4 && !HasUnalignedAccess)
2306 MaxBytes = std::min<unsigned>(MaxBytes, Alignment.value());
2307 bool MergesDwords = AddressSpace == AMDGPUAS::BUFFER_FAT_POINTER ||
2308 (ST->hasFlatInstOffsets() &&
2311 !ST->hasFlatSegmentOffsetBug())));
2312
2313 if (Opcode == Instruction::Load &&
2315 if (VecTy && Alignment >= PowerOf2Ceil(Bytes))
2316 return divideCeil(Bytes, MaxBytes);
2317 if (EltBits <= 16 && Alignment >= 4 && Bytes % 4) {
2318 unsigned Piece = std::min(EltBits == 8 ? 8u : 16u, MaxBytes);
2319 unsigned Granule = std::min<unsigned>(Alignment.value(), Piece);
2320 if (!IsDS && !MergesDwords)
2321 return Bytes / Piece + llvm::popcount(Bytes % Piece / Granule) +
2322 (Bytes % Granule != 0);
2323 unsigned Tail = Bytes % Granule;
2324 if (Tail > EltBits / 8) {
2325 Bytes += std::max<unsigned>(4, PowerOf2Ceil(Tail)) - Tail;
2326 if (IsDS)
2327 HasDwordx3 = false;
2328 }
2329 }
2330 }
2331 if (!MergesDwords && Bytes % MaxBytes > 12)
2332 HasDwordx3 = false;
2333 return getNumMemoryInsts(Bytes, MaxBytes, HasDwordx3);
2334}
2335
2337 if (VectorType *VecTy = dyn_cast<VectorType>(Tp)) {
2338 if (VecTy->getElementType()->isIntegerTy(8)) {
2339 unsigned ElementCount = VecTy->getElementCount().getFixedValue();
2340 return divideCeil(ElementCount - 1, 4);
2341 }
2342 }
2343 return BaseT::getNumberOfParts(Tp);
2344}
2345
2348 switch (Intrinsic->getIntrinsicID()) {
2349 case Intrinsic::amdgcn_wave_shuffle:
2351 default:
2352 break;
2353 }
2354 }
2355
2356 if (isAlwaysUniform(V))
2358
2359 if (isSourceOfDivergence(V))
2361
2363}
2364
2366 StackOffset BaseOffset,
2367 bool HasBaseReg, int64_t Scale,
2368 unsigned AddrSpace) const {
2369 if (HasBaseReg && Scale != 0) {
2370 // gfx1250+ can fold base+scale*index when scale matches the memory access
2371 // size (scale_offset bit). Supported for flat/global/constant/scratch
2372 // (VMEM, max 128 bits) and constant_32bit (SMRD, capped to 128 bits here).
2373 if (getST()->hasScaleOffset() && Ty && Ty->isSized() &&
2375 AddrSpace == AMDGPUAS::FLAT_ADDRESS ||
2376 AddrSpace == AMDGPUAS::PRIVATE_ADDRESS)) {
2377 TypeSize StoreSize = getDataLayout().getTypeStoreSize(Ty);
2378 if (TypeSize::isKnownLE(StoreSize, TypeSize::getFixed(16)) &&
2379 static_cast<int64_t>(StoreSize.getFixedValue()) == Scale)
2380 return 0;
2381 }
2382 return 1;
2383 }
2384 return BaseT::getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, Scale,
2385 AddrSpace);
2386}
2387
2389 const TTI::LSRCost &B) const {
2390 // Favor lower per-iteration work over preheader/setup costs.
2391 // AMDGPU lacks rich addressing modes, so ScaleCost is folded into the
2392 // effective instruction count (base+scale*index requires a separate ADD).
2393 unsigned EffInsnsA = A.Insns + A.ScaleCost;
2394 unsigned EffInsnsB = B.Insns + B.ScaleCost;
2395
2396 return std::tie(EffInsnsA, A.NumIVMuls, A.AddRecCost, A.NumBaseAdds,
2397 A.SetupCost, A.ImmCost, A.NumRegs) <
2398 std::tie(EffInsnsB, B.NumIVMuls, B.AddRecCost, B.NumBaseAdds,
2399 B.SetupCost, B.ImmCost, B.NumRegs);
2400}
2401
2403 // isLSRCostLess de-prioritizes register count; keep consistent.
2404 return false;
2405}
2406
2408 // Prefer the baseline when LSR cannot clearly reduce per-iteration work.
2409 return true;
2410}
2411
2413 const SmallBitVector &UniformArgs) const {
2415 switch (Intrinsic->getIntrinsicID()) {
2416 case Intrinsic::amdgcn_wave_shuffle:
2417 // wave_shuffle(Value, Index): result is uniform when either Value or Index
2418 // is uniform.
2419 return UniformArgs[0] || UniformArgs[1];
2420 default:
2421 llvm_unreachable("unexpected intrinsic in isUniform");
2422 }
2423}
return SDValue()
const TargetLowering & TLI
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 unsigned getNumWidenedSMEMLoads(unsigned Bytes, uint64_t Alignment, unsigned EltBytes, unsigned MaxBytes, bool HasDwordx3)
static TypeSize getCallArgsTotalAllocaSize(const CallBase *CB, const DataLayout &DL)
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 unsigned adjustInliningThresholdUsingCallee(const CallBase *CB, const SITargetLowering *TLI, const GCNTTIImpl *TTIImpl)
static bool isFusedFMul(const SITargetLowering &TLI, Type *Ty, const Instruction *FMul, const Instruction *FAddSub)
static unsigned getNumMemoryInsts(unsigned Bytes, unsigned MaxBytes, bool HasDwordx3)
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 bool hasUniformPointerOperand(const Instruction *I)
static std::pair< bool, bool > getKnownBufferOobProperties(const GCNSubtarget &ST, const DataLayout &DL, const Instruction *I, unsigned Bytes)
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
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition APInt.h:230
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1057
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition APInt.cpp:1078
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:367
bool isNonPositive() const
Determine if this APInt Value is non-positive (<= 0).
Definition APInt.h:357
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
Definition APInt.h:1241
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.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
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
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
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
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
Definition Type.h:265
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
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
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 isTriviallyUniform(const Value *V, const Instruction *CtxI)
Return true if we can easily prove that V is uniform at CtxI.
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:912
@ 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:793
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:958
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:763
LLVM_ABI int getInstrCost(const LLVMContext &C)
Return -inline-instr-cost.
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.
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.
@ Offset
Definition DWP.cpp:577
@ 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
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
@ 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
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:156
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition MathExtras.h:380
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
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:206
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
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
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
Definition ValueTypes.h:70
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:423
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...