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"
22
23namespace llvm {
24
25static inline bool getConstantValue(SDValue N, uint32_t &Out) {
26 // This is only used for packed vectors, where using 0 for undef should
27 // always be good.
28 if (N.isUndef()) {
29 Out = 0;
30 return true;
31 }
32
33 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
34 Out = C->getAPIntValue().getSExtValue();
35 return true;
36 }
37
38 if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N)) {
39 Out = C->getValueAPF().bitcastToAPInt().getSExtValue();
40 return true;
41 }
42
43 return false;
44}
45
46// TODO: Handle undef as zero
47static inline SDNode *packConstantV2I16(const SDNode *N, SelectionDAG &DAG) {
48 assert(N->getOpcode() == ISD::BUILD_VECTOR && N->getNumOperands() == 2);
49 uint32_t LHSVal, RHSVal;
50 if (getConstantValue(N->getOperand(0), LHSVal) &&
51 getConstantValue(N->getOperand(1), RHSVal)) {
52 SDLoc SL(N);
53 uint32_t K = (LHSVal & 0xffff) | (RHSVal << 16);
54 return DAG.getMachineNode(AMDGPU::S_MOV_B32, SL, N->getValueType(0),
55 DAG.getTargetConstant(K, SL, MVT::i32));
56 }
57
58 return nullptr;
59}
60
61/// AMDGPU specific code to select AMDGPU machine instructions for
62/// SelectionDAG operations.
64 // Subtarget - Keep a pointer to the AMDGPU Subtarget around so that we can
65 // make the right decision when generating code for different targets.
66 const GCNSubtarget *Subtarget;
67
68 // Default FP mode for the current function.
70
71 bool EnableLateStructurizeCFG;
72
73 // Instructions that will be lowered with a final instruction that zeros the
74 // high result bits.
75 bool fp16SrcZerosHighBits(unsigned Opc) const;
76
77public:
79
81
84 void PreprocessISelDAG() override;
85 void Select(SDNode *N) override;
86 void PostprocessISelDAG() override;
87
88protected:
89 void SelectBuildVector(SDNode *N, unsigned RegClassID);
90
91private:
92 std::pair<SDValue, SDValue> foldFrameIndex(SDValue N) const;
93
94 bool isInlineImmediate(const SDNode *N) const;
95
96 bool isInlineImmediate(const APInt &Imm) const {
97 return Subtarget->getInstrInfo()->isInlineConstant(Imm);
98 }
99
100 bool isInlineImmediate(const APFloat &Imm) const {
101 return Subtarget->getInstrInfo()->isInlineConstant(Imm);
102 }
103
104 bool isVGPRImm(const SDNode *N) const;
105 bool isUniformLoad(const SDNode *N) const;
106 bool isUniformBr(const SDNode *N) const;
107
108 // Returns true if ISD::AND SDNode `N`'s masking of the shift amount operand's
109 // `ShAmtBits` bits is unneeded.
110 bool isUnneededShiftMask(const SDNode *N, unsigned ShAmtBits) const;
111
112 bool isBaseWithConstantOffset64(SDValue Addr, SDValue &LHS,
113 SDValue &RHS) const;
114
115 MachineSDNode *buildSMovImm64(SDLoc &DL, uint64_t Val, EVT VT) const;
116
117 SDNode *glueCopyToOp(SDNode *N, SDValue NewChain, SDValue Glue) const;
118 SDNode *glueCopyToM0(SDNode *N, SDValue Val) const;
119 SDNode *glueCopyToM0LDSInit(SDNode *N) const;
120
121 const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const;
122 virtual bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset);
123 virtual bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset);
124 bool isDSOffsetLegal(SDValue Base, unsigned Offset) const;
125 bool isDSOffset2Legal(SDValue Base, unsigned Offset0, unsigned Offset1,
126 unsigned Size) const;
127
128 bool isFlatScratchBaseLegal(SDValue Addr) const;
129 bool isFlatScratchBaseLegalSV(SDValue Addr) const;
130 bool isFlatScratchBaseLegalSVImm(SDValue Addr) const;
131 bool isSOffsetLegalWithImmOffset(SDValue *SOffset, bool Imm32Only,
132 bool IsBuffer, int64_t ImmOffset = 0) const;
133
134 bool SelectDS1Addr1Offset(SDValue Ptr, SDValue &Base, SDValue &Offset) const;
135 bool SelectDS64Bit4ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0,
136 SDValue &Offset1) const;
137 bool SelectDS128Bit8ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0,
138 SDValue &Offset1) const;
139 bool SelectDSReadWrite2(SDValue Ptr, SDValue &Base, SDValue &Offset0,
140 SDValue &Offset1, unsigned Size) const;
141 bool SelectMUBUF(SDValue Addr, SDValue &SRsrc, SDValue &VAddr,
142 SDValue &SOffset, SDValue &Offset, SDValue &Offen,
143 SDValue &Idxen, SDValue &Addr64) const;
144 bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, SDValue &VAddr,
145 SDValue &SOffset, SDValue &Offset) const;
146 bool SelectMUBUFScratchOffen(SDNode *Parent, SDValue Addr, SDValue &RSrc,
147 SDValue &VAddr, SDValue &SOffset,
148 SDValue &ImmOffset) const;
149 bool SelectMUBUFScratchOffset(SDNode *Parent, SDValue Addr, SDValue &SRsrc,
150 SDValue &Soffset, SDValue &Offset) const;
151
152 bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset,
153 SDValue &Offset) const;
154 bool SelectBUFSOffset(SDValue Addr, SDValue &SOffset) const;
155
156 bool SelectFlatOffsetImpl(SDNode *N, SDValue Addr, SDValue &VAddr,
157 SDValue &Offset, uint64_t FlatVariant) const;
158 bool SelectFlatOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
159 SDValue &Offset) const;
160 bool SelectGlobalOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
161 SDValue &Offset) const;
162 bool SelectScratchOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
163 SDValue &Offset) const;
164 bool SelectGlobalSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
165 SDValue &VOffset, SDValue &Offset) const;
166 bool SelectScratchSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
167 SDValue &Offset) const;
168 bool checkFlatScratchSVSSwizzleBug(SDValue VAddr, SDValue SAddr,
169 uint64_t ImmOffset) const;
170 bool SelectScratchSVAddr(SDNode *N, SDValue Addr, SDValue &VAddr,
171 SDValue &SAddr, SDValue &Offset) const;
172
173 bool SelectSMRDOffset(SDValue ByteOffsetNode, SDValue *SOffset,
174 SDValue *Offset, bool Imm32Only = false,
175 bool IsBuffer = false, bool HasSOffset = false,
176 int64_t ImmOffset = 0) const;
177 SDValue Expand32BitAddress(SDValue Addr) const;
178 bool SelectSMRDBaseOffset(SDValue Addr, SDValue &SBase, SDValue *SOffset,
179 SDValue *Offset, bool Imm32Only = false,
180 bool IsBuffer = false, bool HasSOffset = false,
181 int64_t ImmOffset = 0) const;
182 bool SelectSMRD(SDValue Addr, SDValue &SBase, SDValue *SOffset,
183 SDValue *Offset, bool Imm32Only = false) const;
184 bool SelectSMRDImm(SDValue Addr, SDValue &SBase, SDValue &Offset) const;
185 bool SelectSMRDImm32(SDValue Addr, SDValue &SBase, SDValue &Offset) const;
186 bool SelectSMRDSgpr(SDValue Addr, SDValue &SBase, SDValue &SOffset) const;
187 bool SelectSMRDSgprImm(SDValue Addr, SDValue &SBase, SDValue &SOffset,
188 SDValue &Offset) const;
189 bool SelectSMRDBufferImm(SDValue N, SDValue &Offset) const;
190 bool SelectSMRDBufferImm32(SDValue N, SDValue &Offset) const;
191 bool SelectSMRDBufferSgprImm(SDValue N, SDValue &SOffset,
192 SDValue &Offset) const;
193 bool SelectSMRDPrefetchImm(SDValue Addr, SDValue &SBase,
194 SDValue &Offset) const;
195 bool SelectMOVRELOffset(SDValue Index, SDValue &Base, SDValue &Offset) const;
196
197 bool SelectVOP3ModsImpl(SDValue In, SDValue &Src, unsigned &SrcMods,
198 bool IsCanonicalizing = true,
199 bool AllowAbs = true) const;
200 bool SelectVOP3Mods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
201 bool SelectVOP3ModsNonCanonicalizing(SDValue In, SDValue &Src,
202 SDValue &SrcMods) const;
203 bool SelectVOP3BMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
204 bool SelectVOP3NoMods(SDValue In, SDValue &Src) const;
205 bool SelectVOP3Mods0(SDValue In, SDValue &Src, SDValue &SrcMods,
206 SDValue &Clamp, SDValue &Omod) const;
207 bool SelectVOP3BMods0(SDValue In, SDValue &Src, SDValue &SrcMods,
208 SDValue &Clamp, SDValue &Omod) const;
209 bool SelectVOP3NoMods0(SDValue In, SDValue &Src, SDValue &SrcMods,
210 SDValue &Clamp, SDValue &Omod) const;
211
212 bool SelectVINTERPModsImpl(SDValue In, SDValue &Src, SDValue &SrcMods,
213 bool OpSel) const;
214 bool SelectVINTERPMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
215 bool SelectVINTERPModsHi(SDValue In, SDValue &Src, SDValue &SrcMods) const;
216
217 bool SelectVOP3OMods(SDValue In, SDValue &Src, SDValue &Clamp,
218 SDValue &Omod) const;
219
220 bool SelectVOP3PMods(SDValue In, SDValue &Src, SDValue &SrcMods,
221 bool IsDOT = false) const;
222 bool SelectVOP3PModsDOT(SDValue In, SDValue &Src, SDValue &SrcMods) const;
223
224 bool SelectVOP3PModsNeg(SDValue In, SDValue &Src) const;
225 bool SelectWMMAOpSelVOP3PMods(SDValue In, SDValue &Src) const;
226
227 bool SelectWMMAModsF32NegAbs(SDValue In, SDValue &Src,
228 SDValue &SrcMods) const;
229 bool SelectWMMAModsF16Neg(SDValue In, SDValue &Src, SDValue &SrcMods) const;
230 bool SelectWMMAModsF16NegAbs(SDValue In, SDValue &Src,
231 SDValue &SrcMods) const;
232 bool SelectWMMAVISrc(SDValue In, SDValue &Src) const;
233
234 bool SelectSWMMACIndex8(SDValue In, SDValue &Src, SDValue &IndexKey) const;
235 bool SelectSWMMACIndex16(SDValue In, SDValue &Src, SDValue &IndexKey) const;
236
237 bool SelectVOP3OpSel(SDValue In, SDValue &Src, SDValue &SrcMods) const;
238
239 bool SelectVOP3OpSelMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
240 bool SelectVOP3PMadMixModsImpl(SDValue In, SDValue &Src,
241 unsigned &Mods) const;
242 bool SelectVOP3PMadMixModsExt(SDValue In, SDValue &Src,
243 SDValue &SrcMods) const;
244 bool SelectVOP3PMadMixMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
245
246 SDValue getHi16Elt(SDValue In) const;
247
248 SDValue getMaterializedScalarImm32(int64_t Val, const SDLoc &DL) const;
249
250 void SelectADD_SUB_I64(SDNode *N);
251 void SelectAddcSubb(SDNode *N);
252 void SelectUADDO_USUBO(SDNode *N);
253 void SelectDIV_SCALE(SDNode *N);
254 void SelectMAD_64_32(SDNode *N);
255 void SelectMUL_LOHI(SDNode *N);
256 void SelectFMA_W_CHAIN(SDNode *N);
257 void SelectFMUL_W_CHAIN(SDNode *N);
258 SDNode *getBFE32(bool IsSigned, const SDLoc &DL, SDValue Val, uint32_t Offset,
259 uint32_t Width);
260 void SelectS_BFEFromShifts(SDNode *N);
261 void SelectS_BFE(SDNode *N);
262 bool isCBranchSCC(const SDNode *N) const;
263 void SelectBRCOND(SDNode *N);
264 void SelectFMAD_FMA(SDNode *N);
265 void SelectFP_EXTEND(SDNode *N);
266 void SelectDSAppendConsume(SDNode *N, unsigned IntrID);
267 void SelectDSBvhStackIntrinsic(SDNode *N);
268 void SelectDS_GWS(SDNode *N, unsigned IntrID);
269 void SelectInterpP1F16(SDNode *N);
270 void SelectINTRINSIC_W_CHAIN(SDNode *N);
271 void SelectINTRINSIC_WO_CHAIN(SDNode *N);
272 void SelectINTRINSIC_VOID(SDNode *N);
273 void SelectWAVE_ADDRESS(SDNode *N);
274 void SelectSTACKRESTORE(SDNode *N);
275
276protected:
277 // Include the pieces autogenerated from the target description.
278#include "AMDGPUGenDAGISel.inc"
279};
280
282public:
284
287};
288
290public:
291 static char ID;
292
294
295 bool runOnMachineFunction(MachineFunction &MF) override;
296 void getAnalysisUsage(AnalysisUsage &AU) const override;
297 StringRef getPassName() const override;
298};
299
300} // namespace llvm
301
302#endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H
amdgpu AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
uint64_t Addr
uint64_t Size
AMD GCN specific subclass of TargetSubtarget.
const char LLVMTargetMachineRef TM
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:266
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:226
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:687
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
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:529
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