blob: e355af186108408bb78faa95be04fb2715bbf9e2 [file] [log] [blame]
Tom Stellardca166212017-01-30 21:56:46 +00001//===- AMDGPUInstructionSelector.cpp ----------------------------*- C++ -*-==//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Tom Stellardca166212017-01-30 21:56:46 +00006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the targeting of the InstructionSelector class for
10/// AMDGPU.
11/// \todo This should be generated by TableGen.
12//===----------------------------------------------------------------------===//
13
14#include "AMDGPUInstructionSelector.h"
15#include "AMDGPUInstrInfo.h"
16#include "AMDGPURegisterBankInfo.h"
17#include "AMDGPURegisterInfo.h"
18#include "AMDGPUSubtarget.h"
Tom Stellard1dc90202018-05-10 20:53:06 +000019#include "AMDGPUTargetMachine.h"
Matt Arsenaultb1cc4f52018-06-25 16:17:48 +000020#include "SIMachineFunctionInfo.h"
Tom Stellard44b30b42018-05-22 02:03:23 +000021#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
Tom Stellard1dc90202018-05-10 20:53:06 +000022#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
23#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
Aditya Nandakumar18b3f9d2018-01-17 19:31:33 +000024#include "llvm/CodeGen/GlobalISel/Utils.h"
Tom Stellardca166212017-01-30 21:56:46 +000025#include "llvm/CodeGen/MachineBasicBlock.h"
26#include "llvm/CodeGen/MachineFunction.h"
27#include "llvm/CodeGen/MachineInstr.h"
28#include "llvm/CodeGen/MachineInstrBuilder.h"
29#include "llvm/CodeGen/MachineRegisterInfo.h"
30#include "llvm/IR/Type.h"
31#include "llvm/Support/Debug.h"
32#include "llvm/Support/raw_ostream.h"
33
34#define DEBUG_TYPE "amdgpu-isel"
35
36using namespace llvm;
37
Tom Stellard1dc90202018-05-10 20:53:06 +000038#define GET_GLOBALISEL_IMPL
Tom Stellard5bfbae52018-07-11 20:59:01 +000039#define AMDGPUSubtarget GCNSubtarget
Tom Stellard1dc90202018-05-10 20:53:06 +000040#include "AMDGPUGenGlobalISel.inc"
41#undef GET_GLOBALISEL_IMPL
Tom Stellard5bfbae52018-07-11 20:59:01 +000042#undef AMDGPUSubtarget
Tom Stellard1dc90202018-05-10 20:53:06 +000043
Tom Stellardca166212017-01-30 21:56:46 +000044AMDGPUInstructionSelector::AMDGPUInstructionSelector(
Tom Stellard5bfbae52018-07-11 20:59:01 +000045 const GCNSubtarget &STI, const AMDGPURegisterBankInfo &RBI,
Tom Stellard1dc90202018-05-10 20:53:06 +000046 const AMDGPUTargetMachine &TM)
Tom Stellardca166212017-01-30 21:56:46 +000047 : InstructionSelector(), TII(*STI.getInstrInfo()),
Tom Stellard1dc90202018-05-10 20:53:06 +000048 TRI(*STI.getRegisterInfo()), RBI(RBI), TM(TM),
49 STI(STI),
50 EnableLateStructurizeCFG(AMDGPUTargetMachine::EnableLateStructurizeCFG),
51#define GET_GLOBALISEL_PREDICATES_INIT
52#include "AMDGPUGenGlobalISel.inc"
53#undef GET_GLOBALISEL_PREDICATES_INIT
54#define GET_GLOBALISEL_TEMPORARIES_INIT
55#include "AMDGPUGenGlobalISel.inc"
56#undef GET_GLOBALISEL_TEMPORARIES_INIT
Tom Stellard1dc90202018-05-10 20:53:06 +000057{
58}
59
60const char *AMDGPUInstructionSelector::getName() { return DEBUG_TYPE; }
Tom Stellardca166212017-01-30 21:56:46 +000061
Tom Stellard8b1c53b2019-06-17 16:27:43 +000062static bool isSCC(unsigned Reg, const MachineRegisterInfo &MRI) {
63 if (Reg == AMDGPU::SCC)
64 return true;
65
66 if (TargetRegisterInfo::isPhysicalRegister(Reg))
67 return false;
68
69 auto &RegClassOrBank = MRI.getRegClassOrRegBank(Reg);
70 const TargetRegisterClass *RC =
71 RegClassOrBank.dyn_cast<const TargetRegisterClass*>();
72 if (RC)
73 return RC->getID() == AMDGPU::SReg_32_XM0RegClassID &&
74 MRI.getType(Reg).getSizeInBits() == 1;
75
76 const RegisterBank *RB = RegClassOrBank.get<const RegisterBank *>();
77 return RB->getID() == AMDGPU::SCCRegBankID;
78}
79
Tom Stellard1e0edad2018-05-10 21:20:10 +000080bool AMDGPUInstructionSelector::selectCOPY(MachineInstr &I) const {
81 MachineBasicBlock *BB = I.getParent();
82 MachineFunction *MF = BB->getParent();
83 MachineRegisterInfo &MRI = MF->getRegInfo();
84 I.setDesc(TII.get(TargetOpcode::COPY));
Tom Stellard8b1c53b2019-06-17 16:27:43 +000085
86 // Special case for COPY from the scc register bank. The scc register bank
87 // is modeled using 32-bit sgprs.
88 const MachineOperand &Src = I.getOperand(1);
89 unsigned SrcReg = Src.getReg();
90 if (!TargetRegisterInfo::isPhysicalRegister(SrcReg) && isSCC(SrcReg, MRI)) {
91 unsigned DstReg = TRI.getRegSizeInBits(I.getOperand(0).getReg(), MRI);
92 unsigned DstSize = TRI.getRegSizeInBits(DstReg, MRI);
93
94 // We have a copy from a 32-bit to 64-bit register. This happens
95 // when we are selecting scc->vcc copies.
96 if (DstSize == 64) {
97 const DebugLoc &DL = I.getDebugLoc();
98 BuildMI(*BB, &I, DL, TII.get(AMDGPU::V_CMP_NE_U32_e64), I.getOperand(0).getReg())
99 .addImm(0)
100 .addReg(SrcReg);
101 if (!MRI.getRegClassOrNull(SrcReg))
102 MRI.setRegClass(SrcReg, TRI.getConstrainedRegClassForOperand(Src, MRI));
103 I.eraseFromParent();
104 return true;
105 }
106 }
107
Tom Stellard1e0edad2018-05-10 21:20:10 +0000108 for (const MachineOperand &MO : I.operands()) {
109 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
110 continue;
111
112 const TargetRegisterClass *RC =
113 TRI.getConstrainedRegClassForOperand(MO, MRI);
114 if (!RC)
115 continue;
116 RBI.constrainGenericRegister(MO.getReg(), *RC, MRI);
117 }
118 return true;
119}
120
Tom Stellardca166212017-01-30 21:56:46 +0000121MachineOperand
122AMDGPUInstructionSelector::getSubOperand64(MachineOperand &MO,
123 unsigned SubIdx) const {
124
125 MachineInstr *MI = MO.getParent();
126 MachineBasicBlock *BB = MO.getParent()->getParent();
127 MachineFunction *MF = BB->getParent();
128 MachineRegisterInfo &MRI = MF->getRegInfo();
129 unsigned DstReg = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
130
131 if (MO.isReg()) {
132 unsigned ComposedSubIdx = TRI.composeSubRegIndices(MO.getSubReg(), SubIdx);
133 unsigned Reg = MO.getReg();
134 BuildMI(*BB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), DstReg)
135 .addReg(Reg, 0, ComposedSubIdx);
136
137 return MachineOperand::CreateReg(DstReg, MO.isDef(), MO.isImplicit(),
138 MO.isKill(), MO.isDead(), MO.isUndef(),
139 MO.isEarlyClobber(), 0, MO.isDebug(),
140 MO.isInternalRead());
141 }
142
143 assert(MO.isImm());
144
145 APInt Imm(64, MO.getImm());
146
147 switch (SubIdx) {
148 default:
149 llvm_unreachable("do not know to split immediate with this sub index.");
150 case AMDGPU::sub0:
151 return MachineOperand::CreateImm(Imm.getLoBits(32).getSExtValue());
152 case AMDGPU::sub1:
153 return MachineOperand::CreateImm(Imm.getHiBits(32).getSExtValue());
154 }
155}
156
Tom Stellard390a5f42018-07-13 21:05:14 +0000157static int64_t getConstant(const MachineInstr *MI) {
158 return MI->getOperand(1).getCImm()->getSExtValue();
159}
160
Tom Stellardca166212017-01-30 21:56:46 +0000161bool AMDGPUInstructionSelector::selectG_ADD(MachineInstr &I) const {
162 MachineBasicBlock *BB = I.getParent();
163 MachineFunction *MF = BB->getParent();
164 MachineRegisterInfo &MRI = MF->getRegInfo();
165 unsigned Size = RBI.getSizeInBits(I.getOperand(0).getReg(), MRI, TRI);
166 unsigned DstLo = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
167 unsigned DstHi = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
168
169 if (Size != 64)
170 return false;
171
172 DebugLoc DL = I.getDebugLoc();
173
Tom Stellard124f5cc2017-01-31 15:24:11 +0000174 MachineOperand Lo1(getSubOperand64(I.getOperand(1), AMDGPU::sub0));
175 MachineOperand Lo2(getSubOperand64(I.getOperand(2), AMDGPU::sub0));
176
Tom Stellardca166212017-01-30 21:56:46 +0000177 BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADD_U32), DstLo)
Tom Stellard124f5cc2017-01-31 15:24:11 +0000178 .add(Lo1)
179 .add(Lo2);
180
181 MachineOperand Hi1(getSubOperand64(I.getOperand(1), AMDGPU::sub1));
182 MachineOperand Hi2(getSubOperand64(I.getOperand(2), AMDGPU::sub1));
Tom Stellardca166212017-01-30 21:56:46 +0000183
184 BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADDC_U32), DstHi)
Tom Stellard124f5cc2017-01-31 15:24:11 +0000185 .add(Hi1)
186 .add(Hi2);
Tom Stellardca166212017-01-30 21:56:46 +0000187
188 BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), I.getOperand(0).getReg())
189 .addReg(DstLo)
190 .addImm(AMDGPU::sub0)
191 .addReg(DstHi)
192 .addImm(AMDGPU::sub1);
193
194 for (MachineOperand &MO : I.explicit_operands()) {
195 if (!MO.isReg() || TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
196 continue;
197 RBI.constrainGenericRegister(MO.getReg(), AMDGPU::SReg_64RegClass, MRI);
198 }
199
200 I.eraseFromParent();
201 return true;
202}
203
Tom Stellard41f32192019-02-28 23:37:48 +0000204bool AMDGPUInstructionSelector::selectG_EXTRACT(MachineInstr &I) const {
205 MachineBasicBlock *BB = I.getParent();
206 MachineFunction *MF = BB->getParent();
207 MachineRegisterInfo &MRI = MF->getRegInfo();
208 assert(I.getOperand(2).getImm() % 32 == 0);
209 unsigned SubReg = TRI.getSubRegFromChannel(I.getOperand(2).getImm() / 32);
210 const DebugLoc &DL = I.getDebugLoc();
211 MachineInstr *Copy = BuildMI(*BB, &I, DL, TII.get(TargetOpcode::COPY),
212 I.getOperand(0).getReg())
213 .addReg(I.getOperand(1).getReg(), 0, SubReg);
214
215 for (const MachineOperand &MO : Copy->operands()) {
216 const TargetRegisterClass *RC =
217 TRI.getConstrainedRegClassForOperand(MO, MRI);
218 if (!RC)
219 continue;
220 RBI.constrainGenericRegister(MO.getReg(), *RC, MRI);
221 }
222 I.eraseFromParent();
223 return true;
224}
225
Tom Stellardca166212017-01-30 21:56:46 +0000226bool AMDGPUInstructionSelector::selectG_GEP(MachineInstr &I) const {
227 return selectG_ADD(I);
228}
229
Tom Stellard3f1c6fe2018-06-21 23:38:20 +0000230bool AMDGPUInstructionSelector::selectG_IMPLICIT_DEF(MachineInstr &I) const {
231 MachineBasicBlock *BB = I.getParent();
232 MachineFunction *MF = BB->getParent();
233 MachineRegisterInfo &MRI = MF->getRegInfo();
234 const MachineOperand &MO = I.getOperand(0);
235 const TargetRegisterClass *RC =
236 TRI.getConstrainedRegClassForOperand(MO, MRI);
237 if (RC)
238 RBI.constrainGenericRegister(MO.getReg(), *RC, MRI);
239 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
240 return true;
241}
242
Tom Stellard33634d1b2019-03-01 00:50:26 +0000243bool AMDGPUInstructionSelector::selectG_INSERT(MachineInstr &I) const {
244 MachineBasicBlock *BB = I.getParent();
245 MachineFunction *MF = BB->getParent();
246 MachineRegisterInfo &MRI = MF->getRegInfo();
247 unsigned SubReg = TRI.getSubRegFromChannel(I.getOperand(3).getImm() / 32);
248 DebugLoc DL = I.getDebugLoc();
249 MachineInstr *Ins = BuildMI(*BB, &I, DL, TII.get(TargetOpcode::INSERT_SUBREG))
250 .addDef(I.getOperand(0).getReg())
251 .addReg(I.getOperand(1).getReg())
252 .addReg(I.getOperand(2).getReg())
253 .addImm(SubReg);
254
255 for (const MachineOperand &MO : Ins->operands()) {
256 if (!MO.isReg())
257 continue;
258 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
259 continue;
260
261 const TargetRegisterClass *RC =
262 TRI.getConstrainedRegClassForOperand(MO, MRI);
263 if (!RC)
264 continue;
265 RBI.constrainGenericRegister(MO.getReg(), *RC, MRI);
266 }
267 I.eraseFromParent();
268 return true;
269}
270
Tom Stellarda9284732018-06-14 19:26:37 +0000271bool AMDGPUInstructionSelector::selectG_INTRINSIC(MachineInstr &I,
272 CodeGenCoverage &CoverageInfo) const {
273 unsigned IntrinsicID = I.getOperand(1).getIntrinsicID();
274
275 switch (IntrinsicID) {
276 default:
277 break;
Tom Stellardac684712018-07-13 22:16:03 +0000278 case Intrinsic::maxnum:
279 case Intrinsic::minnum:
Tom Stellarda9284732018-06-14 19:26:37 +0000280 case Intrinsic::amdgcn_cvt_pkrtz:
281 return selectImpl(I, CoverageInfo);
Matt Arsenaultb1cc4f52018-06-25 16:17:48 +0000282
283 case Intrinsic::amdgcn_kernarg_segment_ptr: {
284 MachineFunction *MF = I.getParent()->getParent();
285 MachineRegisterInfo &MRI = MF->getRegInfo();
286 const SIMachineFunctionInfo *MFI = MF->getInfo<SIMachineFunctionInfo>();
287 const ArgDescriptor *InputPtrReg;
288 const TargetRegisterClass *RC;
289 const DebugLoc &DL = I.getDebugLoc();
290
291 std::tie(InputPtrReg, RC)
292 = MFI->getPreloadedValue(AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR);
293 if (!InputPtrReg)
294 report_fatal_error("missing kernarg segment ptr");
295
296 BuildMI(*I.getParent(), &I, DL, TII.get(AMDGPU::COPY))
297 .add(I.getOperand(0))
298 .addReg(MRI.getLiveInVirtReg(InputPtrReg->getRegister()));
299 I.eraseFromParent();
300 return true;
301 }
Tom Stellarda9284732018-06-14 19:26:37 +0000302 }
303 return false;
304}
305
Tom Stellard8b1c53b2019-06-17 16:27:43 +0000306static unsigned getV_CMPOpcode(CmpInst::Predicate P, unsigned Size) {
307 assert(Size == 32 || Size == 64);
308 switch (P) {
309 default:
310 llvm_unreachable("Unknown condition code!");
311 case CmpInst::ICMP_NE:
312 return Size == 32 ? AMDGPU::V_CMP_NE_U32_e64 : AMDGPU::V_CMP_NE_U64_e64;
313 case CmpInst::ICMP_EQ:
314 return Size == 32 ? AMDGPU::V_CMP_EQ_U32_e64 : AMDGPU::V_CMP_EQ_U64_e64;
315 case CmpInst::ICMP_SGT:
316 return Size == 32 ? AMDGPU::V_CMP_GT_I32_e64 : AMDGPU::V_CMP_GT_I64_e64;
317 case CmpInst::ICMP_SGE:
318 return Size == 32 ? AMDGPU::V_CMP_GE_I32_e64 : AMDGPU::V_CMP_GE_I64_e64;
319 case CmpInst::ICMP_SLT:
320 return Size == 32 ? AMDGPU::V_CMP_LT_I32_e64 : AMDGPU::V_CMP_LT_I64_e64;
321 case CmpInst::ICMP_SLE:
322 return Size == 32 ? AMDGPU::V_CMP_LE_I32_e64 : AMDGPU::V_CMP_LE_I64_e64;
323 case CmpInst::ICMP_UGT:
324 return Size == 32 ? AMDGPU::V_CMP_GT_U32_e64 : AMDGPU::V_CMP_GT_U64_e64;
325 case CmpInst::ICMP_UGE:
326 return Size == 32 ? AMDGPU::V_CMP_GE_U32_e64 : AMDGPU::V_CMP_GE_U64_e64;
327 case CmpInst::ICMP_ULT:
328 return Size == 32 ? AMDGPU::V_CMP_LT_U32_e64 : AMDGPU::V_CMP_LT_U64_e64;
329 case CmpInst::ICMP_ULE:
330 return Size == 32 ? AMDGPU::V_CMP_LE_U32_e64 : AMDGPU::V_CMP_LE_U64_e64;
331 }
332}
333
334static unsigned getS_CMPOpcode(CmpInst::Predicate P, unsigned Size) {
335 // FIXME: VI supports 64-bit comparse.
336 assert(Size == 32);
337 switch (P) {
338 default:
339 llvm_unreachable("Unknown condition code!");
340 case CmpInst::ICMP_NE:
341 return AMDGPU::S_CMP_LG_U32;
342 case CmpInst::ICMP_EQ:
343 return AMDGPU::S_CMP_EQ_U32;
344 case CmpInst::ICMP_SGT:
345 return AMDGPU::S_CMP_GT_I32;
346 case CmpInst::ICMP_SGE:
347 return AMDGPU::S_CMP_GE_I32;
348 case CmpInst::ICMP_SLT:
349 return AMDGPU::S_CMP_LT_I32;
350 case CmpInst::ICMP_SLE:
351 return AMDGPU::S_CMP_LE_I32;
352 case CmpInst::ICMP_UGT:
353 return AMDGPU::S_CMP_GT_U32;
354 case CmpInst::ICMP_UGE:
355 return AMDGPU::S_CMP_GE_U32;
356 case CmpInst::ICMP_ULT:
357 return AMDGPU::S_CMP_LT_U32;
358 case CmpInst::ICMP_ULE:
359 return AMDGPU::S_CMP_LE_U32;
360 }
361}
362
363bool AMDGPUInstructionSelector::selectG_ICMP(MachineInstr &I) const {
364 MachineBasicBlock *BB = I.getParent();
365 MachineFunction *MF = BB->getParent();
366 MachineRegisterInfo &MRI = MF->getRegInfo();
367 DebugLoc DL = I.getDebugLoc();
368
369 unsigned SrcReg = I.getOperand(2).getReg();
370 unsigned Size = RBI.getSizeInBits(SrcReg, MRI, TRI);
371 // FIXME: VI supports 64-bit compares.
372 assert(Size == 32);
373
374 unsigned CCReg = I.getOperand(0).getReg();
375 if (isSCC(CCReg, MRI)) {
376 unsigned Opcode = getS_CMPOpcode((CmpInst::Predicate)I.getOperand(1).getPredicate(), Size);
377 MachineInstr *ICmp = BuildMI(*BB, &I, DL, TII.get(Opcode))
378 .add(I.getOperand(2))
379 .add(I.getOperand(3));
380 MachineInstr *Copy = BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), CCReg)
381 .addReg(AMDGPU::SCC);
382 bool Ret = constrainSelectedInstRegOperands(*ICmp, TII, TRI, RBI) |
383 constrainSelectedInstRegOperands(*Copy, TII, TRI, RBI);
384 I.eraseFromParent();
385 return Ret;
386 }
387
388 assert(Size == 32 || Size == 64);
389 unsigned Opcode = getV_CMPOpcode((CmpInst::Predicate)I.getOperand(1).getPredicate(), Size);
390 MachineInstr *ICmp = BuildMI(*BB, &I, DL, TII.get(Opcode),
391 I.getOperand(0).getReg())
392 .add(I.getOperand(2))
393 .add(I.getOperand(3));
394 RBI.constrainGenericRegister(ICmp->getOperand(0).getReg(),
395 AMDGPU::SReg_64RegClass, MRI);
396 bool Ret = constrainSelectedInstRegOperands(*ICmp, TII, TRI, RBI);
397 I.eraseFromParent();
398 return Ret;
399}
400
Tom Stellard390a5f42018-07-13 21:05:14 +0000401static MachineInstr *
402buildEXP(const TargetInstrInfo &TII, MachineInstr *Insert, unsigned Tgt,
403 unsigned Reg0, unsigned Reg1, unsigned Reg2, unsigned Reg3,
404 unsigned VM, bool Compr, unsigned Enabled, bool Done) {
405 const DebugLoc &DL = Insert->getDebugLoc();
406 MachineBasicBlock &BB = *Insert->getParent();
407 unsigned Opcode = Done ? AMDGPU::EXP_DONE : AMDGPU::EXP;
408 return BuildMI(BB, Insert, DL, TII.get(Opcode))
409 .addImm(Tgt)
410 .addReg(Reg0)
411 .addReg(Reg1)
412 .addReg(Reg2)
413 .addReg(Reg3)
414 .addImm(VM)
415 .addImm(Compr)
416 .addImm(Enabled);
417}
418
419bool AMDGPUInstructionSelector::selectG_INTRINSIC_W_SIDE_EFFECTS(
420 MachineInstr &I,
421 CodeGenCoverage &CoverageInfo) const {
422 MachineBasicBlock *BB = I.getParent();
423 MachineFunction *MF = BB->getParent();
424 MachineRegisterInfo &MRI = MF->getRegInfo();
425
426 unsigned IntrinsicID = I.getOperand(0).getIntrinsicID();
427 switch (IntrinsicID) {
428 case Intrinsic::amdgcn_exp: {
429 int64_t Tgt = getConstant(MRI.getVRegDef(I.getOperand(1).getReg()));
430 int64_t Enabled = getConstant(MRI.getVRegDef(I.getOperand(2).getReg()));
431 int64_t Done = getConstant(MRI.getVRegDef(I.getOperand(7).getReg()));
432 int64_t VM = getConstant(MRI.getVRegDef(I.getOperand(8).getReg()));
433
434 MachineInstr *Exp = buildEXP(TII, &I, Tgt, I.getOperand(3).getReg(),
435 I.getOperand(4).getReg(),
436 I.getOperand(5).getReg(),
437 I.getOperand(6).getReg(),
438 VM, false, Enabled, Done);
439
440 I.eraseFromParent();
441 return constrainSelectedInstRegOperands(*Exp, TII, TRI, RBI);
442 }
443 case Intrinsic::amdgcn_exp_compr: {
444 const DebugLoc &DL = I.getDebugLoc();
445 int64_t Tgt = getConstant(MRI.getVRegDef(I.getOperand(1).getReg()));
446 int64_t Enabled = getConstant(MRI.getVRegDef(I.getOperand(2).getReg()));
447 unsigned Reg0 = I.getOperand(3).getReg();
448 unsigned Reg1 = I.getOperand(4).getReg();
449 unsigned Undef = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
450 int64_t Done = getConstant(MRI.getVRegDef(I.getOperand(5).getReg()));
451 int64_t VM = getConstant(MRI.getVRegDef(I.getOperand(6).getReg()));
452
453 BuildMI(*BB, &I, DL, TII.get(AMDGPU::IMPLICIT_DEF), Undef);
454 MachineInstr *Exp = buildEXP(TII, &I, Tgt, Reg0, Reg1, Undef, Undef, VM,
455 true, Enabled, Done);
456
457 I.eraseFromParent();
458 return constrainSelectedInstRegOperands(*Exp, TII, TRI, RBI);
459 }
460 }
461 return false;
462}
463
Tom Stellard8b1c53b2019-06-17 16:27:43 +0000464bool AMDGPUInstructionSelector::selectG_SELECT(MachineInstr &I) const {
465 MachineBasicBlock *BB = I.getParent();
466 MachineFunction *MF = BB->getParent();
467 MachineRegisterInfo &MRI = MF->getRegInfo();
468 const DebugLoc &DL = I.getDebugLoc();
469
470 unsigned DstReg = I.getOperand(0).getReg();
471 unsigned Size = RBI.getSizeInBits(DstReg, MRI, TRI);
472 assert(Size == 32 || Size == 64);
473 const MachineOperand &CCOp = I.getOperand(1);
474 unsigned CCReg = CCOp.getReg();
475 if (isSCC(CCReg, MRI)) {
476 unsigned SelectOpcode = Size == 32 ? AMDGPU::S_CSELECT_B32 :
477 AMDGPU::S_CSELECT_B64;
478 MachineInstr *CopySCC = BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), AMDGPU::SCC)
479 .addReg(CCReg);
480
481 // The generic constrainSelectedInstRegOperands doesn't work for the scc register
482 // bank, because it does not cover the register class that we used to represent
483 // for it. So we need to manually set the register class here.
484 if (!MRI.getRegClassOrNull(CCReg))
485 MRI.setRegClass(CCReg, TRI.getConstrainedRegClassForOperand(CCOp, MRI));
486 MachineInstr *Select = BuildMI(*BB, &I, DL, TII.get(SelectOpcode), DstReg)
487 .add(I.getOperand(2))
488 .add(I.getOperand(3));
489
490 bool Ret = constrainSelectedInstRegOperands(*Select, TII, TRI, RBI) |
491 constrainSelectedInstRegOperands(*CopySCC, TII, TRI, RBI);
492 I.eraseFromParent();
493 return Ret;
494 }
495
496 assert(Size == 32);
497 // FIXME: Support 64-bit select
498 MachineInstr *Select =
499 BuildMI(*BB, &I, DL, TII.get(AMDGPU::V_CNDMASK_B32_e64), DstReg)
500 .addImm(0)
501 .add(I.getOperand(3))
502 .addImm(0)
503 .add(I.getOperand(2))
504 .add(I.getOperand(1));
505
506 bool Ret = constrainSelectedInstRegOperands(*Select, TII, TRI, RBI);
507 I.eraseFromParent();
508 return Ret;
509}
510
Tom Stellardca166212017-01-30 21:56:46 +0000511bool AMDGPUInstructionSelector::selectG_STORE(MachineInstr &I) const {
512 MachineBasicBlock *BB = I.getParent();
Tom Stellard655fdd32018-05-11 23:12:49 +0000513 MachineFunction *MF = BB->getParent();
514 MachineRegisterInfo &MRI = MF->getRegInfo();
Tom Stellardca166212017-01-30 21:56:46 +0000515 DebugLoc DL = I.getDebugLoc();
Tom Stellard655fdd32018-05-11 23:12:49 +0000516 unsigned StoreSize = RBI.getSizeInBits(I.getOperand(0).getReg(), MRI, TRI);
517 unsigned Opcode;
Tom Stellardca166212017-01-30 21:56:46 +0000518
519 // FIXME: Select store instruction based on address space
Tom Stellard655fdd32018-05-11 23:12:49 +0000520 switch (StoreSize) {
521 default:
522 return false;
523 case 32:
524 Opcode = AMDGPU::FLAT_STORE_DWORD;
525 break;
526 case 64:
527 Opcode = AMDGPU::FLAT_STORE_DWORDX2;
528 break;
529 case 96:
530 Opcode = AMDGPU::FLAT_STORE_DWORDX3;
531 break;
532 case 128:
533 Opcode = AMDGPU::FLAT_STORE_DWORDX4;
534 break;
535 }
536
537 MachineInstr *Flat = BuildMI(*BB, &I, DL, TII.get(Opcode))
Tom Stellardca166212017-01-30 21:56:46 +0000538 .add(I.getOperand(1))
539 .add(I.getOperand(0))
Matt Arsenaultfd023142017-06-12 15:55:58 +0000540 .addImm(0) // offset
541 .addImm(0) // glc
Stanislav Mekhanoshina6322942019-04-30 22:08:23 +0000542 .addImm(0) // slc
543 .addImm(0); // dlc
Tom Stellardca166212017-01-30 21:56:46 +0000544
Matt Arsenault47ccafe2017-05-11 17:38:33 +0000545
Tom Stellardca166212017-01-30 21:56:46 +0000546 // Now that we selected an opcode, we need to constrain the register
547 // operands to use appropriate classes.
548 bool Ret = constrainSelectedInstRegOperands(*Flat, TII, TRI, RBI);
549
550 I.eraseFromParent();
551 return Ret;
552}
553
554bool AMDGPUInstructionSelector::selectG_CONSTANT(MachineInstr &I) const {
555 MachineBasicBlock *BB = I.getParent();
556 MachineFunction *MF = BB->getParent();
557 MachineRegisterInfo &MRI = MF->getRegInfo();
Tom Stellarde182b282018-05-15 17:57:09 +0000558 MachineOperand &ImmOp = I.getOperand(1);
Tom Stellardca166212017-01-30 21:56:46 +0000559
Tom Stellarde182b282018-05-15 17:57:09 +0000560 // The AMDGPU backend only supports Imm operands and not CImm or FPImm.
561 if (ImmOp.isFPImm()) {
562 const APInt &Imm = ImmOp.getFPImm()->getValueAPF().bitcastToAPInt();
563 ImmOp.ChangeToImmediate(Imm.getZExtValue());
564 } else if (ImmOp.isCImm()) {
565 ImmOp.ChangeToImmediate(ImmOp.getCImm()->getZExtValue());
566 }
567
568 unsigned DstReg = I.getOperand(0).getReg();
569 unsigned Size;
570 bool IsSgpr;
571 const RegisterBank *RB = MRI.getRegBankOrNull(I.getOperand(0).getReg());
572 if (RB) {
573 IsSgpr = RB->getID() == AMDGPU::SGPRRegBankID;
574 Size = MRI.getType(DstReg).getSizeInBits();
575 } else {
576 const TargetRegisterClass *RC = TRI.getRegClassForReg(MRI, DstReg);
577 IsSgpr = TRI.isSGPRClass(RC);
Tom Stellarda91ce172018-05-21 17:49:31 +0000578 Size = TRI.getRegSizeInBits(*RC);
Tom Stellarde182b282018-05-15 17:57:09 +0000579 }
580
581 if (Size != 32 && Size != 64)
582 return false;
583
584 unsigned Opcode = IsSgpr ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
Tom Stellardca166212017-01-30 21:56:46 +0000585 if (Size == 32) {
Tom Stellarde182b282018-05-15 17:57:09 +0000586 I.setDesc(TII.get(Opcode));
587 I.addImplicitDefUseOperands(*MF);
Tom Stellardca166212017-01-30 21:56:46 +0000588 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
589 }
590
Tom Stellardca166212017-01-30 21:56:46 +0000591 DebugLoc DL = I.getDebugLoc();
Tom Stellarde182b282018-05-15 17:57:09 +0000592 const TargetRegisterClass *RC = IsSgpr ? &AMDGPU::SReg_32_XM0RegClass :
593 &AMDGPU::VGPR_32RegClass;
594 unsigned LoReg = MRI.createVirtualRegister(RC);
595 unsigned HiReg = MRI.createVirtualRegister(RC);
596 const APInt &Imm = APInt(Size, I.getOperand(1).getImm());
Tom Stellardca166212017-01-30 21:56:46 +0000597
Tom Stellarde182b282018-05-15 17:57:09 +0000598 BuildMI(*BB, &I, DL, TII.get(Opcode), LoReg)
Tom Stellardca166212017-01-30 21:56:46 +0000599 .addImm(Imm.trunc(32).getZExtValue());
600
Tom Stellarde182b282018-05-15 17:57:09 +0000601 BuildMI(*BB, &I, DL, TII.get(Opcode), HiReg)
Tom Stellardca166212017-01-30 21:56:46 +0000602 .addImm(Imm.ashr(32).getZExtValue());
603
Tom Stellarde182b282018-05-15 17:57:09 +0000604 const MachineInstr *RS =
605 BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)
606 .addReg(LoReg)
607 .addImm(AMDGPU::sub0)
608 .addReg(HiReg)
609 .addImm(AMDGPU::sub1);
610
Tom Stellardca166212017-01-30 21:56:46 +0000611 // We can't call constrainSelectedInstRegOperands here, because it doesn't
612 // work for target independent opcodes
613 I.eraseFromParent();
Tom Stellarde182b282018-05-15 17:57:09 +0000614 const TargetRegisterClass *DstRC =
615 TRI.getConstrainedRegClassForOperand(RS->getOperand(0), MRI);
616 if (!DstRC)
617 return true;
618 return RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
Tom Stellardca166212017-01-30 21:56:46 +0000619}
620
621static bool isConstant(const MachineInstr &MI) {
622 return MI.getOpcode() == TargetOpcode::G_CONSTANT;
623}
624
625void AMDGPUInstructionSelector::getAddrModeInfo(const MachineInstr &Load,
626 const MachineRegisterInfo &MRI, SmallVectorImpl<GEPInfo> &AddrInfo) const {
627
628 const MachineInstr *PtrMI = MRI.getUniqueVRegDef(Load.getOperand(1).getReg());
629
630 assert(PtrMI);
631
632 if (PtrMI->getOpcode() != TargetOpcode::G_GEP)
633 return;
634
635 GEPInfo GEPInfo(*PtrMI);
636
637 for (unsigned i = 1, e = 3; i < e; ++i) {
638 const MachineOperand &GEPOp = PtrMI->getOperand(i);
639 const MachineInstr *OpDef = MRI.getUniqueVRegDef(GEPOp.getReg());
640 assert(OpDef);
641 if (isConstant(*OpDef)) {
642 // FIXME: Is it possible to have multiple Imm parts? Maybe if we
643 // are lacking other optimizations.
644 assert(GEPInfo.Imm == 0);
645 GEPInfo.Imm = OpDef->getOperand(1).getCImm()->getSExtValue();
646 continue;
647 }
648 const RegisterBank *OpBank = RBI.getRegBank(GEPOp.getReg(), MRI, TRI);
649 if (OpBank->getID() == AMDGPU::SGPRRegBankID)
650 GEPInfo.SgprParts.push_back(GEPOp.getReg());
651 else
652 GEPInfo.VgprParts.push_back(GEPOp.getReg());
653 }
654
655 AddrInfo.push_back(GEPInfo);
656 getAddrModeInfo(*PtrMI, MRI, AddrInfo);
657}
658
Tom Stellard79b5c382019-02-20 21:02:37 +0000659bool AMDGPUInstructionSelector::isInstrUniform(const MachineInstr &MI) const {
Tom Stellardca166212017-01-30 21:56:46 +0000660 if (!MI.hasOneMemOperand())
661 return false;
662
663 const MachineMemOperand *MMO = *MI.memoperands_begin();
664 const Value *Ptr = MMO->getValue();
665
666 // UndefValue means this is a load of a kernel input. These are uniform.
667 // Sometimes LDS instructions have constant pointers.
668 // If Ptr is null, then that means this mem operand contains a
669 // PseudoSourceValue like GOT.
670 if (!Ptr || isa<UndefValue>(Ptr) || isa<Argument>(Ptr) ||
671 isa<Constant>(Ptr) || isa<GlobalValue>(Ptr))
672 return true;
673
Matt Arsenault923712b2018-02-09 16:57:57 +0000674 if (MMO->getAddrSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT)
675 return true;
676
Tom Stellardca166212017-01-30 21:56:46 +0000677 const Instruction *I = dyn_cast<Instruction>(Ptr);
678 return I && I->getMetadata("amdgpu.uniform");
679}
680
Tom Stellardca166212017-01-30 21:56:46 +0000681bool AMDGPUInstructionSelector::hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const {
682 for (const GEPInfo &GEPInfo : AddrInfo) {
683 if (!GEPInfo.VgprParts.empty())
684 return true;
685 }
686 return false;
687}
688
Tom Stellardca166212017-01-30 21:56:46 +0000689bool AMDGPUInstructionSelector::selectG_LOAD(MachineInstr &I) const {
690 MachineBasicBlock *BB = I.getParent();
691 MachineFunction *MF = BB->getParent();
692 MachineRegisterInfo &MRI = MF->getRegInfo();
693 DebugLoc DL = I.getDebugLoc();
694 unsigned DstReg = I.getOperand(0).getReg();
695 unsigned PtrReg = I.getOperand(1).getReg();
696 unsigned LoadSize = RBI.getSizeInBits(DstReg, MRI, TRI);
697 unsigned Opcode;
698
699 SmallVector<GEPInfo, 4> AddrInfo;
700
701 getAddrModeInfo(I, MRI, AddrInfo);
702
Tom Stellardca166212017-01-30 21:56:46 +0000703 switch (LoadSize) {
704 default:
705 llvm_unreachable("Load size not supported\n");
706 case 32:
707 Opcode = AMDGPU::FLAT_LOAD_DWORD;
708 break;
709 case 64:
710 Opcode = AMDGPU::FLAT_LOAD_DWORDX2;
711 break;
712 }
713
714 MachineInstr *Flat = BuildMI(*BB, &I, DL, TII.get(Opcode))
715 .add(I.getOperand(0))
716 .addReg(PtrReg)
Matt Arsenaultfd023142017-06-12 15:55:58 +0000717 .addImm(0) // offset
718 .addImm(0) // glc
Stanislav Mekhanoshina6322942019-04-30 22:08:23 +0000719 .addImm(0) // slc
720 .addImm(0); // dlc
Tom Stellardca166212017-01-30 21:56:46 +0000721
722 bool Ret = constrainSelectedInstRegOperands(*Flat, TII, TRI, RBI);
723 I.eraseFromParent();
724 return Ret;
725}
726
Daniel Sandersf76f3152017-11-16 00:46:35 +0000727bool AMDGPUInstructionSelector::select(MachineInstr &I,
728 CodeGenCoverage &CoverageInfo) const {
Tom Stellardca166212017-01-30 21:56:46 +0000729
Tom Stellard7712ee82018-06-22 00:44:29 +0000730 if (!isPreISelGenericOpcode(I.getOpcode())) {
731 if (I.isCopy())
732 return selectCOPY(I);
Tom Stellardca166212017-01-30 21:56:46 +0000733 return true;
Tom Stellard7712ee82018-06-22 00:44:29 +0000734 }
Tom Stellardca166212017-01-30 21:56:46 +0000735
736 switch (I.getOpcode()) {
737 default:
Tom Stellard1dc90202018-05-10 20:53:06 +0000738 return selectImpl(I, CoverageInfo);
Tom Stellardca166212017-01-30 21:56:46 +0000739 case TargetOpcode::G_ADD:
740 return selectG_ADD(I);
Tom Stellard7c650782018-10-05 04:34:09 +0000741 case TargetOpcode::G_INTTOPTR:
Tom Stellard1e0edad2018-05-10 21:20:10 +0000742 case TargetOpcode::G_BITCAST:
743 return selectCOPY(I);
Tom Stellardca166212017-01-30 21:56:46 +0000744 case TargetOpcode::G_CONSTANT:
Tom Stellarde182b282018-05-15 17:57:09 +0000745 case TargetOpcode::G_FCONSTANT:
Tom Stellardca166212017-01-30 21:56:46 +0000746 return selectG_CONSTANT(I);
Tom Stellard41f32192019-02-28 23:37:48 +0000747 case TargetOpcode::G_EXTRACT:
748 return selectG_EXTRACT(I);
Tom Stellardca166212017-01-30 21:56:46 +0000749 case TargetOpcode::G_GEP:
750 return selectG_GEP(I);
Tom Stellard3f1c6fe2018-06-21 23:38:20 +0000751 case TargetOpcode::G_IMPLICIT_DEF:
752 return selectG_IMPLICIT_DEF(I);
Tom Stellard33634d1b2019-03-01 00:50:26 +0000753 case TargetOpcode::G_INSERT:
754 return selectG_INSERT(I);
Tom Stellarda9284732018-06-14 19:26:37 +0000755 case TargetOpcode::G_INTRINSIC:
756 return selectG_INTRINSIC(I, CoverageInfo);
Tom Stellard390a5f42018-07-13 21:05:14 +0000757 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
758 return selectG_INTRINSIC_W_SIDE_EFFECTS(I, CoverageInfo);
Tom Stellard8b1c53b2019-06-17 16:27:43 +0000759 case TargetOpcode::G_ICMP:
760 return selectG_ICMP(I);
Tom Stellardca166212017-01-30 21:56:46 +0000761 case TargetOpcode::G_LOAD:
Tom Stellard79b5c382019-02-20 21:02:37 +0000762 if (selectImpl(I, CoverageInfo))
763 return true;
Tom Stellardca166212017-01-30 21:56:46 +0000764 return selectG_LOAD(I);
Tom Stellard8b1c53b2019-06-17 16:27:43 +0000765 case TargetOpcode::G_SELECT:
766 return selectG_SELECT(I);
Tom Stellardca166212017-01-30 21:56:46 +0000767 case TargetOpcode::G_STORE:
768 return selectG_STORE(I);
769 }
770 return false;
771}
Tom Stellard1dc90202018-05-10 20:53:06 +0000772
Tom Stellard26fac0f2018-06-22 02:54:57 +0000773InstructionSelector::ComplexRendererFns
774AMDGPUInstructionSelector::selectVCSRC(MachineOperand &Root) const {
775 return {{
776 [=](MachineInstrBuilder &MIB) { MIB.add(Root); }
777 }};
778
779}
780
Tom Stellard1dc90202018-05-10 20:53:06 +0000781///
782/// This will select either an SGPR or VGPR operand and will save us from
783/// having to write an extra tablegen pattern.
784InstructionSelector::ComplexRendererFns
785AMDGPUInstructionSelector::selectVSRC0(MachineOperand &Root) const {
786 return {{
787 [=](MachineInstrBuilder &MIB) { MIB.add(Root); }
788 }};
789}
Tom Stellarddcc95e92018-05-11 05:44:16 +0000790
791InstructionSelector::ComplexRendererFns
792AMDGPUInstructionSelector::selectVOP3Mods0(MachineOperand &Root) const {
793 return {{
794 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
795 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, // src0_mods
796 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, // clamp
797 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); } // omod
798 }};
799}
Tom Stellard9a653572018-06-22 02:34:29 +0000800InstructionSelector::ComplexRendererFns
801AMDGPUInstructionSelector::selectVOP3OMods(MachineOperand &Root) const {
802 return {{
803 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
804 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, // clamp
805 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); } // omod
806 }};
807}
Tom Stellard46bbbc32018-06-13 22:30:47 +0000808
809InstructionSelector::ComplexRendererFns
810AMDGPUInstructionSelector::selectVOP3Mods(MachineOperand &Root) const {
811 return {{
812 [=](MachineInstrBuilder &MIB) { MIB.add(Root); },
813 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); } // src_mods
814 }};
815}
Tom Stellard79b5c382019-02-20 21:02:37 +0000816
817InstructionSelector::ComplexRendererFns
818AMDGPUInstructionSelector::selectSmrdImm(MachineOperand &Root) const {
819 MachineRegisterInfo &MRI =
820 Root.getParent()->getParent()->getParent()->getRegInfo();
821
822 SmallVector<GEPInfo, 4> AddrInfo;
823 getAddrModeInfo(*Root.getParent(), MRI, AddrInfo);
824
825 if (AddrInfo.empty() || AddrInfo[0].SgprParts.size() != 1)
826 return None;
827
828 const GEPInfo &GEPInfo = AddrInfo[0];
829
830 if (!AMDGPU::isLegalSMRDImmOffset(STI, GEPInfo.Imm))
831 return None;
832
833 unsigned PtrReg = GEPInfo.SgprParts[0];
834 int64_t EncodedImm = AMDGPU::getSMRDEncodedOffset(STI, GEPInfo.Imm);
835 return {{
836 [=](MachineInstrBuilder &MIB) { MIB.addReg(PtrReg); },
837 [=](MachineInstrBuilder &MIB) { MIB.addImm(EncodedImm); }
838 }};
839}
840
841InstructionSelector::ComplexRendererFns
842AMDGPUInstructionSelector::selectSmrdImm32(MachineOperand &Root) const {
843 MachineRegisterInfo &MRI =
844 Root.getParent()->getParent()->getParent()->getRegInfo();
845
846 SmallVector<GEPInfo, 4> AddrInfo;
847 getAddrModeInfo(*Root.getParent(), MRI, AddrInfo);
848
849 if (AddrInfo.empty() || AddrInfo[0].SgprParts.size() != 1)
850 return None;
851
852 const GEPInfo &GEPInfo = AddrInfo[0];
853 unsigned PtrReg = GEPInfo.SgprParts[0];
854 int64_t EncodedImm = AMDGPU::getSMRDEncodedOffset(STI, GEPInfo.Imm);
855 if (!isUInt<32>(EncodedImm))
856 return None;
857
858 return {{
859 [=](MachineInstrBuilder &MIB) { MIB.addReg(PtrReg); },
860 [=](MachineInstrBuilder &MIB) { MIB.addImm(EncodedImm); }
861 }};
862}
863
864InstructionSelector::ComplexRendererFns
865AMDGPUInstructionSelector::selectSmrdSgpr(MachineOperand &Root) const {
866 MachineInstr *MI = Root.getParent();
867 MachineBasicBlock *MBB = MI->getParent();
868 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
869
870 SmallVector<GEPInfo, 4> AddrInfo;
871 getAddrModeInfo(*MI, MRI, AddrInfo);
872
873 // FIXME: We should shrink the GEP if the offset is known to be <= 32-bits,
874 // then we can select all ptr + 32-bit offsets not just immediate offsets.
875 if (AddrInfo.empty() || AddrInfo[0].SgprParts.size() != 1)
876 return None;
877
878 const GEPInfo &GEPInfo = AddrInfo[0];
879 if (!GEPInfo.Imm || !isUInt<32>(GEPInfo.Imm))
880 return None;
881
882 // If we make it this far we have a load with an 32-bit immediate offset.
883 // It is OK to select this using a sgpr offset, because we have already
884 // failed trying to select this load into one of the _IMM variants since
885 // the _IMM Patterns are considered before the _SGPR patterns.
886 unsigned PtrReg = GEPInfo.SgprParts[0];
887 unsigned OffsetReg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
888 BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::S_MOV_B32), OffsetReg)
889 .addImm(GEPInfo.Imm);
890 return {{
891 [=](MachineInstrBuilder &MIB) { MIB.addReg(PtrReg); },
892 [=](MachineInstrBuilder &MIB) { MIB.addReg(OffsetReg); }
893 }};
894}