1
//===-- SIISelLowering.cpp - SI DAG Lowering Implementation ---------------===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
// Most of the DAG lowering is handled in AMDGPUISelLowering.cpp. This file is
11
// mostly EmitInstrWithCustomInserter().
13
//===----------------------------------------------------------------------===//
15
#include "SIISelLowering.h"
17
#include "AMDILIntrinsicInfo.h"
18
#include "SIInstrInfo.h"
19
#include "SIRegisterInfo.h"
20
#include "llvm/CodeGen/MachineInstrBuilder.h"
21
#include "llvm/CodeGen/MachineRegisterInfo.h"
22
#include "llvm/CodeGen/SelectionDAG.h"
26
SITargetLowering::SITargetLowering(TargetMachine &TM) :
27
AMDGPUTargetLowering(TM),
28
TII(static_cast<const SIInstrInfo*>(TM.getInstrInfo()))
30
addRegisterClass(MVT::v4f32, &AMDGPU::VReg_128RegClass);
31
addRegisterClass(MVT::f32, &AMDGPU::VReg_32RegClass);
32
addRegisterClass(MVT::i32, &AMDGPU::VReg_32RegClass);
33
addRegisterClass(MVT::i64, &AMDGPU::VReg_64RegClass);
34
addRegisterClass(MVT::i1, &AMDGPU::SCCRegRegClass);
35
addRegisterClass(MVT::i1, &AMDGPU::VCCRegRegClass);
37
addRegisterClass(MVT::v4i32, &AMDGPU::SReg_128RegClass);
38
addRegisterClass(MVT::v8i32, &AMDGPU::SReg_256RegClass);
40
computeRegisterProperties();
42
setOperationAction(ISD::AND, MVT::i1, Custom);
44
setOperationAction(ISD::ADD, MVT::i64, Legal);
45
setOperationAction(ISD::ADD, MVT::i32, Legal);
47
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
49
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
51
// We need to custom lower loads from the USER_SGPR address space, so we can
52
// add the SGPRs as livein registers.
53
setOperationAction(ISD::LOAD, MVT::i32, Custom);
54
setOperationAction(ISD::LOAD, MVT::i64, Custom);
56
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
57
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
59
setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
60
setTargetDAGCombine(ISD::SELECT_CC);
62
setTargetDAGCombine(ISD::SETCC);
65
MachineBasicBlock * SITargetLowering::EmitInstrWithCustomInserter(
66
MachineInstr * MI, MachineBasicBlock * BB) const
68
const TargetInstrInfo * TII = getTargetMachine().getInstrInfo();
69
MachineRegisterInfo & MRI = BB->getParent()->getRegInfo();
70
MachineBasicBlock::iterator I = MI;
72
if (TII->get(MI->getOpcode()).TSFlags & SIInstrFlags::NEED_WAIT) {
73
AppendS_WAITCNT(MI, *BB, llvm::next(I));
77
switch (MI->getOpcode()) {
79
return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB);
81
case AMDGPU::CLAMP_SI:
82
BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::V_MOV_B32_e64))
83
.addOperand(MI->getOperand(0))
84
.addOperand(MI->getOperand(1))
85
// VSRC1-2 are unused, but we still need to fill all the
86
// operand slots, so we just reuse the VSRC0 operand
87
.addOperand(MI->getOperand(1))
88
.addOperand(MI->getOperand(1))
93
MI->eraseFromParent();
97
BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::V_MOV_B32_e64))
98
.addOperand(MI->getOperand(0))
99
.addOperand(MI->getOperand(1))
100
// VSRC1-2 are unused, but we still need to fill all the
101
// operand slots, so we just reuse the VSRC0 operand
102
.addOperand(MI->getOperand(1))
103
.addOperand(MI->getOperand(1))
108
MI->eraseFromParent();
111
case AMDGPU::FNEG_SI:
112
BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::V_MOV_B32_e64))
113
.addOperand(MI->getOperand(0))
114
.addOperand(MI->getOperand(1))
115
// VSRC1-2 are unused, but we still need to fill all the
116
// operand slots, so we just reuse the VSRC0 operand
117
.addOperand(MI->getOperand(1))
118
.addOperand(MI->getOperand(1))
123
MI->eraseFromParent();
126
case AMDGPU::SI_INTERP:
127
LowerSI_INTERP(MI, *BB, I, MRI);
129
case AMDGPU::SI_INTERP_CONST:
130
LowerSI_INTERP_CONST(MI, *BB, I, MRI);
133
LowerSI_KIL(MI, *BB, I, MRI);
135
case AMDGPU::SI_V_CNDLT:
136
LowerSI_V_CNDLT(MI, *BB, I, MRI);
142
void SITargetLowering::AppendS_WAITCNT(MachineInstr *MI, MachineBasicBlock &BB,
143
MachineBasicBlock::iterator I) const
145
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::S_WAITCNT))
149
void SITargetLowering::LowerSI_INTERP(MachineInstr *MI, MachineBasicBlock &BB,
150
MachineBasicBlock::iterator I, MachineRegisterInfo & MRI) const
152
unsigned tmp = MRI.createVirtualRegister(&AMDGPU::VReg_32RegClass);
153
unsigned M0 = MRI.createVirtualRegister(&AMDGPU::M0RegRegClass);
154
MachineOperand dst = MI->getOperand(0);
155
MachineOperand iReg = MI->getOperand(1);
156
MachineOperand jReg = MI->getOperand(2);
157
MachineOperand attr_chan = MI->getOperand(3);
158
MachineOperand attr = MI->getOperand(4);
159
MachineOperand params = MI->getOperand(5);
161
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::S_MOV_B32), M0)
164
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::V_INTERP_P1_F32), tmp)
166
.addOperand(attr_chan)
170
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::V_INTERP_P2_F32))
174
.addOperand(attr_chan)
178
MI->eraseFromParent();
181
void SITargetLowering::LowerSI_INTERP_CONST(MachineInstr *MI,
182
MachineBasicBlock &BB, MachineBasicBlock::iterator I,
183
MachineRegisterInfo &MRI) const
185
MachineOperand dst = MI->getOperand(0);
186
MachineOperand attr_chan = MI->getOperand(1);
187
MachineOperand attr = MI->getOperand(2);
188
MachineOperand params = MI->getOperand(3);
189
unsigned M0 = MRI.createVirtualRegister(&AMDGPU::M0RegRegClass);
191
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::S_MOV_B32), M0)
194
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::V_INTERP_MOV_F32))
196
.addOperand(attr_chan)
200
MI->eraseFromParent();
203
void SITargetLowering::LowerSI_KIL(MachineInstr *MI, MachineBasicBlock &BB,
204
MachineBasicBlock::iterator I, MachineRegisterInfo & MRI) const
206
// Clear this pixel from the exec mask if the operand is negative
207
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::V_CMPX_LE_F32_e32),
209
.addReg(AMDGPU::SREG_LIT_0)
210
.addOperand(MI->getOperand(0));
212
// If the exec mask is non-zero, skip the next two instructions
213
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::S_CBRANCH_EXECNZ))
215
.addReg(AMDGPU::EXEC);
217
// Exec mask is zero: Export to NULL target...
218
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::EXP))
220
.addImm(0x09) // V_008DFC_SQ_EXP_NULL
224
.addReg(AMDGPU::SREG_LIT_0)
225
.addReg(AMDGPU::SREG_LIT_0)
226
.addReg(AMDGPU::SREG_LIT_0)
227
.addReg(AMDGPU::SREG_LIT_0);
229
// ... and terminate wavefront
230
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::S_ENDPGM));
232
MI->eraseFromParent();
235
void SITargetLowering::LowerSI_V_CNDLT(MachineInstr *MI, MachineBasicBlock &BB,
236
MachineBasicBlock::iterator I, MachineRegisterInfo & MRI) const
238
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::V_CMP_LT_F32_e32),
240
.addOperand(MI->getOperand(1))
241
.addReg(AMDGPU::SREG_LIT_0);
243
BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::V_CNDMASK_B32))
244
.addOperand(MI->getOperand(0))
246
.addOperand(MI->getOperand(2))
247
.addOperand(MI->getOperand(3));
249
MI->eraseFromParent();
252
EVT SITargetLowering::getSetCCResultType(EVT VT) const
257
//===----------------------------------------------------------------------===//
258
// Custom DAG Lowering Operations
259
//===----------------------------------------------------------------------===//
261
SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
263
switch (Op.getOpcode()) {
264
default: return AMDGPUTargetLowering::LowerOperation(Op, DAG);
265
case ISD::BR_CC: return LowerBR_CC(Op, DAG);
266
case ISD::LOAD: return LowerLOAD(Op, DAG);
267
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
268
case ISD::AND: return Loweri1ContextSwitch(Op, DAG, ISD::AND);
269
case ISD::INTRINSIC_WO_CHAIN: {
270
unsigned IntrinsicID =
271
cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
272
EVT VT = Op.getValueType();
273
switch (IntrinsicID) {
274
case AMDGPUIntrinsic::SI_vs_load_buffer_index:
275
return CreateLiveInRegister(DAG, &AMDGPU::VReg_32RegClass,
277
default: return AMDGPUTargetLowering::LowerOperation(Op, DAG);
285
/// Loweri1ContextSwitch - The function is for lowering i1 operations on the
286
/// VCC register. In the VALU context, VCC is a one bit register, but in the
287
/// SALU context the VCC is a 64-bit register (1-bit per thread). Since only
288
/// the SALU can perform operations on the VCC register, we need to promote
289
/// the operand types from i1 to i64 in order for tablegen to be able to match
290
/// this operation to the correct SALU instruction. We do this promotion by
291
/// wrapping the operands in a CopyToReg node.
293
SDValue SITargetLowering::Loweri1ContextSwitch(SDValue Op,
295
unsigned VCCNode) const
297
DebugLoc DL = Op.getDebugLoc();
299
SDValue OpNode = DAG.getNode(VCCNode, DL, MVT::i64,
300
DAG.getNode(SIISD::VCC_BITCAST, DL, MVT::i64,
302
DAG.getNode(SIISD::VCC_BITCAST, DL, MVT::i64,
305
return DAG.getNode(SIISD::VCC_BITCAST, DL, MVT::i1, OpNode);
308
SDValue SITargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const
310
SDValue Chain = Op.getOperand(0);
311
SDValue CC = Op.getOperand(1);
312
SDValue LHS = Op.getOperand(2);
313
SDValue RHS = Op.getOperand(3);
314
SDValue JumpT = Op.getOperand(4);
317
CmpValue = DAG.getNode(
324
Result = DAG.getNode(
325
AMDGPUISD::BRANCH_COND,
326
CmpValue.getDebugLoc(),
332
SDValue SITargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const
334
EVT VT = Op.getValueType();
335
LoadSDNode *Ptr = dyn_cast<LoadSDNode>(Op);
339
unsigned AddrSpace = Ptr->getPointerInfo().getAddrSpace();
341
// We only need to lower USER_SGPR address space loads
342
if (AddrSpace != AMDGPUAS::USER_SGPR_ADDRESS) {
346
// Loads from the USER_SGPR address space can only have constant value
348
ConstantSDNode *BasePtr = dyn_cast<ConstantSDNode>(Ptr->getBasePtr());
351
unsigned TypeDwordWidth = VT.getSizeInBits() / 32;
352
const TargetRegisterClass * dstClass;
353
switch (TypeDwordWidth) {
355
assert(!"USER_SGPR value size not implemented");
358
dstClass = &AMDGPU::SReg_32RegClass;
361
dstClass = &AMDGPU::SReg_64RegClass;
364
uint64_t Index = BasePtr->getZExtValue();
365
assert(Index % TypeDwordWidth == 0 && "USER_SGPR not properly aligned");
366
unsigned SGPRIndex = Index / TypeDwordWidth;
367
unsigned Reg = dstClass->getRegister(SGPRIndex);
369
DAG.ReplaceAllUsesOfValueWith(Op, CreateLiveInRegister(DAG, dstClass, Reg,
374
SDValue SITargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
376
SDValue LHS = Op.getOperand(0);
377
SDValue RHS = Op.getOperand(1);
378
SDValue True = Op.getOperand(2);
379
SDValue False = Op.getOperand(3);
380
SDValue CC = Op.getOperand(4);
381
EVT VT = Op.getValueType();
382
DebugLoc DL = Op.getDebugLoc();
384
SDValue Cond = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS, CC);
385
return DAG.getNode(ISD::SELECT, DL, VT, Cond, True, False);
388
//===----------------------------------------------------------------------===//
389
// Custom DAG optimizations
390
//===----------------------------------------------------------------------===//
392
SDValue SITargetLowering::PerformDAGCombine(SDNode *N,
393
DAGCombinerInfo &DCI) const {
394
SelectionDAG &DAG = DCI.DAG;
395
DebugLoc DL = N->getDebugLoc();
396
EVT VT = N->getValueType(0);
398
switch (N->getOpcode()) {
400
case ISD::SELECT_CC: {
402
ConstantSDNode *True, *False;
403
// i1 selectcc(l, r, -1, 0, cc) -> i1 setcc(l, r, cc)
404
if ((True = dyn_cast<ConstantSDNode>(N->getOperand(2)))
405
&& (False = dyn_cast<ConstantSDNode>(N->getOperand(3)))
406
&& True->isAllOnesValue()
407
&& False->isNullValue()
409
return DAG.getNode(ISD::SETCC, DL, VT, N->getOperand(0),
410
N->getOperand(1), N->getOperand(4));
416
SDValue Arg0 = N->getOperand(0);
417
SDValue Arg1 = N->getOperand(1);
418
SDValue CC = N->getOperand(2);
419
ConstantSDNode * C = NULL;
420
ISD::CondCode CCOp = dyn_cast<CondCodeSDNode>(CC)->get();
422
// i1 setcc (sext(i1), 0, setne) -> i1 setcc(i1, 0, setne)
424
&& Arg0.getOpcode() == ISD::SIGN_EXTEND
425
&& Arg0.getOperand(0).getValueType() == MVT::i1
426
&& (C = dyn_cast<ConstantSDNode>(Arg1))
428
&& CCOp == ISD::SETNE) {
429
return SimplifySetCC(VT, Arg0.getOperand(0),
430
DAG.getConstant(0, MVT::i1), CCOp, true, DCI, DL);
438
#define NODE_NAME_CASE(node) case SIISD::node: return #node;
440
const char* SITargetLowering::getTargetNodeName(unsigned Opcode) const
443
default: return AMDGPUTargetLowering::getTargetNodeName(Opcode);
444
NODE_NAME_CASE(VCC_AND)
445
NODE_NAME_CASE(VCC_BITCAST)