1 //===-- AMDGPUISelLowering.cpp - AMDGPU Common DAG lowering functions -----===//
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 // This is the parent TargetLowering class for hardware code gen targets.
12 //===----------------------------------------------------------------------===//
14 #include "AMDGPUISelLowering.h"
15 #include "AMDILIntrinsicInfo.h"
16 #include "AMDGPUUtil.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine
&TM
) :
22 AMDILTargetLowering(TM
)
24 // We need to custom lower some of the intrinsics
25 setOperationAction(ISD::INTRINSIC_WO_CHAIN
, MVT::Other
, Custom
);
27 setOperationAction(ISD::SELECT_CC
, MVT::f32
, Custom
);
28 setOperationAction(ISD::SELECT_CC
, MVT::i32
, Custom
);
31 SDValue
AMDGPUTargetLowering::LowerOperation(SDValue Op
, SelectionDAG
&DAG
)
34 switch (Op
.getOpcode()) {
35 default: return AMDILTargetLowering::LowerOperation(Op
, DAG
);
36 case ISD::INTRINSIC_WO_CHAIN
: return LowerINTRINSIC_WO_CHAIN(Op
, DAG
);
37 case ISD::SELECT_CC
: return LowerSELECT_CC(Op
, DAG
);
41 SDValue
AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op
,
42 SelectionDAG
&DAG
) const
44 unsigned IntrinsicID
= cast
<ConstantSDNode
>(Op
.getOperand(0))->getZExtValue();
45 DebugLoc DL
= Op
.getDebugLoc();
46 EVT VT
= Op
.getValueType();
48 switch (IntrinsicID
) {
50 case AMDGPUIntrinsic::AMDIL_abs
:
51 return LowerIntrinsicIABS(Op
, DAG
);
52 case AMDGPUIntrinsic::AMDGPU_lrp
:
53 return LowerIntrinsicLRP(Op
, DAG
);
54 case AMDGPUIntrinsic::AMDIL_fraction
:
55 return DAG
.getNode(AMDGPUISD::FRACT
, DL
, VT
, Op
.getOperand(1));
56 case AMDGPUIntrinsic::AMDIL_mad
:
57 return DAG
.getNode(AMDILISD::MAD
, DL
, VT
, Op
.getOperand(1),
58 Op
.getOperand(2), Op
.getOperand(3));
59 case AMDGPUIntrinsic::AMDIL_max
:
60 return DAG
.getNode(AMDGPUISD::FMAX
, DL
, VT
, Op
.getOperand(1),
62 case AMDGPUIntrinsic::AMDGPU_imax
:
63 return DAG
.getNode(AMDGPUISD::SMAX
, DL
, VT
, Op
.getOperand(1),
65 case AMDGPUIntrinsic::AMDGPU_umax
:
66 return DAG
.getNode(AMDGPUISD::UMAX
, DL
, VT
, Op
.getOperand(1),
68 case AMDGPUIntrinsic::AMDIL_min
:
69 return DAG
.getNode(AMDGPUISD::FMIN
, DL
, VT
, Op
.getOperand(1),
71 case AMDGPUIntrinsic::AMDGPU_imin
:
72 return DAG
.getNode(AMDGPUISD::SMIN
, DL
, VT
, Op
.getOperand(1),
74 case AMDGPUIntrinsic::AMDGPU_umin
:
75 return DAG
.getNode(AMDGPUISD::UMIN
, DL
, VT
, Op
.getOperand(1),
80 ///IABS(a) = SMAX(sub(0, a), a)
81 SDValue
AMDGPUTargetLowering::LowerIntrinsicIABS(SDValue Op
,
82 SelectionDAG
&DAG
) const
85 DebugLoc DL
= Op
.getDebugLoc();
86 EVT VT
= Op
.getValueType();
87 SDValue Neg
= DAG
.getNode(ISD::SUB
, DL
, VT
, DAG
.getConstant(0, VT
),
90 return DAG
.getNode(AMDGPUISD::SMAX
, DL
, VT
, Neg
, Op
.getOperand(1));
93 /// Linear Interpolation
94 /// LRP(a, b, c) = muladd(a, b, (1 - a) * c)
95 SDValue
AMDGPUTargetLowering::LowerIntrinsicLRP(SDValue Op
,
96 SelectionDAG
&DAG
) const
98 DebugLoc DL
= Op
.getDebugLoc();
99 EVT VT
= Op
.getValueType();
100 SDValue OneSubA
= DAG
.getNode(ISD::FSUB
, DL
, VT
,
101 DAG
.getConstantFP(1.0f
, MVT::f32
),
103 SDValue OneSubAC
= DAG
.getNode(ISD::FMUL
, DL
, VT
, OneSubA
,
105 return DAG
.getNode(AMDILISD::MAD
, DL
, VT
, Op
.getOperand(1),
110 SDValue
AMDGPUTargetLowering::LowerSELECT_CC(SDValue Op
,
111 SelectionDAG
&DAG
) const
113 DebugLoc DL
= Op
.getDebugLoc();
114 EVT VT
= Op
.getValueType();
116 SDValue LHS
= Op
.getOperand(0);
117 SDValue RHS
= Op
.getOperand(1);
118 SDValue True
= Op
.getOperand(2);
119 SDValue False
= Op
.getOperand(3);
120 SDValue CC
= Op
.getOperand(4);
121 ISD::CondCode CCOpcode
= cast
<CondCodeSDNode
>(CC
)->get();
124 // LHS and RHS are guaranteed to be the same value type
125 EVT CompareVT
= LHS
.getValueType();
127 // We need all the operands of SELECT_CC to have the same value type, so if
128 // necessary we need to convert LHS and RHS to be the same type True and
129 // False. True and False are guaranteed to have the same type as this
132 if (CompareVT
!= VT
) {
133 ISD::NodeType ConversionOp
= ISD::DELETED_NODE
;
134 if (VT
== MVT::f32
&& CompareVT
== MVT::i32
) {
135 if (isUnsignedIntSetCC(CCOpcode
)) {
136 ConversionOp
= ISD::UINT_TO_FP
;
138 ConversionOp
= ISD::SINT_TO_FP
;
140 } else if (VT
== MVT::i32
&& CompareVT
== MVT::f32
) {
141 ConversionOp
= ISD::FP_TO_SINT
;
143 // I don't think there will be any other type pairings.
144 assert(!"Unhandled operand type parings in SELECT_CC");
146 // XXX Check the value of LHS and RHS and avoid creating sequences like
148 LHS
= DAG
.getNode(ConversionOp
, DL
, VT
, LHS
);
149 RHS
= DAG
.getNode(ConversionOp
, DL
, VT
, RHS
);
152 // If True is a hardware TRUE value and False is a hardware FALSE value or
153 // vice-versa we can handle this with a native instruction (SET* instructions).
154 if ((isHWTrueValue(True
) && isHWFalseValue(False
))) {
155 return DAG
.getNode(ISD::SELECT_CC
, DL
, VT
, LHS
, RHS
, True
, False
, CC
);
158 // XXX If True is a hardware TRUE value and False is a hardware FALSE value,
159 // we can handle this with a native instruction, but we need to swap true
160 // and false and change the conditional.
161 if (isHWTrueValue(False
) && isHWFalseValue(True
)) {
164 // XXX Check if we can lower this to a SELECT or if it is supported by a native
165 // operation. (The code below does this but we don't have the Instruction
166 // selection patterns to do this yet.
168 if (isZero(LHS
) || isZero(RHS
)) {
169 SDValue Cond
= (isZero(LHS
) ? RHS
: LHS
);
180 // We can lower to select
187 return DAG
.getNode(ISD::SELECT
, DL
, VT
, Cond
, True
, False
);
189 // Supported by a native operation (CNDGE, CNDGT)
190 return DAG
.getNode(ISD::SELECT_CC
, DL
, VT
, LHS
, RHS
, True
, False
, CC
);
195 // If we make it this for it means we have no native instructions to handle
196 // this SELECT_CC, so we must lower it.
197 SDValue HWTrue
, HWFalse
;
199 if (VT
== MVT::f32
) {
200 HWTrue
= DAG
.getConstantFP(1.0f
, VT
);
201 HWFalse
= DAG
.getConstantFP(0.0f
, VT
);
202 } else if (VT
== MVT::i32
) {
203 HWTrue
= DAG
.getConstant(-1, VT
);
204 HWFalse
= DAG
.getConstant(0, VT
);
207 assert(!"Unhandled value type in LowerSELECT_CC");
210 // Lower this unsupported SELECT_CC into a combination of two supported
211 // SELECT_CC operations.
212 SDValue Cond
= DAG
.getNode(ISD::SELECT_CC
, DL
, VT
, LHS
, RHS
, HWTrue
, HWFalse
, CC
);
214 return DAG
.getNode(ISD::SELECT
, DL
, VT
, Cond
, True
, False
);
217 //===----------------------------------------------------------------------===//
219 //===----------------------------------------------------------------------===//
221 bool AMDGPUTargetLowering::isHWTrueValue(SDValue Op
) const
223 if (ConstantFPSDNode
* CFP
= dyn_cast
<ConstantFPSDNode
>(Op
)) {
224 return CFP
->isExactlyValue(1.0);
226 if (ConstantSDNode
*C
= dyn_cast
<ConstantSDNode
>(Op
)) {
227 return C
->isAllOnesValue();
232 bool AMDGPUTargetLowering::isHWFalseValue(SDValue Op
) const
234 if (ConstantFPSDNode
* CFP
= dyn_cast
<ConstantFPSDNode
>(Op
)) {
235 return CFP
->getValueAPF().isZero();
237 if (ConstantSDNode
*C
= dyn_cast
<ConstantSDNode
>(Op
)) {
238 return C
->isNullValue();
243 void AMDGPUTargetLowering::addLiveIn(MachineInstr
* MI
,
244 MachineFunction
* MF
, MachineRegisterInfo
& MRI
,
245 const TargetInstrInfo
* TII
, unsigned reg
) const
247 AMDGPU::utilAddLiveIn(MF
, MRI
, TII
, reg
, MI
->getOperand(0).getReg());
250 #define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node;
252 const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode
) const
255 default: return AMDILTargetLowering::getTargetNodeName(Opcode
);
257 NODE_NAME_CASE(FRACT
)