1 //===-- AMDGPUISelLowering.h - AMDGPU Lowering Interface --------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// \brief Interface definition of the TargetLowering class that is common
12 /// to all AMD GPUs.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_LIB_TARGET_R600_AMDGPUISELLOWERING_H
17 #define LLVM_LIB_TARGET_R600_AMDGPUISELLOWERING_H
18 
19 #include "llvm/Target/TargetLowering.h"
20 
21 namespace llvm {
22 
23 class AMDGPUMachineFunction;
24 class AMDGPUSubtarget;
25 class MachineRegisterInfo;
26 
27 class AMDGPUTargetLowering : public TargetLowering {
28 protected:
29   const AMDGPUSubtarget *Subtarget;
30 
31 private:
32   SDValue LowerConstantInitializer(const Constant* Init, const GlobalValue *GV,
33                                    const SDValue &InitPtr,
34                                    SDValue Chain,
35                                    SelectionDAG &DAG) const;
36   SDValue LowerFrameIndex(SDValue Op, SelectionDAG &DAG) const;
37   SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
38   SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
39   SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
40   /// \brief Lower vector stores by merging the vector elements into an integer
41   /// of the same bitwidth.
42   SDValue MergeVectorStore(const SDValue &Op, SelectionDAG &DAG) const;
43   /// \brief Split a vector store into multiple scalar stores.
44   /// \returns The resulting chain.
45 
46   SDValue LowerFREM(SDValue Op, SelectionDAG &DAG) const;
47   SDValue LowerFCEIL(SDValue Op, SelectionDAG &DAG) const;
48   SDValue LowerFTRUNC(SDValue Op, SelectionDAG &DAG) const;
49   SDValue LowerFRINT(SDValue Op, SelectionDAG &DAG) const;
50   SDValue LowerFNEARBYINT(SDValue Op, SelectionDAG &DAG) const;
51 
52   SDValue LowerFROUND32(SDValue Op, SelectionDAG &DAG) const;
53   SDValue LowerFROUND64(SDValue Op, SelectionDAG &DAG) const;
54   SDValue LowerFROUND(SDValue Op, SelectionDAG &DAG) const;
55   SDValue LowerFFLOOR(SDValue Op, SelectionDAG &DAG) const;
56 
57   SDValue LowerCTLZ(SDValue Op, SelectionDAG &DAG) const;
58 
59   SDValue LowerINT_TO_FP32(SDValue Op, SelectionDAG &DAG, bool Signed) const;
60   SDValue LowerINT_TO_FP64(SDValue Op, SelectionDAG &DAG, bool Signed) const;
61   SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
62   SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
63 
64   SDValue LowerFP64_TO_INT(SDValue Op, SelectionDAG &DAG, bool Signed) const;
65   SDValue LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG) const;
66   SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
67 
68   SDValue LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const;
69 
70 protected:
71   SDValue performStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const;
72   SDValue performAndCombine(SDNode *N, DAGCombinerInfo &DCI) const;
73   SDValue performShlCombine(SDNode *N, DAGCombinerInfo &DCI) const;
74   SDValue performSraCombine(SDNode *N, DAGCombinerInfo &DCI) const;
75   SDValue performSrlCombine(SDNode *N, DAGCombinerInfo &DCI) const;
76   SDValue performMulCombine(SDNode *N, DAGCombinerInfo &DCI) const;
77   SDValue performCtlzCombine(SDLoc SL, SDValue Cond, SDValue LHS, SDValue RHS,
78                              DAGCombinerInfo &DCI) const;
79   SDValue performSelectCombine(SDNode *N, DAGCombinerInfo &DCI) const;
80 
81   static EVT getEquivalentMemType(LLVMContext &Context, EVT VT);
82   static EVT getEquivalentLoadRegType(LLVMContext &Context, EVT VT);
83 
84   virtual SDValue LowerGlobalAddress(AMDGPUMachineFunction *MFI, SDValue Op,
85                                      SelectionDAG &DAG) const;
86 
87   /// Return 64-bit value Op as two 32-bit integers.
88   std::pair<SDValue, SDValue> split64BitValue(SDValue Op,
89                                               SelectionDAG &DAG) const;
90   SDValue getLoHalf64(SDValue Op, SelectionDAG &DAG) const;
91   SDValue getHiHalf64(SDValue Op, SelectionDAG &DAG) const;
92 
93   /// \brief Split a vector load into a scalar load of each component.
94   SDValue ScalarizeVectorLoad(SDValue Op, SelectionDAG &DAG) const;
95 
96   /// \brief Split a vector load into 2 loads of half the vector.
97   SDValue SplitVectorLoad(SDValue Op, SelectionDAG &DAG) const;
98 
99   /// \brief Split a vector store into a scalar store of each component.
100   SDValue ScalarizeVectorStore(SDValue Op, SelectionDAG &DAG) const;
101 
102   /// \brief Split a vector store into 2 stores of half the vector.
103   SDValue SplitVectorStore(SDValue Op, SelectionDAG &DAG) const;
104 
105   SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
106   SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
107   SDValue LowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
108   SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
109   SDValue LowerDIVREM24(SDValue Op, SelectionDAG &DAG, bool sign) const;
110   void LowerUDIVREM64(SDValue Op, SelectionDAG &DAG,
111                                     SmallVectorImpl<SDValue> &Results) const;
112   bool isHWTrueValue(SDValue Op) const;
113   bool isHWFalseValue(SDValue Op) const;
114 
115   /// The SelectionDAGBuilder will automatically promote function arguments
116   /// with illegal types.  However, this does not work for the AMDGPU targets
117   /// since the function arguments are stored in memory as these illegal types.
118   /// In order to handle this properly we need to get the origianl types sizes
119   /// from the LLVM IR Function and fixup the ISD:InputArg values before
120   /// passing them to AnalyzeFormalArguments()
121   void getOriginalFunctionArgs(SelectionDAG &DAG,
122                                const Function *F,
123                                const SmallVectorImpl<ISD::InputArg> &Ins,
124                                SmallVectorImpl<ISD::InputArg> &OrigIns) const;
125   void AnalyzeFormalArguments(CCState &State,
126                               const SmallVectorImpl<ISD::InputArg> &Ins) const;
127   void AnalyzeReturn(CCState &State,
128                      const SmallVectorImpl<ISD::OutputArg> &Outs) const;
129 
130 public:
131   AMDGPUTargetLowering(TargetMachine &TM, const AMDGPUSubtarget &STI);
132 
133   bool isFAbsFree(EVT VT) const override;
134   bool isFNegFree(EVT VT) const override;
135   bool isTruncateFree(EVT Src, EVT Dest) const override;
136   bool isTruncateFree(Type *Src, Type *Dest) const override;
137 
138   bool isZExtFree(Type *Src, Type *Dest) const override;
139   bool isZExtFree(EVT Src, EVT Dest) const override;
140   bool isZExtFree(SDValue Val, EVT VT2) const override;
141 
142   bool isNarrowingProfitable(EVT VT1, EVT VT2) const override;
143 
144   MVT getVectorIdxTy(const DataLayout &) const override;
145   bool isSelectSupported(SelectSupportKind) const override;
146 
147   bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
148   bool ShouldShrinkFPConstant(EVT VT) const override;
149   bool shouldReduceLoadWidth(SDNode *Load,
150                              ISD::LoadExtType ExtType,
151                              EVT ExtVT) const override;
152 
153   bool isLoadBitCastBeneficial(EVT, EVT) const override;
154 
155   bool storeOfVectorConstantIsCheap(EVT MemVT,
156                                     unsigned NumElem,
157                                     unsigned AS) const override;
158   bool aggressivelyPreferBuildVectorSources(EVT VecVT) const override;
159   bool isCheapToSpeculateCttz() const override;
160   bool isCheapToSpeculateCtlz() const override;
161 
162   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv,
163                       bool isVarArg,
164                       const SmallVectorImpl<ISD::OutputArg> &Outs,
165                       const SmallVectorImpl<SDValue> &OutVals,
166                       SDLoc DL, SelectionDAG &DAG) const override;
167   SDValue LowerCall(CallLoweringInfo &CLI,
168                     SmallVectorImpl<SDValue> &InVals) const override;
169 
170   SDValue LowerDYNAMIC_STACKALLOC(SDValue Op,
171                                   SelectionDAG &DAG) const;
172 
173   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
174   SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
175   void ReplaceNodeResults(SDNode * N,
176                           SmallVectorImpl<SDValue> &Results,
177                           SelectionDAG &DAG) const override;
178 
179   SDValue CombineFMinMaxLegacy(SDLoc DL,
180                                EVT VT,
181                                SDValue LHS,
182                                SDValue RHS,
183                                SDValue True,
184                                SDValue False,
185                                SDValue CC,
186                                DAGCombinerInfo &DCI) const;
187 
188   const char* getTargetNodeName(unsigned Opcode) const override;
189 
190   SDValue getRsqrtEstimate(SDValue Operand,
191                            DAGCombinerInfo &DCI,
192                            unsigned &RefinementSteps,
193                            bool &UseOneConstNR) const override;
194   SDValue getRecipEstimate(SDValue Operand,
195                            DAGCombinerInfo &DCI,
196                            unsigned &RefinementSteps) const override;
197 
198   virtual SDNode *PostISelFolding(MachineSDNode *N,
199                                   SelectionDAG &DAG) const {
200     return N;
201   }
202 
203   /// \brief Determine which of the bits specified in \p Mask are known to be
204   /// either zero or one and return them in the \p KnownZero and \p KnownOne
205   /// bitsets.
206   void computeKnownBitsForTargetNode(const SDValue Op,
207                                      APInt &KnownZero,
208                                      APInt &KnownOne,
209                                      const SelectionDAG &DAG,
210                                      unsigned Depth = 0) const override;
211 
212   unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const SelectionDAG &DAG,
213                                            unsigned Depth = 0) const override;
214 
215   /// \brief Helper function that adds Reg to the LiveIn list of the DAG's
216   /// MachineFunction.
217   ///
218   /// \returns a RegisterSDNode representing Reg.
219   virtual SDValue CreateLiveInRegister(SelectionDAG &DAG,
220                                        const TargetRegisterClass *RC,
221                                        unsigned Reg, EVT VT) const;
222 
223   enum ImplicitParameter {
224     GRID_DIM,
225     GRID_OFFSET
226   };
227 
228   /// \brief Helper function that returns the byte offset of the given
229   /// type of implicit parameter.
230   uint32_t getImplicitParameterOffset(const AMDGPUMachineFunction *MFI,
231                                       const ImplicitParameter Param) const;
232 };
233 
234 namespace AMDGPUISD {
235 
236 enum NodeType : unsigned {
237   // AMDIL ISD Opcodes
238   FIRST_NUMBER = ISD::BUILTIN_OP_END,
239   CALL,        // Function call based on a single integer
240   UMUL,        // 32bit unsigned multiplication
241   RET_FLAG,
242   BRANCH_COND,
243   // End AMDIL ISD Opcodes
244   DWORDADDR,
245   FRACT,
246   CLAMP,
247 
248   // SIN_HW, COS_HW - f32 for SI, 1 ULP max error, valid from -100 pi to 100 pi.
249   // Denormals handled on some parts.
250   COS_HW,
251   SIN_HW,
252   FMAX_LEGACY,
253   FMIN_LEGACY,
254   FMAX3,
255   SMAX3,
256   UMAX3,
257   FMIN3,
258   SMIN3,
259   UMIN3,
260   URECIP,
261   DIV_SCALE,
262   DIV_FMAS,
263   DIV_FIXUP,
264   TRIG_PREOP, // 1 ULP max error for f64
265 
266   // RCP, RSQ - For f32, 1 ULP max error, no denormal handling.
267   //            For f64, max error 2^29 ULP, handles denormals.
268   RCP,
269   RSQ,
270   RSQ_LEGACY,
271   RSQ_CLAMPED,
272   LDEXP,
273   FP_CLASS,
274   DOT4,
275   CARRY,
276   BORROW,
277   BFE_U32, // Extract range of bits with zero extension to 32-bits.
278   BFE_I32, // Extract range of bits with sign extension to 32-bits.
279   BFI, // (src0 & src1) | (~src0 & src2)
280   BFM, // Insert a range of bits into a 32-bit word.
281   FFBH_U32, // ctlz with -1 if input is zero.
282   MUL_U24,
283   MUL_I24,
284   MAD_U24,
285   MAD_I24,
286   TEXTURE_FETCH,
287   EXPORT,
288   CONST_ADDRESS,
289   REGISTER_LOAD,
290   REGISTER_STORE,
291   LOAD_INPUT,
292   SAMPLE,
293   SAMPLEB,
294   SAMPLED,
295   SAMPLEL,
296 
297   // These cvt_f32_ubyte* nodes need to remain consecutive and in order.
298   CVT_F32_UBYTE0,
299   CVT_F32_UBYTE1,
300   CVT_F32_UBYTE2,
301   CVT_F32_UBYTE3,
302   /// This node is for VLIW targets and it is used to represent a vector
303   /// that is stored in consecutive registers with the same channel.
304   /// For example:
305   ///   |X  |Y|Z|W|
306   /// T0|v.x| | | |
307   /// T1|v.y| | | |
308   /// T2|v.z| | | |
309   /// T3|v.w| | | |
310   BUILD_VERTICAL_VECTOR,
311   /// Pointer to the start of the shader's constant data.
312   CONST_DATA_PTR,
313   SENDMSG,
314   INTERP_MOV,
315   INTERP_P1,
316   INTERP_P2,
317   FIRST_MEM_OPCODE_NUMBER = ISD::FIRST_TARGET_MEMORY_OPCODE,
318   STORE_MSKOR,
319   LOAD_CONSTANT,
320   TBUFFER_STORE_FORMAT,
321   LAST_AMDGPU_ISD_NUMBER
322 };
323 
324 
325 } // End namespace AMDGPUISD
326 
327 } // End namespace llvm
328 
329 #endif
330