LLVM 20.0.0git
AMDGPUISelDAGToDAG.h
Go to the documentation of this file.
1//===-- AMDGPUISelDAGToDAG.h - A dag to dag inst selector for AMDGPU ----===//
2//
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
6//
7//==-----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines an instruction selector for the AMDGPU target.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H
15#define LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H
16
17#include "GCNSubtarget.h"
23
24namespace llvm {
25
26static inline bool getConstantValue(SDValue N, uint32_t &Out) {
27 // This is only used for packed vectors, where using 0 for undef should
28 // always be good.
29 if (N.isUndef()) {
30 Out = 0;
31 return true;
32 }
33
34 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
35 Out = C->getAPIntValue().getSExtValue();
36 return true;
37 }
38
39 if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N)) {
40 Out = C->getValueAPF().bitcastToAPInt().getSExtValue();
41 return true;
42 }
43
44 return false;
45}
46
47// TODO: Handle undef as zero
48static inline SDNode *packConstantV2I16(const SDNode *N, SelectionDAG &DAG) {
49 assert(N->getOpcode() == ISD::BUILD_VECTOR && N->getNumOperands() == 2);
50 uint32_t LHSVal, RHSVal;
51 if (getConstantValue(N->getOperand(0), LHSVal) &&
52 getConstantValue(N->getOperand(1), RHSVal)) {
53 SDLoc SL(N);
54 uint32_t K = (LHSVal & 0xffff) | (RHSVal << 16);
55 return DAG.getMachineNode(AMDGPU::S_MOV_B32, SL, N->getValueType(0),
56 DAG.getTargetConstant(K, SL, MVT::i32));
57 }
58
59 return nullptr;
60}
61
62/// AMDGPU specific code to select AMDGPU machine instructions for
63/// SelectionDAG operations.
65 // Subtarget - Keep a pointer to the AMDGPU Subtarget around so that we can
66 // make the right decision when generating code for different targets.
67 const GCNSubtarget *Subtarget;
68
69 // Default FP mode for the current function.
71
72 // Instructions that will be lowered with a final instruction that zeros the
73 // high result bits.
74 bool fp16SrcZerosHighBits(unsigned Opc) const;
75
76public:
78
80
83 void PreprocessISelDAG() override;
84 void Select(SDNode *N) override;
85 void PostprocessISelDAG() override;
86
87protected:
88 void SelectBuildVector(SDNode *N, unsigned RegClassID);
89
90private:
91 std::pair<SDValue, SDValue> foldFrameIndex(SDValue N) const;
92
93 bool isInlineImmediate(const SDNode *N) const;
94
95 bool isInlineImmediate(const APInt &Imm) const {
96 return Subtarget->getInstrInfo()->isInlineConstant(Imm);
97 }
98
99 bool isInlineImmediate(const APFloat &Imm) const {
100 return Subtarget->getInstrInfo()->isInlineConstant(Imm);
101 }
102
103 bool isVGPRImm(const SDNode *N) const;
104 bool isUniformLoad(const SDNode *N) const;
105 bool isUniformBr(const SDNode *N) const;
106
107 // Returns true if ISD::AND SDNode `N`'s masking of the shift amount operand's
108 // `ShAmtBits` bits is unneeded.
109 bool isUnneededShiftMask(const SDNode *N, unsigned ShAmtBits) const;
110
111 bool isBaseWithConstantOffset64(SDValue Addr, SDValue &LHS,
112 SDValue &RHS) const;
113
114 MachineSDNode *buildSMovImm64(SDLoc &DL, uint64_t Val, EVT VT) const;
115
116 SDNode *glueCopyToOp(SDNode *N, SDValue NewChain, SDValue Glue) const;
117 SDNode *glueCopyToM0(SDNode *N, SDValue Val) const;
118 SDNode *glueCopyToM0LDSInit(SDNode *N) const;
119
120 const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const;
121 virtual bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset);
122 virtual bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset);
123 bool isDSOffsetLegal(SDValue Base, unsigned Offset) const;
124 bool isDSOffset2Legal(SDValue Base, unsigned Offset0, unsigned Offset1,
125 unsigned Size) const;
126
127 bool isFlatScratchBaseLegal(SDValue Addr) const;
128 bool isFlatScratchBaseLegalSV(SDValue Addr) const;
129 bool isFlatScratchBaseLegalSVImm(SDValue Addr) const;
130 bool isSOffsetLegalWithImmOffset(SDValue *SOffset, bool Imm32Only,
131 bool IsBuffer, int64_t ImmOffset = 0) const;
132
133 bool SelectDS1Addr1Offset(SDValue Ptr, SDValue &Base, SDValue &Offset) const;
134 bool SelectDS64Bit4ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0,
135 SDValue &Offset1) const;
136 bool SelectDS128Bit8ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0,
137 SDValue &Offset1) const;
138 bool SelectDSReadWrite2(SDValue Ptr, SDValue &Base, SDValue &Offset0,
139 SDValue &Offset1, unsigned Size) const;
140 bool SelectMUBUF(SDValue Addr, SDValue &SRsrc, SDValue &VAddr,
141 SDValue &SOffset, SDValue &Offset, SDValue &Offen,
142 SDValue &Idxen, SDValue &Addr64) const;
143 bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, SDValue &VAddr,
144 SDValue &SOffset, SDValue &Offset) const;
145 bool SelectMUBUFScratchOffen(SDNode *Parent, SDValue Addr, SDValue &RSrc,
146 SDValue &VAddr, SDValue &SOffset,
147 SDValue &ImmOffset) const;
148 bool SelectMUBUFScratchOffset(SDNode *Parent, SDValue Addr, SDValue &SRsrc,
149 SDValue &Soffset, SDValue &Offset) const;
150
151 bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset,
152 SDValue &Offset) const;
153 bool SelectBUFSOffset(SDValue Addr, SDValue &SOffset) const;
154
155 bool SelectFlatOffsetImpl(SDNode *N, SDValue Addr, SDValue &VAddr,
156 SDValue &Offset, uint64_t FlatVariant) const;
157 bool SelectFlatOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
158 SDValue &Offset) const;
159 bool SelectGlobalOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
160 SDValue &Offset) const;
161 bool SelectScratchOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
162 SDValue &Offset) const;
163 bool SelectGlobalSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
164 SDValue &VOffset, SDValue &Offset) const;
165 bool SelectScratchSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
166 SDValue &Offset) const;
167 bool checkFlatScratchSVSSwizzleBug(SDValue VAddr, SDValue SAddr,
168 uint64_t ImmOffset) const;
169 bool SelectScratchSVAddr(SDNode *N, SDValue Addr, SDValue &VAddr,
170 SDValue &SAddr, SDValue &Offset) const;
171
172 bool SelectSMRDOffset(SDValue ByteOffsetNode, SDValue *SOffset,
173 SDValue *Offset, bool Imm32Only = false,
174 bool IsBuffer = false, bool HasSOffset = false,
175 int64_t ImmOffset = 0) const;
176 SDValue Expand32BitAddress(SDValue Addr) const;
177 bool SelectSMRDBaseOffset(SDValue Addr, SDValue &SBase, SDValue *SOffset,
178 SDValue *Offset, bool Imm32Only = false,
179 bool IsBuffer = false, bool HasSOffset = false,
180 int64_t ImmOffset = 0) const;
181 bool SelectSMRD(SDValue Addr, SDValue &SBase, SDValue *SOffset,
182 SDValue *Offset, bool Imm32Only = false) const;
183 bool SelectSMRDImm(SDValue Addr, SDValue &SBase, SDValue &Offset) const;
184 bool SelectSMRDImm32(SDValue Addr, SDValue &SBase, SDValue &Offset) const;
185 bool SelectSMRDSgpr(SDValue Addr, SDValue &SBase, SDValue &SOffset) const;
186 bool SelectSMRDSgprImm(SDValue Addr, SDValue &SBase, SDValue &SOffset,
187 SDValue &Offset) const;
188 bool SelectSMRDBufferImm(SDValue N, SDValue &Offset) const;
189 bool SelectSMRDBufferImm32(SDValue N, SDValue &Offset) const;
190 bool SelectSMRDBufferSgprImm(SDValue N, SDValue &SOffset,
191 SDValue &Offset) const;
192 bool SelectSMRDPrefetchImm(SDValue Addr, SDValue &SBase,
193 SDValue &Offset) const;
194 bool SelectMOVRELOffset(SDValue Index, SDValue &Base, SDValue &Offset) const;
195
196 bool SelectVOP3ModsImpl(SDValue In, SDValue &Src, unsigned &SrcMods,
197 bool IsCanonicalizing = true,
198 bool AllowAbs = true) const;
199 bool SelectVOP3Mods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
200 bool SelectVOP3ModsNonCanonicalizing(SDValue In, SDValue &Src,
201 SDValue &SrcMods) const;
202 bool SelectVOP3BMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
203 bool SelectVOP3NoMods(SDValue In, SDValue &Src) const;
204 bool SelectVOP3Mods0(SDValue In, SDValue &Src, SDValue &SrcMods,
205 SDValue &Clamp, SDValue &Omod) const;
206 bool SelectVOP3BMods0(SDValue In, SDValue &Src, SDValue &SrcMods,
207 SDValue &Clamp, SDValue &Omod) const;
208 bool SelectVOP3NoMods0(SDValue In, SDValue &Src, SDValue &SrcMods,
209 SDValue &Clamp, SDValue &Omod) const;
210
211 bool SelectVINTERPModsImpl(SDValue In, SDValue &Src, SDValue &SrcMods,
212 bool OpSel) const;
213 bool SelectVINTERPMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
214 bool SelectVINTERPModsHi(SDValue In, SDValue &Src, SDValue &SrcMods) const;
215
216 bool SelectVOP3OMods(SDValue In, SDValue &Src, SDValue &Clamp,
217 SDValue &Omod) const;
218
219 bool SelectVOP3PMods(SDValue In, SDValue &Src, SDValue &SrcMods,
220 bool IsDOT = false) const;
221 bool SelectVOP3PModsDOT(SDValue In, SDValue &Src, SDValue &SrcMods) const;
222
223 bool SelectVOP3PModsNeg(SDValue In, SDValue &Src) const;
224 bool SelectWMMAOpSelVOP3PMods(SDValue In, SDValue &Src) const;
225
226 bool SelectWMMAModsF32NegAbs(SDValue In, SDValue &Src,
227 SDValue &SrcMods) const;
228 bool SelectWMMAModsF16Neg(SDValue In, SDValue &Src, SDValue &SrcMods) const;
229 bool SelectWMMAModsF16NegAbs(SDValue In, SDValue &Src,
230 SDValue &SrcMods) const;
231 bool SelectWMMAVISrc(SDValue In, SDValue &Src) const;
232
233 bool SelectSWMMACIndex8(SDValue In, SDValue &Src, SDValue &IndexKey) const;
234 bool SelectSWMMACIndex16(SDValue In, SDValue &Src, SDValue &IndexKey) const;
235
236 bool SelectVOP3OpSel(SDValue In, SDValue &Src, SDValue &SrcMods) const;
237
238 bool SelectVOP3OpSelMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
239 bool SelectVOP3PMadMixModsImpl(SDValue In, SDValue &Src,
240 unsigned &Mods) const;
241 bool SelectVOP3PMadMixModsExt(SDValue In, SDValue &Src,
242 SDValue &SrcMods) const;
243 bool SelectVOP3PMadMixMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
244
245 bool SelectBITOP3(SDValue In, SDValue &Src0, SDValue &Src1, SDValue &Src2,
246 SDValue &Tbl) const;
247
248 SDValue getHi16Elt(SDValue In) const;
249
250 SDValue getMaterializedScalarImm32(int64_t Val, const SDLoc &DL) const;
251
252 void SelectADD_SUB_I64(SDNode *N);
253 void SelectAddcSubb(SDNode *N);
254 void SelectUADDO_USUBO(SDNode *N);
255 void SelectDIV_SCALE(SDNode *N);
256 void SelectMAD_64_32(SDNode *N);
257 void SelectMUL_LOHI(SDNode *N);
258 void SelectFMA_W_CHAIN(SDNode *N);
259 void SelectFMUL_W_CHAIN(SDNode *N);
260 SDNode *getBFE32(bool IsSigned, const SDLoc &DL, SDValue Val, uint32_t Offset,
261 uint32_t Width);
262 void SelectS_BFEFromShifts(SDNode *N);
263 void SelectS_BFE(SDNode *N);
264 bool isCBranchSCC(const SDNode *N) const;
265 void SelectBRCOND(SDNode *N);
266 void SelectFMAD_FMA(SDNode *N);
267 void SelectFP_EXTEND(SDNode *N);
268 void SelectDSAppendConsume(SDNode *N, unsigned IntrID);
269 void SelectDSBvhStackIntrinsic(SDNode *N);
270 void SelectDS_GWS(SDNode *N, unsigned IntrID);
271 void SelectInterpP1F16(SDNode *N);
272 void SelectINTRINSIC_W_CHAIN(SDNode *N);
273 void SelectINTRINSIC_WO_CHAIN(SDNode *N);
274 void SelectINTRINSIC_VOID(SDNode *N);
275 void SelectWAVE_ADDRESS(SDNode *N);
276 void SelectSTACKRESTORE(SDNode *N);
277
278protected:
279 // Include the pieces autogenerated from the target description.
280#include "AMDGPUGenDAGISel.inc"
281};
282
284public:
286
289};
290
292public:
293 static char ID;
294
296
297 bool runOnMachineFunction(MachineFunction &MF) override;
298 void getAnalysisUsage(AnalysisUsage &AU) const override;
299 StringRef getPassName() const override;
300};
301
302} // namespace llvm
303
304#endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
uint64_t Addr
uint32_t Index
uint64_t Size
AMD GCN specific subclass of TargetSubtarget.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Value * RHS
Value * LHS
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
AMDGPU specific code to select AMDGPU machine instructions for SelectionDAG operations.
void SelectBuildVector(SDNode *N, unsigned RegClassID)
bool runOnMachineFunction(MachineFunction &MF) override
void PreprocessISelDAG() override
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
void PostprocessISelDAG() override
PostprocessISelDAG() - This hook allows the target to hack on the graph right after selection.
bool matchLoadD16FromBuildVector(SDNode *N) const
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Class for arbitrary precision integers.
Definition: APInt.h:78
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
Represent the analysis usage information of a pass.
const SIInstrInfo * getInstrInfo() const override
Definition: GCNSubtarget.h:279
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isInlineConstant(const APInt &Imm) const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
MachineFunction * MF
CodeGenOptLevel OptLevel
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:228
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:698
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:530
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
static bool getConstantValue(SDValue N, uint32_t &Out)
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
static SDNode * packConstantV2I16(const SDNode *N, SelectionDAG &DAG)
#define N