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"
17#include "llvm/CodeGen/GlobalISel/InstructionSelector.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 {
31struct ImageDimIntrinsicInfo;
32}
33
34class AMDGPURegisterBankInfo;
35class AMDGPUTargetMachine;
36class BlockFrequencyInfo;
37class ProfileSummaryInfo;
38class GCNSubtarget;
39class MachineInstr;
40class MachineIRBuilder;
41class MachineOperand;
42class MachineRegisterInfo;
43class RegisterBank;
44class SIInstrInfo;
45class SIRegisterInfo;
46class TargetRegisterClass;
47
48class AMDGPUInstructionSelector final : public InstructionSelector {
49private:
50 MachineRegisterInfo *MRI;
51 const GCNSubtarget *Subtarget;
52
53public:
54 AMDGPUInstructionSelector(const GCNSubtarget &STI,
55 const AMDGPURegisterBankInfo &RBI,
56 const AMDGPUTargetMachine &TM);
57
58 bool select(MachineInstr &I) override;
59 static const char *getName();
60
61 void setupMF(MachineFunction &MF, GISelValueTracking *VT,
62 CodeGenCoverage *CoverageInfo, ProfileSummaryInfo *PSI,
63 BlockFrequencyInfo *BFI) override;
64
65private:
66 struct GEPInfo {
67 SmallVector<unsigned, 2> SgprParts;
68 SmallVector<unsigned, 2> VgprParts;
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(
78 Register Reg, const MachineRegisterInfo &MRI,
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 selectG_FMA_FMAD(MachineInstr &I) const;
105 bool selectG_MERGE_VALUES(MachineInstr &I) const;
106 bool selectG_UNMERGE_VALUES(MachineInstr &I) const;
107 bool selectG_BUILD_VECTOR(MachineInstr &I) const;
108 bool selectG_IMPLICIT_DEF(MachineInstr &I) const;
109 bool selectG_INSERT(MachineInstr &I) const;
110 bool selectG_SBFX_UBFX(MachineInstr &I) const;
111
112 bool selectInterpP1F16(MachineInstr &MI) const;
113 bool selectWritelane(MachineInstr &MI) const;
114 bool selectDivScale(MachineInstr &MI) const;
115 bool selectIntrinsicCmp(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 selectSBarrier(MachineInstr &MI) const;
128 bool selectDSBvhStackIntrinsic(MachineInstr &MI) const;
129
130 bool selectImageIntrinsic(MachineInstr &MI,
131 const AMDGPU::ImageDimIntrinsicInfo *Intr) const;
132 bool selectG_INTRINSIC_W_SIDE_EFFECTS(MachineInstr &I) const;
133 int getS_CMPOpcode(CmpInst::Predicate P, unsigned Size) const;
134 bool selectG_ICMP_or_FCMP(MachineInstr &I) const;
135 bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const;
136 void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI,
137 SmallVectorImpl<GEPInfo> &AddrInfo) const;
138
139 void initM0(MachineInstr &I) const;
140 bool selectG_LOAD_STORE_ATOMICRMW(MachineInstr &I) const;
141 bool selectG_SELECT(MachineInstr &I) const;
142 bool selectG_BRCOND(MachineInstr &I) const;
143 bool selectG_GLOBAL_VALUE(MachineInstr &I) const;
144 bool selectG_PTRMASK(MachineInstr &I) const;
145 bool selectG_EXTRACT_VECTOR_ELT(MachineInstr &I) const;
146 bool selectG_INSERT_VECTOR_ELT(MachineInstr &I) const;
147 bool selectBufferLoadLds(MachineInstr &MI) const;
148 bool selectGlobalLoadLds(MachineInstr &MI) 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 selectStackRestore(MachineInstr &MI) const;
155 bool selectNamedBarrierInit(MachineInstr &I, Intrinsic::ID IID) const;
156 bool selectNamedBarrierInst(MachineInstr &I, Intrinsic::ID IID) const;
157 bool selectSBarrierSignalIsfirst(MachineInstr &I, Intrinsic::ID IID) const;
158 bool selectSGetBarrierState(MachineInstr &I, Intrinsic::ID IID) const;
159
160 std::pair<Register, unsigned> selectVOP3ModsImpl(Register Src,
161 bool IsCanonicalizing = true,
162 bool AllowAbs = true,
163 bool OpSel = false) const;
164
165 Register copyToVGPRIfSrcFolded(Register Src, unsigned Mods,
166 MachineOperand Root, MachineInstr *InsertPt,
167 bool ForceVGPR = false) const;
168
169 InstructionSelector::ComplexRendererFns
170 selectVCSRC(MachineOperand &Root) const;
171
172 InstructionSelector::ComplexRendererFns
173 selectVSRC0(MachineOperand &Root) const;
174
175 InstructionSelector::ComplexRendererFns
176 selectVOP3Mods0(MachineOperand &Root) const;
177 InstructionSelector::ComplexRendererFns
178 selectVOP3BMods0(MachineOperand &Root) const;
179 InstructionSelector::ComplexRendererFns
180 selectVOP3OMods(MachineOperand &Root) const;
181 InstructionSelector::ComplexRendererFns
182 selectVOP3Mods(MachineOperand &Root) const;
183 InstructionSelector::ComplexRendererFns
184 selectVOP3ModsNonCanonicalizing(MachineOperand &Root) const;
185 InstructionSelector::ComplexRendererFns
186 selectVOP3BMods(MachineOperand &Root) const;
187
188 ComplexRendererFns selectVOP3NoMods(MachineOperand &Root) const;
189
190 std::pair<Register, unsigned>
191 selectVOP3PModsImpl(Register Src, const MachineRegisterInfo &MRI,
192 bool IsDOT = false) const;
193
194 InstructionSelector::ComplexRendererFns
195 selectVOP3PMods(MachineOperand &Root) const;
196
197 InstructionSelector::ComplexRendererFns
198 selectVOP3PModsDOT(MachineOperand &Root) const;
199
200 InstructionSelector::ComplexRendererFns
201 selectVOP3PModsNeg(MachineOperand &Root) const;
202
203 InstructionSelector::ComplexRendererFns
204 selectWMMAOpSelVOP3PMods(MachineOperand &Root) const;
205
206 InstructionSelector::ComplexRendererFns
207 selectWMMAModsF32NegAbs(MachineOperand &Root) const;
208 InstructionSelector::ComplexRendererFns
209 selectWMMAModsF16Neg(MachineOperand &Root) const;
210 InstructionSelector::ComplexRendererFns
211 selectWMMAModsF16NegAbs(MachineOperand &Root) const;
212 InstructionSelector::ComplexRendererFns
213 selectWMMAVISrc(MachineOperand &Root) const;
214 InstructionSelector::ComplexRendererFns
215 selectSWMMACIndex8(MachineOperand &Root) const;
216 InstructionSelector::ComplexRendererFns
217 selectSWMMACIndex16(MachineOperand &Root) const;
218
219 InstructionSelector::ComplexRendererFns
220 selectVOP3OpSelMods(MachineOperand &Root) const;
221
222 InstructionSelector::ComplexRendererFns
223 selectVINTERPMods(MachineOperand &Root) const;
224 InstructionSelector::ComplexRendererFns
225 selectVINTERPModsHi(MachineOperand &Root) const;
226
227 bool selectSmrdOffset(MachineOperand &Root, Register &Base, Register *SOffset,
228 int64_t *Offset) const;
229 InstructionSelector::ComplexRendererFns
230 selectSmrdImm(MachineOperand &Root) const;
231 InstructionSelector::ComplexRendererFns
232 selectSmrdImm32(MachineOperand &Root) const;
233 InstructionSelector::ComplexRendererFns
234 selectSmrdSgpr(MachineOperand &Root) const;
235 InstructionSelector::ComplexRendererFns
236 selectSmrdSgprImm(MachineOperand &Root) const;
237
238 std::pair<Register, int> selectFlatOffsetImpl(MachineOperand &Root,
239 uint64_t FlatVariant) const;
240
241 InstructionSelector::ComplexRendererFns
242 selectFlatOffset(MachineOperand &Root) const;
243 InstructionSelector::ComplexRendererFns
244 selectGlobalOffset(MachineOperand &Root) const;
245 InstructionSelector::ComplexRendererFns
246 selectScratchOffset(MachineOperand &Root) const;
247
248 InstructionSelector::ComplexRendererFns
249 selectGlobalSAddr(MachineOperand &Root) const;
250
251 InstructionSelector::ComplexRendererFns
252 selectScratchSAddr(MachineOperand &Root) const;
253 bool checkFlatScratchSVSSwizzleBug(Register VAddr, Register SAddr,
254 uint64_t ImmOffset) const;
255 InstructionSelector::ComplexRendererFns
256 selectScratchSVAddr(MachineOperand &Root) const;
257
258 InstructionSelector::ComplexRendererFns
259 selectMUBUFScratchOffen(MachineOperand &Root) const;
260 InstructionSelector::ComplexRendererFns
261 selectMUBUFScratchOffset(MachineOperand &Root) const;
262
263 bool isDSOffsetLegal(Register Base, int64_t Offset) const;
264 bool isDSOffset2Legal(Register Base, int64_t Offset0, int64_t Offset1,
265 unsigned Size) const;
266 bool isFlatScratchBaseLegal(Register Addr) const;
267 bool isFlatScratchBaseLegalSV(Register Addr) const;
268 bool isFlatScratchBaseLegalSVImm(Register Addr) const;
269
270 std::pair<Register, unsigned>
271 selectDS1Addr1OffsetImpl(MachineOperand &Root) const;
272 InstructionSelector::ComplexRendererFns
273 selectDS1Addr1Offset(MachineOperand &Root) const;
274
275 InstructionSelector::ComplexRendererFns
276 selectDS64Bit4ByteAligned(MachineOperand &Root) const;
277
278 InstructionSelector::ComplexRendererFns
279 selectDS128Bit8ByteAligned(MachineOperand &Root) const;
280
281 std::pair<Register, unsigned> selectDSReadWrite2Impl(MachineOperand &Root,
282 unsigned size) const;
283 InstructionSelector::ComplexRendererFns
284 selectDSReadWrite2(MachineOperand &Root, unsigned size) const;
285
286 std::pair<Register, int64_t>
287 getPtrBaseWithConstantOffset(Register Root,
288 const MachineRegisterInfo &MRI) const;
289
290 // Parse out a chain of up to two g_ptr_add instructions.
291 // g_ptr_add (n0, _)
292 // g_ptr_add (n0, (n1 = g_ptr_add n2, n3))
293 struct MUBUFAddressData {
294 Register N0, N2, N3;
295 int64_t Offset = 0;
296 };
297
298 bool shouldUseAddr64(MUBUFAddressData AddrData) const;
299
300 void splitIllegalMUBUFOffset(MachineIRBuilder &B,
301 Register &SOffset, int64_t &ImmOffset) const;
302
303 MUBUFAddressData parseMUBUFAddress(Register Src) const;
304
305 bool selectMUBUFAddr64Impl(MachineOperand &Root, Register &VAddr,
306 Register &RSrcReg, Register &SOffset,
307 int64_t &Offset) const;
308
309 bool selectMUBUFOffsetImpl(MachineOperand &Root, Register &RSrcReg,
310 Register &SOffset, int64_t &Offset) const;
311
312 InstructionSelector::ComplexRendererFns
313 selectBUFSOffset(MachineOperand &Root) const;
314
315 InstructionSelector::ComplexRendererFns
316 selectMUBUFAddr64(MachineOperand &Root) const;
317
318 InstructionSelector::ComplexRendererFns
319 selectMUBUFOffset(MachineOperand &Root) const;
320
321 ComplexRendererFns selectSMRDBufferImm(MachineOperand &Root) const;
322 ComplexRendererFns selectSMRDBufferImm32(MachineOperand &Root) const;
323 ComplexRendererFns selectSMRDBufferSgprImm(MachineOperand &Root) const;
324
325 std::pair<Register, unsigned> selectVOP3PMadMixModsImpl(MachineOperand &Root,
326 bool &Matched) const;
327 ComplexRendererFns selectVOP3PMadMixModsExt(MachineOperand &Root) const;
328 ComplexRendererFns selectVOP3PMadMixMods(MachineOperand &Root) const;
329
330 void renderTruncImm32(MachineInstrBuilder &MIB, const MachineInstr &MI,
331 int OpIdx = -1) const;
332
333 void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
334 int OpIdx) const;
335 void renderZextBoolTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
336 int OpIdx) const;
337
338 void renderOpSelTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
339 int OpIdx) const;
340
341 void renderSrcAndDstSelToOpSelXForm_0_0(MachineInstrBuilder &MIB,
342 const MachineInstr &MI,
343 int OpIdx) const;
344
345 void renderSrcAndDstSelToOpSelXForm_0_1(MachineInstrBuilder &MIB,
346 const MachineInstr &MI,
347 int OpIdx) const;
348
349 void renderSrcAndDstSelToOpSelXForm_1_0(MachineInstrBuilder &MIB,
350 const MachineInstr &MI,
351 int OpIdx) const;
352
353 void renderSrcAndDstSelToOpSelXForm_1_1(MachineInstrBuilder &MIB,
354 const MachineInstr &MI,
355 int OpIdx) const;
356
357 void renderDstSelToOpSelXForm(MachineInstrBuilder &MIB,
358 const MachineInstr &MI, int OpIdx) const;
359
360 void renderSrcSelToOpSelXForm(MachineInstrBuilder &MIB,
361 const MachineInstr &MI, int OpIdx) const;
362
363 void renderSrcAndDstSelToOpSelXForm_2_0(MachineInstrBuilder &MIB,
364 const MachineInstr &MI,
365 int OpIdx) const;
366
367 void renderDstSelToOpSel3XFormXForm(MachineInstrBuilder &MIB,
368 const MachineInstr &MI, int OpIdx) const;
369
370 void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
371 int OpIdx) const;
372
373 void renderBitcastFPImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
374 int OpIdx) const;
375
376 void renderBitcastFPImm32(MachineInstrBuilder &MIB, const MachineInstr &MI,
377 int OpIdx) const {
378 renderBitcastFPImm(MIB, MI, OpIdx);
379 }
380 void renderBitcastFPImm64(MachineInstrBuilder &MIB, const MachineInstr &MI,
381 int OpIdx) const {
382 renderBitcastFPImm(MIB, MI, OpIdx);
383 }
384
385 void renderPopcntImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
386 int OpIdx) const;
387 void renderExtractCPol(MachineInstrBuilder &MIB, const MachineInstr &MI,
388 int OpIdx) const;
389 void renderExtractSWZ(MachineInstrBuilder &MIB, const MachineInstr &MI,
390 int OpIdx) const;
391 void renderExtractCpolSetGLC(MachineInstrBuilder &MIB, const MachineInstr &MI,
392 int OpIdx) const;
393
394 void renderFrameIndex(MachineInstrBuilder &MIB, const MachineInstr &MI,
395 int OpIdx) const;
396
397 void renderFPPow2ToExponent(MachineInstrBuilder &MIB, const MachineInstr &MI,
398 int OpIdx) const;
399
400 void renderRoundMode(MachineInstrBuilder &MIB, const MachineInstr &MI,
401 int OpIdx) const;
402 void renderScaledMAIIntrinsicOperand(MachineInstrBuilder &MIB,
403 const MachineInstr &MI, int OpIdx) const;
404
405 bool isInlineImmediate(const APInt &Imm) const;
406 bool isInlineImmediate(const APFloat &Imm) const;
407
408 // Returns true if TargetOpcode::G_AND MachineInstr `MI`'s masking of the
409 // shift amount operand's `ShAmtBits` bits is unneeded.
410 bool isUnneededShiftMask(const MachineInstr &MI, unsigned ShAmtBits) const;
411
412 const SIInstrInfo &TII;
413 const SIRegisterInfo &TRI;
414 const AMDGPURegisterBankInfo &RBI;
415 const AMDGPUTargetMachine &TM;
416 const GCNSubtarget &STI;
417#define GET_GLOBALISEL_PREDICATES_DECL
418#define AMDGPUSubtarget GCNSubtarget
419#include "AMDGPUGenGlobalISel.inc"
420#undef GET_GLOBALISEL_PREDICATES_DECL
421#undef AMDGPUSubtarget
422
423#define GET_GLOBALISEL_TEMPORARIES_DECL
424#include "AMDGPUGenGlobalISel.inc"
425#undef GET_GLOBALISEL_TEMPORARIES_DECL
426};
427
428} // End llvm namespace.
429#endif
430