LLVM 24.0.0git
AMDGPUInstructionSelector.h
Go to the documentation of this file.
1//===- AMDGPUInstructionSelector --------------------------------*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file declares the targeting of the InstructionSelector class for
10/// AMDGPU.
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUINSTRUCTIONSELECTOR_H
14#define LLVM_LIB_TARGET_AMDGPU_AMDGPUINSTRUCTIONSELECTOR_H
15
16#include "SIDefines.h"
18#include "llvm/IR/InstrTypes.h"
19
20namespace {
21#define GET_GLOBALISEL_PREDICATE_BITSET
22#define AMDGPUSubtarget GCNSubtarget
23#include "AMDGPUGenGlobalISel.inc"
24#undef GET_GLOBALISEL_PREDICATE_BITSET
25#undef AMDGPUSubtarget
26}
27
28namespace llvm {
29
30namespace AMDGPU {
32}
33
38class GCNSubtarget;
39class MachineInstr;
41class MachineOperand;
43class RegisterBank;
44class SIInstrInfo;
45class SIRegisterInfo;
46class MCRegisterClass;
48
50private:
52 const GCNSubtarget *Subtarget;
53
54public:
56 const AMDGPURegisterBankInfo &RBI);
57
58 bool select(MachineInstr &I) override;
59 static const char *getName();
60
63 BlockFrequencyInfo *BFI) override;
64
65private:
66 struct GEPInfo {
69 int64_t Imm = 0;
70 };
71
72 bool isSGPR(Register Reg) const;
73
74 bool isInstrUniform(const MachineInstr &MI) const;
75 bool isVCC(Register Reg, const MachineRegisterInfo &MRI) const;
76
77 const RegisterBank *getArtifactRegBank(
79 const TargetRegisterInfo &TRI) const;
80
81 /// tblgen-erated 'select' implementation.
82 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
83
84 MachineOperand getSubOperand64(MachineOperand &MO,
85 const TargetRegisterClass &SubRC,
86 unsigned SubIdx) const;
87
88 bool constrainCopyLikeIntrin(MachineInstr &MI, unsigned NewOpc) const;
89 bool selectCOPY(MachineInstr &I) const;
90 bool selectCOPY_SCC_VCC(MachineInstr &I) const;
91 bool selectCOPY_VCC_SCC(MachineInstr &I) const;
92 bool selectReadAnyLane(MachineInstr &I) const;
93 bool selectPHI(MachineInstr &I) const;
94 bool selectG_TRUNC(MachineInstr &I) const;
95 bool selectG_SZA_EXT(MachineInstr &I) const;
96 bool selectG_FPEXT(MachineInstr &I) const;
97 bool selectG_FNEG(MachineInstr &I) const;
98 bool selectG_FABS(MachineInstr &I) const;
99 bool selectG_AND_OR_XOR(MachineInstr &I) const;
100 bool selectG_ADD_SUB(MachineInstr &I) const;
101 bool selectG_UADDO_USUBO_UADDE_USUBE(MachineInstr &I) const;
102 bool selectG_AMDGPU_MAD_64_32(MachineInstr &I) const;
103 bool selectG_EXTRACT(MachineInstr &I) const;
104 bool selectS16MergeToS32(MachineInstr &MI) const;
105 bool selectS16MergeToWide(MachineInstr &MI) const;
106 bool selectG_MERGE_VALUES(MachineInstr &I) const;
107 bool selectG_UNMERGE_VALUES(MachineInstr &I) const;
108 bool selectG_BUILD_VECTOR(MachineInstr &I) const;
109 bool selectG_IMPLICIT_DEF(MachineInstr &I) const;
110 bool selectG_INSERT(MachineInstr &I) const;
111 bool selectG_SBFX_UBFX(MachineInstr &I) const;
112
113 bool selectInterpP1F16(MachineInstr &MI) const;
114 bool selectWritelane(MachineInstr &MI) const;
115 bool selectDivScale(MachineInstr &MI) const;
116 bool selectBallot(MachineInstr &I) const;
117 bool selectRelocConstant(MachineInstr &I) const;
118 bool selectGroupStaticSize(MachineInstr &I) const;
119 bool selectReturnAddress(MachineInstr &I) const;
120 bool selectG_INTRINSIC(MachineInstr &I) const;
121
122 bool selectEndCfIntrinsic(MachineInstr &MI) const;
123 bool selectDSOrderedIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const;
124 bool selectDSGWSIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const;
125 bool selectDSAppendConsume(MachineInstr &MI, bool IsAppend) const;
126 bool selectInitWholeWave(MachineInstr &MI) const;
127 bool selectDSBvhStackIntrinsic(MachineInstr &MI) const;
128
129 bool selectImageIntrinsic(MachineInstr &MI,
130 const AMDGPU::ImageDimIntrinsicInfo *Intr) const;
131 bool selectG_INTRINSIC_W_SIDE_EFFECTS(MachineInstr &I) const;
132 int getS_CMPOpcode(CmpInst::Predicate P, uint64_t Size) const;
133 bool selectG_ICMP_or_FCMP(MachineInstr &I) const;
134 bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const;
135 void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI,
136 SmallVectorImpl<GEPInfo> &AddrInfo) const;
137
138 void initM0(MachineInstr &I) const;
139 bool selectG_LOAD_STORE_ATOMICRMW(MachineInstr &I) const;
140 bool selectG_SELECT(MachineInstr &I) const;
141 bool selectG_BRCOND(MachineInstr &I) const;
142 bool selectG_GLOBAL_VALUE(MachineInstr &I) const;
143 bool selectG_PTRMASK(MachineInstr &I) const;
144 bool selectG_EXTRACT_VECTOR_ELT(MachineInstr &I) const;
145 bool selectG_INSERT_VECTOR_ELT(MachineInstr &I) const;
146 bool selectBufferLoadLds(MachineInstr &MI) const;
147 bool selectGlobalLoadLds(MachineInstr &MI) const;
148 bool selectTensorLoadStore(MachineInstr &MI, Intrinsic::ID IID) const;
149 bool selectBVHIntersectRayIntrinsic(MachineInstr &I) const;
150 bool selectSMFMACIntrin(MachineInstr &I) const;
151 bool selectPermlaneSwapIntrin(MachineInstr &I, Intrinsic::ID IntrID) const;
152 bool selectWaveAddress(MachineInstr &I) const;
153 bool selectBITOP3(MachineInstr &I) const;
154 bool selectWriteRegister(MachineInstr &MI) const;
155 bool selectStackRestore(MachineInstr &MI) const;
156 bool selectNamedBarrierInit(MachineInstr &I, Intrinsic::ID IID) const;
157 bool selectNamedBarrierInst(MachineInstr &I, Intrinsic::ID IID) const;
158 bool selectSBarrierSignalIsfirst(MachineInstr &I, Intrinsic::ID IID) const;
159 bool selectSGetBarrierState(MachineInstr &I, Intrinsic::ID IID) const;
160 bool selectWaveShuffleIntrin(MachineInstr &I) const;
161
162 std::pair<Register, unsigned> selectVOP3ModsImpl(Register Src,
163 bool IsCanonicalizing = true,
164 bool AllowAbs = true,
165 bool OpSel = false) const;
166 std::pair<Register, unsigned> selectVOP3PModsF32Impl(Register Src) const;
167
168 Register copyToVGPRIfSrcFolded(Register Src, unsigned Mods,
169 MachineOperand Root, MachineInstr *InsertPt,
170 bool ForceVGPR = false) const;
171
172 Register widenSrcIfVGPR16(Register Src, MachineInstr *InsertPt) const;
173
175 selectVCSRC(MachineOperand &Root) const;
176
178 selectVSRC0(MachineOperand &Root) const;
179
181 selectVOP3Mods0(MachineOperand &Root) const;
183 selectVOP3BMods0(MachineOperand &Root) const;
185 selectVOP3OMods(MachineOperand &Root) const;
187 selectVOP3Mods(MachineOperand &Root) const;
189 selectVOP3ModsNonCanonicalizing(MachineOperand &Root) const;
191 selectVOP3BMods(MachineOperand &Root) const;
192
193 ComplexRendererFns selectVOP3NoMods(MachineOperand &Root) const;
194 ComplexRendererFns selectVOP3NoOpSelMods(MachineOperand &Root) const;
195
196 std::pair<Register, unsigned>
197 selectVOP3PModsImpl(Register RootReg, const MachineRegisterInfo &MRI,
198 bool IsDOT = false, bool NoOpSel0 = false) const;
200 selectVOP3PRetHelper(MachineOperand &Root, bool IsDOT = false,
201 bool NoOpSel0 = false) const;
202
204 selectVOP3PMods(MachineOperand &Root) const;
206 selectVOP3PModsPkFmaOpSel0(MachineOperand &Root) const;
208 selectVOP3PModsPkAddMulOpSel0(MachineOperand &Root) const;
209
211 selectVOP3PModsDOT(MachineOperand &Root) const;
213 selectVOP3PNoModsDOT(MachineOperand &Root) const;
215 selectVOP3PModsF32(MachineOperand &Root) const;
217 selectVOP3PNoModsF32(MachineOperand &Root) const;
218
220 selectWMMAOpSelVOP3PMods(MachineOperand &Root) const;
221
223 selectWMMAModsF32NegAbs(MachineOperand &Root) const;
225 selectWMMAModsF16Neg(MachineOperand &Root) const;
227 selectWMMAModsF16NegAbs(MachineOperand &Root) const;
229 selectWMMAVISrc(MachineOperand &Root) const;
231 selectSWMMACIndex8(MachineOperand &Root) const;
233 selectSWMMACIndex16(MachineOperand &Root) const;
235 selectSWMMACIndex32(MachineOperand &Root) const;
236
238 selectVOP3OpSelMods(MachineOperand &Root) const;
239
241 selectVINTERPMods(MachineOperand &Root) const;
243 selectVINTERPModsHi(MachineOperand &Root) const;
244
245 bool selectScaleOffset(MachineOperand &Root, Register &Offset, bool IsSigned,
246 bool IsSMEM = false) const;
247 bool selectSmrdOffset(MachineOperand &Root, Register &Base, Register *SOffset,
248 int64_t *Offset, bool *ScaleOffset) const;
250 selectSmrdImm(MachineOperand &Root) const;
252 selectSmrdImm32(MachineOperand &Root) const;
254 selectSmrdSgpr(MachineOperand &Root) const;
256 selectSmrdSgprImm(MachineOperand &Root) const;
257
258 std::pair<Register, int64_t>
259 selectFlatOffsetImpl(MachineOperand &Root,
260 AMDGPU::FlatAddrSpace FlatVariant) const;
261
263 selectFlatOffset(MachineOperand &Root) const;
265 selectGlobalOffset(MachineOperand &Root) const;
267 selectScratchOffset(MachineOperand &Root) const;
268
270 selectGlobalSAddr(MachineOperand &Root, unsigned CPolBits,
271 bool NeedIOffset = true) const;
273 selectGlobalSAddr(MachineOperand &Root) const;
275 selectGlobalSAddrCPol(MachineOperand &Root) const;
277 selectGlobalSAddrCPolM0(MachineOperand &Root) const;
279 selectGlobalSAddrGLC(MachineOperand &Root) const;
281 selectGlobalSAddrNoIOffset(MachineOperand &Root) const;
283 selectGlobalSAddrNoIOffsetM0(MachineOperand &Root) const;
284
286 selectScratchSAddr(MachineOperand &Root) const;
287 bool checkFlatScratchSVSSwizzleBug(Register VAddr, Register SAddr,
288 uint64_t ImmOffset) const;
290 selectScratchSVAddr(MachineOperand &Root) const;
291
293 selectMUBUFScratchOffen(MachineOperand &Root) const;
295 selectMUBUFScratchOffset(MachineOperand &Root) const;
296
297 bool isDSOffsetLegal(Register Base, int64_t Offset) const;
298 bool isDSOffset2Legal(Register Base, int64_t Offset0, int64_t Offset1,
299 unsigned Size) const;
300 bool isFlatScratchBaseLegal(Register Addr) const;
301 bool isFlatScratchBaseLegalSV(Register Addr) const;
302 bool isFlatScratchBaseLegalSVImm(Register Addr) const;
303
304 std::pair<Register, int64_t>
305 selectDS1Addr1OffsetImpl(MachineOperand &Root) const;
307 selectDS1Addr1Offset(MachineOperand &Root) const;
308
310 selectDS64Bit4ByteAligned(MachineOperand &Root) const;
311
313 selectDS128Bit8ByteAligned(MachineOperand &Root) const;
314
315 std::pair<Register, int64_t> selectDSReadWrite2Impl(MachineOperand &Root,
316 unsigned size) const;
318 selectDSReadWrite2(MachineOperand &Root, unsigned size) const;
319
320 std::tuple<Register, int64_t, bool>
321 getPtrBaseWithConstantOffset(Register Root,
322 const MachineRegisterInfo &MRI) const;
323
324 // Parse out a chain of up to two g_ptr_add instructions.
325 // g_ptr_add (n0, _)
326 // g_ptr_add (n0, (n1 = g_ptr_add n2, n3))
327 struct MUBUFAddressData {
328 Register N0, N2, N3;
329 int64_t Offset = 0;
330 };
331
332 bool shouldUseAddr64(MUBUFAddressData AddrData) const;
333
334 void splitIllegalMUBUFOffset(MachineIRBuilder &B,
335 Register &SOffset, int64_t &ImmOffset) const;
336
337 MUBUFAddressData parseMUBUFAddress(Register Src) const;
338
339 bool selectMUBUFAddr64Impl(MachineOperand &Root, Register &VAddr,
340 Register &RSrcReg, Register &SOffset,
341 int64_t &Offset) const;
342
343 bool selectMUBUFOffsetImpl(MachineOperand &Root, Register &RSrcReg,
344 Register &SOffset, int64_t &Offset) const;
345
347 selectBUFSOffset(MachineOperand &Root) const;
348
350 selectMUBUFAddr64(MachineOperand &Root) const;
351
353 selectMUBUFOffset(MachineOperand &Root) const;
354
355 ComplexRendererFns selectSMRDBufferImm(MachineOperand &Root) const;
356 ComplexRendererFns selectSMRDBufferImm32(MachineOperand &Root) const;
357 ComplexRendererFns selectSMRDBufferSgprImm(MachineOperand &Root) const;
358
359 std::pair<Register, unsigned> selectVOP3PMadMixModsImpl(MachineOperand &Root,
360 bool &Matched) const;
361 ComplexRendererFns selectVOP3PMadMixModsExt(MachineOperand &Root) const;
362 ComplexRendererFns selectVOP3PMadMixMods(MachineOperand &Root) const;
363 ComplexRendererFns selectVOP3PMadMixModsExtNeg(MachineOperand &Root) const;
364 ComplexRendererFns selectVOP3PMadMixModsNeg(MachineOperand &Root) const;
365
366 void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
367 int OpIdx) const;
368 void renderPrefetchLen(MachineInstrBuilder &MIB, const MachineInstr &MI,
369 int OpIdx) const;
370 void renderZextBoolTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
371 int OpIdx) const;
372
373 void renderOpSelTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
374 int OpIdx) const;
375
376 void renderSrcAndDstSelToOpSelXForm_0_0(MachineInstrBuilder &MIB,
377 const MachineInstr &MI,
378 int OpIdx) const;
379
380 void renderSrcAndDstSelToOpSelXForm_0_1(MachineInstrBuilder &MIB,
381 const MachineInstr &MI,
382 int OpIdx) const;
383
384 void renderSrcAndDstSelToOpSelXForm_1_0(MachineInstrBuilder &MIB,
385 const MachineInstr &MI,
386 int OpIdx) const;
387
388 void renderSrcAndDstSelToOpSelXForm_1_1(MachineInstrBuilder &MIB,
389 const MachineInstr &MI,
390 int OpIdx) const;
391
392 void renderDstSelToOpSelXForm(MachineInstrBuilder &MIB,
393 const MachineInstr &MI, int OpIdx) const;
394
395 void renderSrcSelToOpSelXForm(MachineInstrBuilder &MIB,
396 const MachineInstr &MI, int OpIdx) const;
397
398 void renderSrcAndDstSelToOpSelXForm_2_0(MachineInstrBuilder &MIB,
399 const MachineInstr &MI,
400 int OpIdx) const;
401
402 void renderDstSelToOpSel3XFormXForm(MachineInstrBuilder &MIB,
403 const MachineInstr &MI, int OpIdx) const;
404
405 void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
406 int OpIdx) const;
407
408 void renderBitcastFPImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
409 int OpIdx) const;
410
411 void renderBitcastFPImm32(MachineInstrBuilder &MIB, const MachineInstr &MI,
412 int OpIdx) const {
413 renderBitcastFPImm(MIB, MI, OpIdx);
414 }
415 void renderBitcastFPImm64(MachineInstrBuilder &MIB, const MachineInstr &MI,
416 int OpIdx) const {
417 renderBitcastFPImm(MIB, MI, OpIdx);
418 }
419
420 void renderCountTrailingOnesImm(MachineInstrBuilder &MIB,
421 const MachineInstr &MI, int OpIdx) const;
422 void renderExtractCPol(MachineInstrBuilder &MIB, const MachineInstr &MI,
423 int OpIdx) const;
424 void renderExtractSWZ(MachineInstrBuilder &MIB, const MachineInstr &MI,
425 int OpIdx) const;
426 void renderExtractCpolSetGLC(MachineInstrBuilder &MIB, const MachineInstr &MI,
427 int OpIdx) const;
428
429 void renderFPPow2ToExponent(MachineInstrBuilder &MIB, const MachineInstr &MI,
430 int OpIdx) const;
431
432 void renderRoundMode(MachineInstrBuilder &MIB, const MachineInstr &MI,
433 int OpIdx) const;
434
435 void renderVOP3PModsNeg(MachineInstrBuilder &MIB, const MachineInstr &MI,
436 int OpIdx) const;
437 void renderVOP3PModsNegs(MachineInstrBuilder &MIB, const MachineInstr &MI,
438 int OpIdx) const;
439 void renderVOP3PModsNegAbs(MachineInstrBuilder &MIB, const MachineInstr &MI,
440 int OpIdx) const;
441
442 void renderPrefetchLoc(MachineInstrBuilder &MIB, const MachineInstr &MI,
443 int OpIdx) const;
444
445 void renderScaledMAIIntrinsicOperand(MachineInstrBuilder &MIB,
446 const MachineInstr &MI, int OpIdx) const;
447
448 bool isInlineImmediate(const APInt &Imm) const;
449 bool isInlineImmediate(const APFloat &Imm) const;
450
451 // Returns true if TargetOpcode::G_AND MachineInstr `MI`'s masking of the
452 // shift amount operand's `ShAmtBits` bits is unneeded.
453 bool isUnneededShiftMask(const MachineInstr &MI, unsigned ShAmtBits) const;
454
455 /// Match a zero extend from a 32-bit value to 64-bits.
456 Register matchZeroExtendFromS32(Register Reg) const;
457 /// Match a sign extend from a 32-bit value to 64-bits.
458 Register matchSignExtendFromS32(Register Reg) const;
459 /// Match a zero extend from a 32-bit value to 64-bits, or \p Reg itself if it
460 /// is 32-bit.
461 Register matchZeroExtendFromS32OrS32(Register Reg) const;
462 /// Match a sign extend from a 32-bit value to 64-bits, or \p Reg itself if it
463 /// is 32-bit.
464 Register matchSignExtendFromS32OrS32(Register Reg) const;
465 /// Match either sign or zero extend depending on the \p IsSigned from a
466 /// 32-bit value to 64-bits, or \p Reg itself if it is 32-bit.
467 Register matchExtendFromS32OrS32(Register Reg, bool IsSigned) const;
468 /// Match an any extend from a 32-bit value to 64-bit.
469 Register matchAnyExtendFromS32(Register Reg) const;
470
471 const SIInstrInfo &TII;
472 const SIRegisterInfo &TRI;
473 const AMDGPURegisterBankInfo &RBI;
474 const GCNSubtarget &STI;
475#define GET_GLOBALISEL_PREDICATES_DECL
476#define AMDGPUSubtarget GCNSubtarget
477#include "AMDGPUGenGlobalISel.inc"
478#undef GET_GLOBALISEL_PREDICATES_DECL
479#undef AMDGPUSubtarget
480
481#define GET_GLOBALISEL_TEMPORARIES_DECL
482#include "AMDGPUGenGlobalISel.inc"
483#undef GET_GLOBALISEL_TEMPORARIES_DECL
484};
485
486} // End llvm namespace.
487#endif
uint64_t uint64_t
uint64_t Imm
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define P(N)
MachineRegisterInfo & MRI
AMDGPUInstructionSelector(const GCNSubtarget &STI, const AMDGPURegisterBankInfo &RBI)
static const char * getName()
bool select(MachineInstr &I) override
Select the (possibly generic) instruction I to only use target-specific opcodes.
void setupMF(MachineFunction &MF, GISelValueTracking *VT, CodeGenCoverage *CoverageInfo, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) override
Setup per-MF executor state.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
std::optional< SmallVector< std::function< void(MachineInstrBuilder &)>, 4 > > ComplexRendererFns
MCRegisterClass - Base class of TargetRegisterClass.
Helper class to build MachineInstr.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Analysis providing profile information.
This class implements the register bank concept.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
@ Load
The value being inserted comes from a load (InsertElement only).
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58