1 //===- AMDGPUInstructionSelector.cpp ----------------------------*- C++ -*-==//
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
7 //===----------------------------------------------------------------------===//
9 /// This file implements the targeting of the InstructionSelector class for
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
14 #include "AMDGPUInstructionSelector.h"
15 #include "AMDGPUInstrInfo.h"
16 #include "AMDGPURegisterBankInfo.h"
17 #include "AMDGPURegisterInfo.h"
18 #include "AMDGPUSubtarget.h"
19 #include "AMDGPUTargetMachine.h"
20 #include "SIMachineFunctionInfo.h"
21 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
22 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
23 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
24 #include "llvm/CodeGen/GlobalISel/Utils.h"
25 #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"
34 #define DEBUG_TYPE "amdgpu-isel"
38 #define GET_GLOBALISEL_IMPL
39 #define AMDGPUSubtarget GCNSubtarget
40 #include "AMDGPUGenGlobalISel.inc"
41 #undef GET_GLOBALISEL_IMPL
42 #undef AMDGPUSubtarget
44 AMDGPUInstructionSelector::AMDGPUInstructionSelector(
45 const GCNSubtarget
&STI
, const AMDGPURegisterBankInfo
&RBI
,
46 const AMDGPUTargetMachine
&TM
)
47 : InstructionSelector(), TII(*STI
.getInstrInfo()),
48 TRI(*STI
.getRegisterInfo()), RBI(RBI
), TM(TM
),
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
60 const char *AMDGPUInstructionSelector::getName() { return DEBUG_TYPE
; }
62 bool AMDGPUInstructionSelector::selectCOPY(MachineInstr
&I
) const {
63 MachineBasicBlock
*BB
= I
.getParent();
64 MachineFunction
*MF
= BB
->getParent();
65 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
66 I
.setDesc(TII
.get(TargetOpcode::COPY
));
67 for (const MachineOperand
&MO
: I
.operands()) {
68 if (TargetRegisterInfo::isPhysicalRegister(MO
.getReg()))
71 const TargetRegisterClass
*RC
=
72 TRI
.getConstrainedRegClassForOperand(MO
, MRI
);
75 RBI
.constrainGenericRegister(MO
.getReg(), *RC
, MRI
);
81 AMDGPUInstructionSelector::getSubOperand64(MachineOperand
&MO
,
82 unsigned SubIdx
) const {
84 MachineInstr
*MI
= MO
.getParent();
85 MachineBasicBlock
*BB
= MO
.getParent()->getParent();
86 MachineFunction
*MF
= BB
->getParent();
87 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
88 unsigned DstReg
= MRI
.createVirtualRegister(&AMDGPU::SGPR_32RegClass
);
91 unsigned ComposedSubIdx
= TRI
.composeSubRegIndices(MO
.getSubReg(), SubIdx
);
92 unsigned Reg
= MO
.getReg();
93 BuildMI(*BB
, MI
, MI
->getDebugLoc(), TII
.get(AMDGPU::COPY
), DstReg
)
94 .addReg(Reg
, 0, ComposedSubIdx
);
96 return MachineOperand::CreateReg(DstReg
, MO
.isDef(), MO
.isImplicit(),
97 MO
.isKill(), MO
.isDead(), MO
.isUndef(),
98 MO
.isEarlyClobber(), 0, MO
.isDebug(),
104 APInt
Imm(64, MO
.getImm());
108 llvm_unreachable("do not know to split immediate with this sub index.");
110 return MachineOperand::CreateImm(Imm
.getLoBits(32).getSExtValue());
112 return MachineOperand::CreateImm(Imm
.getHiBits(32).getSExtValue());
116 static int64_t getConstant(const MachineInstr
*MI
) {
117 return MI
->getOperand(1).getCImm()->getSExtValue();
120 bool AMDGPUInstructionSelector::selectG_ADD(MachineInstr
&I
) const {
121 MachineBasicBlock
*BB
= I
.getParent();
122 MachineFunction
*MF
= BB
->getParent();
123 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
124 unsigned Size
= RBI
.getSizeInBits(I
.getOperand(0).getReg(), MRI
, TRI
);
125 unsigned DstLo
= MRI
.createVirtualRegister(&AMDGPU::SReg_32RegClass
);
126 unsigned DstHi
= MRI
.createVirtualRegister(&AMDGPU::SReg_32RegClass
);
131 DebugLoc DL
= I
.getDebugLoc();
133 MachineOperand
Lo1(getSubOperand64(I
.getOperand(1), AMDGPU::sub0
));
134 MachineOperand
Lo2(getSubOperand64(I
.getOperand(2), AMDGPU::sub0
));
136 BuildMI(*BB
, &I
, DL
, TII
.get(AMDGPU::S_ADD_U32
), DstLo
)
140 MachineOperand
Hi1(getSubOperand64(I
.getOperand(1), AMDGPU::sub1
));
141 MachineOperand
Hi2(getSubOperand64(I
.getOperand(2), AMDGPU::sub1
));
143 BuildMI(*BB
, &I
, DL
, TII
.get(AMDGPU::S_ADDC_U32
), DstHi
)
147 BuildMI(*BB
, &I
, DL
, TII
.get(AMDGPU::REG_SEQUENCE
), I
.getOperand(0).getReg())
149 .addImm(AMDGPU::sub0
)
151 .addImm(AMDGPU::sub1
);
153 for (MachineOperand
&MO
: I
.explicit_operands()) {
154 if (!MO
.isReg() || TargetRegisterInfo::isPhysicalRegister(MO
.getReg()))
156 RBI
.constrainGenericRegister(MO
.getReg(), AMDGPU::SReg_64RegClass
, MRI
);
163 bool AMDGPUInstructionSelector::selectG_GEP(MachineInstr
&I
) const {
164 return selectG_ADD(I
);
167 bool AMDGPUInstructionSelector::selectG_IMPLICIT_DEF(MachineInstr
&I
) const {
168 MachineBasicBlock
*BB
= I
.getParent();
169 MachineFunction
*MF
= BB
->getParent();
170 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
171 const MachineOperand
&MO
= I
.getOperand(0);
172 const TargetRegisterClass
*RC
=
173 TRI
.getConstrainedRegClassForOperand(MO
, MRI
);
175 RBI
.constrainGenericRegister(MO
.getReg(), *RC
, MRI
);
176 I
.setDesc(TII
.get(TargetOpcode::IMPLICIT_DEF
));
180 bool AMDGPUInstructionSelector::selectG_INTRINSIC(MachineInstr
&I
,
181 CodeGenCoverage
&CoverageInfo
) const {
182 unsigned IntrinsicID
= I
.getOperand(1).getIntrinsicID();
184 switch (IntrinsicID
) {
187 case Intrinsic::maxnum
:
188 case Intrinsic::minnum
:
189 case Intrinsic::amdgcn_cvt_pkrtz
:
190 return selectImpl(I
, CoverageInfo
);
192 case Intrinsic::amdgcn_kernarg_segment_ptr
: {
193 MachineFunction
*MF
= I
.getParent()->getParent();
194 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
195 const SIMachineFunctionInfo
*MFI
= MF
->getInfo
<SIMachineFunctionInfo
>();
196 const ArgDescriptor
*InputPtrReg
;
197 const TargetRegisterClass
*RC
;
198 const DebugLoc
&DL
= I
.getDebugLoc();
200 std::tie(InputPtrReg
, RC
)
201 = MFI
->getPreloadedValue(AMDGPUFunctionArgInfo::KERNARG_SEGMENT_PTR
);
203 report_fatal_error("missing kernarg segment ptr");
205 BuildMI(*I
.getParent(), &I
, DL
, TII
.get(AMDGPU::COPY
))
206 .add(I
.getOperand(0))
207 .addReg(MRI
.getLiveInVirtReg(InputPtrReg
->getRegister()));
215 static MachineInstr
*
216 buildEXP(const TargetInstrInfo
&TII
, MachineInstr
*Insert
, unsigned Tgt
,
217 unsigned Reg0
, unsigned Reg1
, unsigned Reg2
, unsigned Reg3
,
218 unsigned VM
, bool Compr
, unsigned Enabled
, bool Done
) {
219 const DebugLoc
&DL
= Insert
->getDebugLoc();
220 MachineBasicBlock
&BB
= *Insert
->getParent();
221 unsigned Opcode
= Done
? AMDGPU::EXP_DONE
: AMDGPU::EXP
;
222 return BuildMI(BB
, Insert
, DL
, TII
.get(Opcode
))
233 bool AMDGPUInstructionSelector::selectG_INTRINSIC_W_SIDE_EFFECTS(
235 CodeGenCoverage
&CoverageInfo
) const {
236 MachineBasicBlock
*BB
= I
.getParent();
237 MachineFunction
*MF
= BB
->getParent();
238 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
240 unsigned IntrinsicID
= I
.getOperand(0).getIntrinsicID();
241 switch (IntrinsicID
) {
242 case Intrinsic::amdgcn_exp
: {
243 int64_t Tgt
= getConstant(MRI
.getVRegDef(I
.getOperand(1).getReg()));
244 int64_t Enabled
= getConstant(MRI
.getVRegDef(I
.getOperand(2).getReg()));
245 int64_t Done
= getConstant(MRI
.getVRegDef(I
.getOperand(7).getReg()));
246 int64_t VM
= getConstant(MRI
.getVRegDef(I
.getOperand(8).getReg()));
248 MachineInstr
*Exp
= buildEXP(TII
, &I
, Tgt
, I
.getOperand(3).getReg(),
249 I
.getOperand(4).getReg(),
250 I
.getOperand(5).getReg(),
251 I
.getOperand(6).getReg(),
252 VM
, false, Enabled
, Done
);
255 return constrainSelectedInstRegOperands(*Exp
, TII
, TRI
, RBI
);
257 case Intrinsic::amdgcn_exp_compr
: {
258 const DebugLoc
&DL
= I
.getDebugLoc();
259 int64_t Tgt
= getConstant(MRI
.getVRegDef(I
.getOperand(1).getReg()));
260 int64_t Enabled
= getConstant(MRI
.getVRegDef(I
.getOperand(2).getReg()));
261 unsigned Reg0
= I
.getOperand(3).getReg();
262 unsigned Reg1
= I
.getOperand(4).getReg();
263 unsigned Undef
= MRI
.createVirtualRegister(&AMDGPU::VGPR_32RegClass
);
264 int64_t Done
= getConstant(MRI
.getVRegDef(I
.getOperand(5).getReg()));
265 int64_t VM
= getConstant(MRI
.getVRegDef(I
.getOperand(6).getReg()));
267 BuildMI(*BB
, &I
, DL
, TII
.get(AMDGPU::IMPLICIT_DEF
), Undef
);
268 MachineInstr
*Exp
= buildEXP(TII
, &I
, Tgt
, Reg0
, Reg1
, Undef
, Undef
, VM
,
269 true, Enabled
, Done
);
272 return constrainSelectedInstRegOperands(*Exp
, TII
, TRI
, RBI
);
278 bool AMDGPUInstructionSelector::selectG_STORE(MachineInstr
&I
) const {
279 MachineBasicBlock
*BB
= I
.getParent();
280 MachineFunction
*MF
= BB
->getParent();
281 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
282 DebugLoc DL
= I
.getDebugLoc();
283 unsigned StoreSize
= RBI
.getSizeInBits(I
.getOperand(0).getReg(), MRI
, TRI
);
286 // FIXME: Select store instruction based on address space
291 Opcode
= AMDGPU::FLAT_STORE_DWORD
;
294 Opcode
= AMDGPU::FLAT_STORE_DWORDX2
;
297 Opcode
= AMDGPU::FLAT_STORE_DWORDX3
;
300 Opcode
= AMDGPU::FLAT_STORE_DWORDX4
;
304 MachineInstr
*Flat
= BuildMI(*BB
, &I
, DL
, TII
.get(Opcode
))
305 .add(I
.getOperand(1))
306 .add(I
.getOperand(0))
312 // Now that we selected an opcode, we need to constrain the register
313 // operands to use appropriate classes.
314 bool Ret
= constrainSelectedInstRegOperands(*Flat
, TII
, TRI
, RBI
);
320 bool AMDGPUInstructionSelector::selectG_CONSTANT(MachineInstr
&I
) const {
321 MachineBasicBlock
*BB
= I
.getParent();
322 MachineFunction
*MF
= BB
->getParent();
323 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
324 MachineOperand
&ImmOp
= I
.getOperand(1);
326 // The AMDGPU backend only supports Imm operands and not CImm or FPImm.
327 if (ImmOp
.isFPImm()) {
328 const APInt
&Imm
= ImmOp
.getFPImm()->getValueAPF().bitcastToAPInt();
329 ImmOp
.ChangeToImmediate(Imm
.getZExtValue());
330 } else if (ImmOp
.isCImm()) {
331 ImmOp
.ChangeToImmediate(ImmOp
.getCImm()->getZExtValue());
334 unsigned DstReg
= I
.getOperand(0).getReg();
337 const RegisterBank
*RB
= MRI
.getRegBankOrNull(I
.getOperand(0).getReg());
339 IsSgpr
= RB
->getID() == AMDGPU::SGPRRegBankID
;
340 Size
= MRI
.getType(DstReg
).getSizeInBits();
342 const TargetRegisterClass
*RC
= TRI
.getRegClassForReg(MRI
, DstReg
);
343 IsSgpr
= TRI
.isSGPRClass(RC
);
344 Size
= TRI
.getRegSizeInBits(*RC
);
347 if (Size
!= 32 && Size
!= 64)
350 unsigned Opcode
= IsSgpr
? AMDGPU::S_MOV_B32
: AMDGPU::V_MOV_B32_e32
;
352 I
.setDesc(TII
.get(Opcode
));
353 I
.addImplicitDefUseOperands(*MF
);
354 return constrainSelectedInstRegOperands(I
, TII
, TRI
, RBI
);
357 DebugLoc DL
= I
.getDebugLoc();
358 const TargetRegisterClass
*RC
= IsSgpr
? &AMDGPU::SReg_32_XM0RegClass
:
359 &AMDGPU::VGPR_32RegClass
;
360 unsigned LoReg
= MRI
.createVirtualRegister(RC
);
361 unsigned HiReg
= MRI
.createVirtualRegister(RC
);
362 const APInt
&Imm
= APInt(Size
, I
.getOperand(1).getImm());
364 BuildMI(*BB
, &I
, DL
, TII
.get(Opcode
), LoReg
)
365 .addImm(Imm
.trunc(32).getZExtValue());
367 BuildMI(*BB
, &I
, DL
, TII
.get(Opcode
), HiReg
)
368 .addImm(Imm
.ashr(32).getZExtValue());
370 const MachineInstr
*RS
=
371 BuildMI(*BB
, &I
, DL
, TII
.get(AMDGPU::REG_SEQUENCE
), DstReg
)
373 .addImm(AMDGPU::sub0
)
375 .addImm(AMDGPU::sub1
);
377 // We can't call constrainSelectedInstRegOperands here, because it doesn't
378 // work for target independent opcodes
380 const TargetRegisterClass
*DstRC
=
381 TRI
.getConstrainedRegClassForOperand(RS
->getOperand(0), MRI
);
384 return RBI
.constrainGenericRegister(DstReg
, *DstRC
, MRI
);
387 static bool isConstant(const MachineInstr
&MI
) {
388 return MI
.getOpcode() == TargetOpcode::G_CONSTANT
;
391 void AMDGPUInstructionSelector::getAddrModeInfo(const MachineInstr
&Load
,
392 const MachineRegisterInfo
&MRI
, SmallVectorImpl
<GEPInfo
> &AddrInfo
) const {
394 const MachineInstr
*PtrMI
= MRI
.getUniqueVRegDef(Load
.getOperand(1).getReg());
398 if (PtrMI
->getOpcode() != TargetOpcode::G_GEP
)
401 GEPInfo
GEPInfo(*PtrMI
);
403 for (unsigned i
= 1, e
= 3; i
< e
; ++i
) {
404 const MachineOperand
&GEPOp
= PtrMI
->getOperand(i
);
405 const MachineInstr
*OpDef
= MRI
.getUniqueVRegDef(GEPOp
.getReg());
407 if (isConstant(*OpDef
)) {
408 // FIXME: Is it possible to have multiple Imm parts? Maybe if we
409 // are lacking other optimizations.
410 assert(GEPInfo
.Imm
== 0);
411 GEPInfo
.Imm
= OpDef
->getOperand(1).getCImm()->getSExtValue();
414 const RegisterBank
*OpBank
= RBI
.getRegBank(GEPOp
.getReg(), MRI
, TRI
);
415 if (OpBank
->getID() == AMDGPU::SGPRRegBankID
)
416 GEPInfo
.SgprParts
.push_back(GEPOp
.getReg());
418 GEPInfo
.VgprParts
.push_back(GEPOp
.getReg());
421 AddrInfo
.push_back(GEPInfo
);
422 getAddrModeInfo(*PtrMI
, MRI
, AddrInfo
);
425 static bool isInstrUniform(const MachineInstr
&MI
) {
426 if (!MI
.hasOneMemOperand())
429 const MachineMemOperand
*MMO
= *MI
.memoperands_begin();
430 const Value
*Ptr
= MMO
->getValue();
432 // UndefValue means this is a load of a kernel input. These are uniform.
433 // Sometimes LDS instructions have constant pointers.
434 // If Ptr is null, then that means this mem operand contains a
435 // PseudoSourceValue like GOT.
436 if (!Ptr
|| isa
<UndefValue
>(Ptr
) || isa
<Argument
>(Ptr
) ||
437 isa
<Constant
>(Ptr
) || isa
<GlobalValue
>(Ptr
))
440 if (MMO
->getAddrSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT
)
443 const Instruction
*I
= dyn_cast
<Instruction
>(Ptr
);
444 return I
&& I
->getMetadata("amdgpu.uniform");
447 static unsigned getSmrdOpcode(unsigned BaseOpcode
, unsigned LoadSize
) {
452 switch (BaseOpcode
) {
453 case AMDGPU::S_LOAD_DWORD_IMM
:
456 return AMDGPU::S_LOAD_DWORDX2_IMM
;
458 return AMDGPU::S_LOAD_DWORDX4_IMM
;
460 return AMDGPU::S_LOAD_DWORDX8_IMM
;
462 return AMDGPU::S_LOAD_DWORDX16_IMM
;
465 case AMDGPU::S_LOAD_DWORD_IMM_ci
:
468 return AMDGPU::S_LOAD_DWORDX2_IMM_ci
;
470 return AMDGPU::S_LOAD_DWORDX4_IMM_ci
;
472 return AMDGPU::S_LOAD_DWORDX8_IMM_ci
;
474 return AMDGPU::S_LOAD_DWORDX16_IMM_ci
;
477 case AMDGPU::S_LOAD_DWORD_SGPR
:
480 return AMDGPU::S_LOAD_DWORDX2_SGPR
;
482 return AMDGPU::S_LOAD_DWORDX4_SGPR
;
484 return AMDGPU::S_LOAD_DWORDX8_SGPR
;
486 return AMDGPU::S_LOAD_DWORDX16_SGPR
;
490 llvm_unreachable("Invalid base smrd opcode or size");
493 bool AMDGPUInstructionSelector::hasVgprParts(ArrayRef
<GEPInfo
> AddrInfo
) const {
494 for (const GEPInfo
&GEPInfo
: AddrInfo
) {
495 if (!GEPInfo
.VgprParts
.empty())
501 bool AMDGPUInstructionSelector::selectSMRD(MachineInstr
&I
,
502 ArrayRef
<GEPInfo
> AddrInfo
) const {
504 if (!I
.hasOneMemOperand())
507 if ((*I
.memoperands_begin())->getAddrSpace() != AMDGPUAS::CONSTANT_ADDRESS
&&
508 (*I
.memoperands_begin())->getAddrSpace() != AMDGPUAS::CONSTANT_ADDRESS_32BIT
)
511 if (!isInstrUniform(I
))
514 if (hasVgprParts(AddrInfo
))
517 MachineBasicBlock
*BB
= I
.getParent();
518 MachineFunction
*MF
= BB
->getParent();
519 const GCNSubtarget
&Subtarget
= MF
->getSubtarget
<GCNSubtarget
>();
520 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
521 unsigned DstReg
= I
.getOperand(0).getReg();
522 const DebugLoc
&DL
= I
.getDebugLoc();
524 unsigned LoadSize
= RBI
.getSizeInBits(DstReg
, MRI
, TRI
);
526 if (!AddrInfo
.empty() && AddrInfo
[0].SgprParts
.size() == 1) {
528 const GEPInfo
&GEPInfo
= AddrInfo
[0];
530 unsigned PtrReg
= GEPInfo
.SgprParts
[0];
531 int64_t EncodedImm
= AMDGPU::getSMRDEncodedOffset(Subtarget
, GEPInfo
.Imm
);
532 if (AMDGPU::isLegalSMRDImmOffset(Subtarget
, GEPInfo
.Imm
)) {
533 Opcode
= getSmrdOpcode(AMDGPU::S_LOAD_DWORD_IMM
, LoadSize
);
535 MachineInstr
*SMRD
= BuildMI(*BB
, &I
, DL
, TII
.get(Opcode
), DstReg
)
539 return constrainSelectedInstRegOperands(*SMRD
, TII
, TRI
, RBI
);
542 if (Subtarget
.getGeneration() == AMDGPUSubtarget::SEA_ISLANDS
&&
543 isUInt
<32>(EncodedImm
)) {
544 Opcode
= getSmrdOpcode(AMDGPU::S_LOAD_DWORD_IMM_ci
, LoadSize
);
545 MachineInstr
*SMRD
= BuildMI(*BB
, &I
, DL
, TII
.get(Opcode
), DstReg
)
549 return constrainSelectedInstRegOperands(*SMRD
, TII
, TRI
, RBI
);
552 if (isUInt
<32>(GEPInfo
.Imm
)) {
553 Opcode
= getSmrdOpcode(AMDGPU::S_LOAD_DWORD_SGPR
, LoadSize
);
554 unsigned OffsetReg
= MRI
.createVirtualRegister(&AMDGPU::SReg_32RegClass
);
555 BuildMI(*BB
, &I
, DL
, TII
.get(AMDGPU::S_MOV_B32
), OffsetReg
)
556 .addImm(GEPInfo
.Imm
);
558 MachineInstr
*SMRD
= BuildMI(*BB
, &I
, DL
, TII
.get(Opcode
), DstReg
)
562 return constrainSelectedInstRegOperands(*SMRD
, TII
, TRI
, RBI
);
566 unsigned PtrReg
= I
.getOperand(1).getReg();
567 Opcode
= getSmrdOpcode(AMDGPU::S_LOAD_DWORD_IMM
, LoadSize
);
568 MachineInstr
*SMRD
= BuildMI(*BB
, &I
, DL
, TII
.get(Opcode
), DstReg
)
572 return constrainSelectedInstRegOperands(*SMRD
, TII
, TRI
, RBI
);
576 bool AMDGPUInstructionSelector::selectG_LOAD(MachineInstr
&I
) const {
577 MachineBasicBlock
*BB
= I
.getParent();
578 MachineFunction
*MF
= BB
->getParent();
579 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
580 DebugLoc DL
= I
.getDebugLoc();
581 unsigned DstReg
= I
.getOperand(0).getReg();
582 unsigned PtrReg
= I
.getOperand(1).getReg();
583 unsigned LoadSize
= RBI
.getSizeInBits(DstReg
, MRI
, TRI
);
586 SmallVector
<GEPInfo
, 4> AddrInfo
;
588 getAddrModeInfo(I
, MRI
, AddrInfo
);
590 if (selectSMRD(I
, AddrInfo
)) {
597 llvm_unreachable("Load size not supported\n");
599 Opcode
= AMDGPU::FLAT_LOAD_DWORD
;
602 Opcode
= AMDGPU::FLAT_LOAD_DWORDX2
;
606 MachineInstr
*Flat
= BuildMI(*BB
, &I
, DL
, TII
.get(Opcode
))
607 .add(I
.getOperand(0))
613 bool Ret
= constrainSelectedInstRegOperands(*Flat
, TII
, TRI
, RBI
);
618 bool AMDGPUInstructionSelector::select(MachineInstr
&I
,
619 CodeGenCoverage
&CoverageInfo
) const {
621 if (!isPreISelGenericOpcode(I
.getOpcode())) {
623 return selectCOPY(I
);
627 switch (I
.getOpcode()) {
629 return selectImpl(I
, CoverageInfo
);
630 case TargetOpcode::G_ADD
:
631 return selectG_ADD(I
);
632 case TargetOpcode::G_INTTOPTR
:
633 case TargetOpcode::G_BITCAST
:
634 return selectCOPY(I
);
635 case TargetOpcode::G_CONSTANT
:
636 case TargetOpcode::G_FCONSTANT
:
637 return selectG_CONSTANT(I
);
638 case TargetOpcode::G_GEP
:
639 return selectG_GEP(I
);
640 case TargetOpcode::G_IMPLICIT_DEF
:
641 return selectG_IMPLICIT_DEF(I
);
642 case TargetOpcode::G_INTRINSIC
:
643 return selectG_INTRINSIC(I
, CoverageInfo
);
644 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
:
645 return selectG_INTRINSIC_W_SIDE_EFFECTS(I
, CoverageInfo
);
646 case TargetOpcode::G_LOAD
:
647 return selectG_LOAD(I
);
648 case TargetOpcode::G_STORE
:
649 return selectG_STORE(I
);
654 InstructionSelector::ComplexRendererFns
655 AMDGPUInstructionSelector::selectVCSRC(MachineOperand
&Root
) const {
657 [=](MachineInstrBuilder
&MIB
) { MIB
.add(Root
); }
663 /// This will select either an SGPR or VGPR operand and will save us from
664 /// having to write an extra tablegen pattern.
665 InstructionSelector::ComplexRendererFns
666 AMDGPUInstructionSelector::selectVSRC0(MachineOperand
&Root
) const {
668 [=](MachineInstrBuilder
&MIB
) { MIB
.add(Root
); }
672 InstructionSelector::ComplexRendererFns
673 AMDGPUInstructionSelector::selectVOP3Mods0(MachineOperand
&Root
) const {
675 [=](MachineInstrBuilder
&MIB
) { MIB
.add(Root
); },
676 [=](MachineInstrBuilder
&MIB
) { MIB
.addImm(0); }, // src0_mods
677 [=](MachineInstrBuilder
&MIB
) { MIB
.addImm(0); }, // clamp
678 [=](MachineInstrBuilder
&MIB
) { MIB
.addImm(0); } // omod
681 InstructionSelector::ComplexRendererFns
682 AMDGPUInstructionSelector::selectVOP3OMods(MachineOperand
&Root
) const {
684 [=](MachineInstrBuilder
&MIB
) { MIB
.add(Root
); },
685 [=](MachineInstrBuilder
&MIB
) { MIB
.addImm(0); }, // clamp
686 [=](MachineInstrBuilder
&MIB
) { MIB
.addImm(0); } // omod
690 InstructionSelector::ComplexRendererFns
691 AMDGPUInstructionSelector::selectVOP3Mods(MachineOperand
&Root
) const {
693 [=](MachineInstrBuilder
&MIB
) { MIB
.add(Root
); },
694 [=](MachineInstrBuilder
&MIB
) { MIB
.addImm(0); } // src_mods