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"
16 #include "SIInstrInfo.h"
17 #include "SIRegisterInfo.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 SITargetLowering::SITargetLowering(TargetMachine
&TM
) :
23 AMDGPUTargetLowering(TM
),
24 TII(static_cast<const SIInstrInfo
*>(TM
.getInstrInfo()))
26 addRegisterClass(MVT::v4f32
, &AMDGPU::VReg_128RegClass
);
27 addRegisterClass(MVT::f32
, &AMDGPU::VReg_32RegClass
);
28 addRegisterClass(MVT::i32
, &AMDGPU::VReg_32RegClass
);
29 addRegisterClass(MVT::i64
, &AMDGPU::VReg_64RegClass
);
30 addRegisterClass(MVT::i1
, &AMDGPU::SCCRegRegClass
);
31 addRegisterClass(MVT::i1
, &AMDGPU::VCCRegRegClass
);
33 addRegisterClass(MVT::v4i32
, &AMDGPU::SReg_128RegClass
);
34 addRegisterClass(MVT::v8i32
, &AMDGPU::SReg_256RegClass
);
36 computeRegisterProperties();
38 setOperationAction(ISD::ADD
, MVT::i64
, Legal
);
39 setOperationAction(ISD::ADD
, MVT::i32
, Legal
);
41 setOperationAction(ISD::BR_CC
, MVT::i32
, Custom
);
43 setOperationAction(ISD::SELECT_CC
, MVT::f32
, Custom
);
44 setOperationAction(ISD::SELECT_CC
, MVT::i32
, Custom
);
46 setOperationAction(ISD::SELECT_CC
, MVT::Other
, Expand
);
49 MachineBasicBlock
* SITargetLowering::EmitInstrWithCustomInserter(
50 MachineInstr
* MI
, MachineBasicBlock
* BB
) const
52 const TargetInstrInfo
* TII
= getTargetMachine().getInstrInfo();
53 MachineRegisterInfo
& MRI
= BB
->getParent()->getRegInfo();
54 MachineBasicBlock::iterator I
= MI
;
56 if (TII
->get(MI
->getOpcode()).TSFlags
& SIInstrFlags::NEED_WAIT
) {
57 AppendS_WAITCNT(MI
, *BB
, llvm::next(I
));
61 switch (MI
->getOpcode()) {
63 return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI
, BB
);
65 case AMDGPU::CLAMP_SI
:
66 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDGPU::V_MOV_B32_e64
))
67 .addOperand(MI
->getOperand(0))
68 .addOperand(MI
->getOperand(1))
69 // VSRC1-2 are unused, but we still need to fill all the
70 // operand slots, so we just reuse the VSRC0 operand
71 .addOperand(MI
->getOperand(1))
72 .addOperand(MI
->getOperand(1))
77 MI
->eraseFromParent();
81 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDGPU::V_MOV_B32_e64
))
82 .addOperand(MI
->getOperand(0))
83 .addOperand(MI
->getOperand(1))
84 // VSRC1-2 are unused, but we still need to fill all the
85 // operand slots, so we just reuse the VSRC0 operand
86 .addOperand(MI
->getOperand(1))
87 .addOperand(MI
->getOperand(1))
92 MI
->eraseFromParent();
95 case AMDGPU::SI_INTERP
:
96 LowerSI_INTERP(MI
, *BB
, I
, MRI
);
98 case AMDGPU::SI_INTERP_CONST
:
99 LowerSI_INTERP_CONST(MI
, *BB
, I
);
101 case AMDGPU::SI_V_CNDLT
:
102 LowerSI_V_CNDLT(MI
, *BB
, I
, MRI
);
104 case AMDGPU::USE_SGPR_32
:
105 case AMDGPU::USE_SGPR_64
:
106 lowerUSE_SGPR(MI
, BB
->getParent(), MRI
);
107 MI
->eraseFromParent();
109 case AMDGPU::VS_LOAD_BUFFER_INDEX
:
110 addLiveIn(MI
, BB
->getParent(), MRI
, TII
, AMDGPU::VGPR0
);
111 MI
->eraseFromParent();
117 void SITargetLowering::AppendS_WAITCNT(MachineInstr
*MI
, MachineBasicBlock
&BB
,
118 MachineBasicBlock::iterator I
) const
120 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDGPU::S_WAITCNT
))
124 void SITargetLowering::LowerSI_INTERP(MachineInstr
*MI
, MachineBasicBlock
&BB
,
125 MachineBasicBlock::iterator I
, MachineRegisterInfo
& MRI
) const
127 unsigned tmp
= MRI
.createVirtualRegister(&AMDGPU::VReg_32RegClass
);
128 MachineOperand dst
= MI
->getOperand(0);
129 MachineOperand iReg
= MI
->getOperand(1);
130 MachineOperand jReg
= MI
->getOperand(2);
131 MachineOperand attr_chan
= MI
->getOperand(3);
132 MachineOperand attr
= MI
->getOperand(4);
133 MachineOperand params
= MI
->getOperand(5);
135 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDGPU::S_MOV_B32
))
139 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDGPU::V_INTERP_P1_F32
), tmp
)
141 .addOperand(attr_chan
)
144 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDGPU::V_INTERP_P2_F32
))
148 .addOperand(attr_chan
)
151 MI
->eraseFromParent();
154 void SITargetLowering::LowerSI_INTERP_CONST(MachineInstr
*MI
,
155 MachineBasicBlock
&BB
, MachineBasicBlock::iterator I
) const
157 MachineOperand dst
= MI
->getOperand(0);
158 MachineOperand attr_chan
= MI
->getOperand(1);
159 MachineOperand attr
= MI
->getOperand(2);
160 MachineOperand params
= MI
->getOperand(3);
162 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDGPU::S_MOV_B32
))
166 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDGPU::V_INTERP_MOV_F32
))
168 .addOperand(attr_chan
)
171 MI
->eraseFromParent();
174 void SITargetLowering::LowerSI_V_CNDLT(MachineInstr
*MI
, MachineBasicBlock
&BB
,
175 MachineBasicBlock::iterator I
, MachineRegisterInfo
& MRI
) const
177 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDGPU::V_CMP_LT_F32_e32
))
178 .addOperand(MI
->getOperand(1))
179 .addReg(AMDGPU::SREG_LIT_0
);
181 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDGPU::V_CNDMASK_B32
))
182 .addOperand(MI
->getOperand(0))
183 .addOperand(MI
->getOperand(2))
184 .addOperand(MI
->getOperand(3));
186 MI
->eraseFromParent();
189 void SITargetLowering::lowerUSE_SGPR(MachineInstr
*MI
,
190 MachineFunction
* MF
, MachineRegisterInfo
& MRI
) const
192 const TargetInstrInfo
* TII
= getTargetMachine().getInstrInfo();
193 unsigned dstReg
= MI
->getOperand(0).getReg();
194 int64_t newIndex
= MI
->getOperand(1).getImm();
195 const TargetRegisterClass
* dstClass
= MRI
.getRegClass(dstReg
);
196 unsigned DwordWidth
= dstClass
->getSize() / 4;
197 assert(newIndex
% DwordWidth
== 0 && "USER_SGPR not properly aligned");
198 newIndex
= newIndex
/ DwordWidth
;
200 unsigned newReg
= dstClass
->getRegister(newIndex
);
201 addLiveIn(MI
, MF
, MRI
, TII
, newReg
);
204 EVT
SITargetLowering::getSetCCResultType(EVT VT
) const
209 //===----------------------------------------------------------------------===//
210 // Custom DAG Lowering Operations
211 //===----------------------------------------------------------------------===//
213 SDValue
SITargetLowering::LowerOperation(SDValue Op
, SelectionDAG
&DAG
) const
215 switch (Op
.getOpcode()) {
216 default: return AMDGPUTargetLowering::LowerOperation(Op
, DAG
);
217 case ISD::BR_CC
: return LowerBR_CC(Op
, DAG
);
218 case ISD::SELECT_CC
: return LowerSELECT_CC(Op
, DAG
);
222 SDValue
SITargetLowering::LowerBR_CC(SDValue Op
, SelectionDAG
&DAG
) const
224 SDValue Chain
= Op
.getOperand(0);
225 SDValue CC
= Op
.getOperand(1);
226 SDValue LHS
= Op
.getOperand(2);
227 SDValue RHS
= Op
.getOperand(3);
228 SDValue JumpT
= Op
.getOperand(4);
231 CmpValue
= DAG
.getNode(
238 Result
= DAG
.getNode(
239 AMDILISD::BRANCH_COND
,
240 CmpValue
.getDebugLoc(),
246 SDValue
SITargetLowering::LowerSELECT_CC(SDValue Op
, SelectionDAG
&DAG
) const
248 SDValue LHS
= Op
.getOperand(0);
249 SDValue RHS
= Op
.getOperand(1);
250 SDValue True
= Op
.getOperand(2);
251 SDValue False
= Op
.getOperand(3);
252 SDValue CC
= Op
.getOperand(4);
253 EVT VT
= Op
.getValueType();
254 DebugLoc DL
= Op
.getDebugLoc();
256 SDValue Cond
= DAG
.getNode(ISD::SETCC
, DL
, MVT::i1
, LHS
, RHS
, CC
);
257 return DAG
.getNode(ISD::SELECT
, DL
, VT
, Cond
, True
, False
);