LLVM  16.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"
18 #include "SIMachineFunctionInfo.h"
21 
22 using namespace llvm;
23 
24 namespace {
25 
26 static inline bool isNullConstantOrUndef(SDValue V) {
27  if (V.isUndef())
28  return true;
29 
30  ConstantSDNode *Const = dyn_cast<ConstantSDNode>(V);
31  return Const != nullptr && Const->isZero();
32 }
33 
34 static inline bool getConstantValue(SDValue N, uint32_t &Out) {
35  // This is only used for packed vectors, where using 0 for undef should
36  // always be good.
37  if (N.isUndef()) {
38  Out = 0;
39  return true;
40  }
41 
42  if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
43  Out = C->getAPIntValue().getSExtValue();
44  return true;
45  }
46 
47  if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N)) {
48  Out = C->getValueAPF().bitcastToAPInt().getSExtValue();
49  return true;
50  }
51 
52  return false;
53 }
54 
55 // TODO: Handle undef as zero
56 static inline SDNode *packConstantV2I16(const SDNode *N, SelectionDAG &DAG,
57  bool Negate = false) {
58  assert(N->getOpcode() == ISD::BUILD_VECTOR && N->getNumOperands() == 2);
59  uint32_t LHSVal, RHSVal;
60  if (getConstantValue(N->getOperand(0), LHSVal) &&
61  getConstantValue(N->getOperand(1), RHSVal)) {
62  SDLoc SL(N);
63  uint32_t K = Negate ? (-LHSVal & 0xffff) | (-RHSVal << 16)
64  : (LHSVal & 0xffff) | (RHSVal << 16);
65  return DAG.getMachineNode(AMDGPU::S_MOV_B32, SL, N->getValueType(0),
66  DAG.getTargetConstant(K, SL, MVT::i32));
67  }
68 
69  return nullptr;
70 }
71 
72 static inline SDNode *packNegConstantV2I16(const SDNode *N, SelectionDAG &DAG) {
73  return packConstantV2I16(N, DAG, true);
74 }
75 } // namespace
76 
77 /// AMDGPU specific code to select AMDGPU machine instructions for
78 /// SelectionDAG operations.
80  // Subtarget - Keep a pointer to the AMDGPU Subtarget around so that we can
81  // make the right decision when generating code for different targets.
82  const GCNSubtarget *Subtarget;
83 
84  // Default FP mode for the current function.
85  AMDGPU::SIModeRegisterDefaults Mode;
86 
87  bool EnableLateStructurizeCFG;
88 
89  // Instructions that will be lowered with a final instruction that zeros the
90  // high result bits.
91  bool fp16SrcZerosHighBits(unsigned Opc) const;
92 
93 public:
94  explicit AMDGPUDAGToDAGISel(TargetMachine *TM = nullptr,
96  ~AMDGPUDAGToDAGISel() override = default;
97 
98  void getAnalysisUsage(AnalysisUsage &AU) const override;
99 
100  bool matchLoadD16FromBuildVector(SDNode *N) const;
101 
102  bool runOnMachineFunction(MachineFunction &MF) override;
103  void PreprocessISelDAG() override;
104  void Select(SDNode *N) override;
105  StringRef getPassName() const override;
106  void PostprocessISelDAG() override;
107 
108 protected:
109  void SelectBuildVector(SDNode *N, unsigned RegClassID);
110 
111 private:
112  std::pair<SDValue, SDValue> foldFrameIndex(SDValue N) const;
113  bool isInlineImmediate(const SDNode *N, bool Negated = false) const;
114  bool isNegInlineImmediate(const SDNode *N) const {
115  return isInlineImmediate(N, true);
116  }
117 
118  bool isInlineImmediate16(int64_t Imm) const {
120  }
121 
122  bool isInlineImmediate32(int64_t Imm) const {
124  }
125 
126  bool isInlineImmediate64(int64_t Imm) const {
128  }
129 
130  bool isInlineImmediate(const APFloat &Imm) const {
131  return Subtarget->getInstrInfo()->isInlineConstant(Imm);
132  }
133 
134  bool isVGPRImm(const SDNode *N) const;
135  bool isUniformLoad(const SDNode *N) const;
136  bool isUniformBr(const SDNode *N) const;
137 
138  // Returns true if ISD::AND SDNode `N`'s masking of the shift amount operand's
139  // `ShAmtBits` bits is unneeded.
140  bool isUnneededShiftMask(const SDNode *N, unsigned ShAmtBits) const;
141 
142  bool isBaseWithConstantOffset64(SDValue Addr, SDValue &LHS,
143  SDValue &RHS) const;
144 
145  MachineSDNode *buildSMovImm64(SDLoc &DL, uint64_t Val, EVT VT) const;
146 
147  SDNode *glueCopyToOp(SDNode *N, SDValue NewChain, SDValue Glue) const;
148  SDNode *glueCopyToM0(SDNode *N, SDValue Val) const;
149  SDNode *glueCopyToM0LDSInit(SDNode *N) const;
150 
151  const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const;
152  virtual bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset);
153  virtual bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset);
154  bool isDSOffsetLegal(SDValue Base, unsigned Offset) const;
155  bool isDSOffset2Legal(SDValue Base, unsigned Offset0, unsigned Offset1,
156  unsigned Size) const;
157  bool SelectDS1Addr1Offset(SDValue Ptr, SDValue &Base, SDValue &Offset) const;
158  bool SelectDS64Bit4ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0,
159  SDValue &Offset1) const;
160  bool SelectDS128Bit8ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0,
161  SDValue &Offset1) const;
162  bool SelectDSReadWrite2(SDValue Ptr, SDValue &Base, SDValue &Offset0,
163  SDValue &Offset1, unsigned Size) const;
164  bool SelectMUBUF(SDValue Addr, SDValue &SRsrc, SDValue &VAddr,
165  SDValue &SOffset, SDValue &Offset, SDValue &Offen,
166  SDValue &Idxen, SDValue &Addr64) const;
167  bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, SDValue &VAddr,
168  SDValue &SOffset, SDValue &Offset) const;
169  bool SelectMUBUFScratchOffen(SDNode *Parent, SDValue Addr, SDValue &RSrc,
170  SDValue &VAddr, SDValue &SOffset,
171  SDValue &ImmOffset) const;
172  bool SelectMUBUFScratchOffset(SDNode *Parent, SDValue Addr, SDValue &SRsrc,
173  SDValue &Soffset, SDValue &Offset) const;
174 
175  bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset,
176  SDValue &Offset) const;
177 
178  bool SelectFlatOffsetImpl(SDNode *N, SDValue Addr, SDValue &VAddr,
179  SDValue &Offset, uint64_t FlatVariant) const;
180  bool SelectFlatOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
181  SDValue &Offset) const;
182  bool SelectGlobalOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
183  SDValue &Offset) const;
184  bool SelectScratchOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
185  SDValue &Offset) const;
186  bool SelectGlobalSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
187  SDValue &VOffset, SDValue &Offset) const;
188  bool SelectScratchSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
189  SDValue &Offset) const;
190  bool checkFlatScratchSVSSwizzleBug(SDValue VAddr, SDValue SAddr,
191  uint64_t ImmOffset) const;
192  bool SelectScratchSVAddr(SDNode *N, SDValue Addr, SDValue &VAddr,
193  SDValue &SAddr, SDValue &Offset) const;
194 
195  bool SelectSMRDOffset(SDValue ByteOffsetNode, SDValue *SOffset,
196  SDValue *Offset, bool Imm32Only = false,
197  bool IsBuffer = false) const;
198  SDValue Expand32BitAddress(SDValue Addr) const;
199  bool SelectSMRDBaseOffset(SDValue Addr, SDValue &SBase, SDValue *SOffset,
200  SDValue *Offset, bool Imm32Only = false,
201  bool IsBuffer = false) const;
202  bool SelectSMRD(SDValue Addr, SDValue &SBase, SDValue *SOffset,
203  SDValue *Offset, bool Imm32Only = false) const;
204  bool SelectSMRDImm(SDValue Addr, SDValue &SBase, SDValue &Offset) const;
205  bool SelectSMRDImm32(SDValue Addr, SDValue &SBase, SDValue &Offset) const;
206  bool SelectSMRDSgpr(SDValue Addr, SDValue &SBase, SDValue &SOffset) const;
207  bool SelectSMRDSgprImm(SDValue Addr, SDValue &SBase, SDValue &SOffset,
208  SDValue &Offset) const;
209  bool SelectSMRDBufferImm(SDValue N, SDValue &Offset) const;
210  bool SelectSMRDBufferImm32(SDValue N, SDValue &Offset) const;
211  bool SelectSMRDBufferSgprImm(SDValue N, SDValue &SOffset,
212  SDValue &Offset) const;
213  bool SelectMOVRELOffset(SDValue Index, SDValue &Base, SDValue &Offset) const;
214 
215  bool SelectVOP3Mods_NNaN(SDValue In, SDValue &Src, SDValue &SrcMods) const;
216  bool SelectVOP3ModsImpl(SDValue In, SDValue &Src, unsigned &SrcMods,
217  bool AllowAbs = true) const;
218  bool SelectVOP3Mods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
219  bool SelectVOP3BMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
220  bool SelectVOP3NoMods(SDValue In, SDValue &Src) const;
221  bool SelectVOP3Mods0(SDValue In, SDValue &Src, SDValue &SrcMods,
222  SDValue &Clamp, SDValue &Omod) const;
223  bool SelectVOP3BMods0(SDValue In, SDValue &Src, SDValue &SrcMods,
224  SDValue &Clamp, SDValue &Omod) const;
225  bool SelectVOP3NoMods0(SDValue In, SDValue &Src, SDValue &SrcMods,
226  SDValue &Clamp, SDValue &Omod) const;
227 
228  bool SelectVINTERPModsImpl(SDValue In, SDValue &Src, SDValue &SrcMods,
229  bool OpSel) const;
230  bool SelectVINTERPMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
231  bool SelectVINTERPModsHi(SDValue In, SDValue &Src, SDValue &SrcMods) const;
232 
233  bool SelectVOP3OMods(SDValue In, SDValue &Src, SDValue &Clamp,
234  SDValue &Omod) const;
235 
236  bool SelectVOP3PMods(SDValue In, SDValue &Src, SDValue &SrcMods,
237  bool IsDOT = false) const;
238  bool SelectVOP3PModsDOT(SDValue In, SDValue &Src, SDValue &SrcMods) const;
239 
240  bool SelectDotIUVOP3PMods(SDValue In, SDValue &Src) const;
241  bool SelectWMMAOpSelVOP3PMods(SDValue In, SDValue &Src) const;
242 
243  bool SelectVOP3OpSel(SDValue In, SDValue &Src, SDValue &SrcMods) const;
244 
245  bool SelectVOP3OpSelMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
246  bool SelectVOP3PMadMixModsImpl(SDValue In, SDValue &Src,
247  unsigned &Mods) const;
248  bool SelectVOP3PMadMixMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
249 
250  SDValue getHi16Elt(SDValue In) const;
251 
252  SDValue getMaterializedScalarImm32(int64_t Val, const SDLoc &DL) const;
253 
254  void SelectADD_SUB_I64(SDNode *N);
255  void SelectAddcSubb(SDNode *N);
256  void SelectUADDO_USUBO(SDNode *N);
257  void SelectDIV_SCALE(SDNode *N);
258  void SelectMAD_64_32(SDNode *N);
259  void SelectMUL_LOHI(SDNode *N);
260  void SelectFMA_W_CHAIN(SDNode *N);
261  void SelectFMUL_W_CHAIN(SDNode *N);
262  SDNode *getBFE32(bool IsSigned, const SDLoc &DL, SDValue Val, uint32_t Offset,
263  uint32_t Width);
264  void SelectS_BFEFromShifts(SDNode *N);
265  void SelectS_BFE(SDNode *N);
266  bool isCBranchSCC(const SDNode *N) const;
267  void SelectBRCOND(SDNode *N);
268  void SelectFMAD_FMA(SDNode *N);
269  void SelectDSAppendConsume(SDNode *N, unsigned IntrID);
270  void SelectDSBvhStackIntrinsic(SDNode *N);
271  void SelectDS_GWS(SDNode *N, unsigned IntrID);
272  void SelectInterpP1F16(SDNode *N);
273  void SelectINTRINSIC_W_CHAIN(SDNode *N);
274  void SelectINTRINSIC_WO_CHAIN(SDNode *N);
275  void SelectINTRINSIC_VOID(SDNode *N);
276 
277 protected:
278  // Include the pieces autogenerated from the target description.
279 #include "AMDGPUGenDAGISel.inc"
280 };
281 
282 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1582
llvm::AMDGPUSubtarget::hasInv2PiInlineImm
bool hasInv2PiInlineImm() const
Definition: AMDGPUSubtarget.h:184
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1106
SIMachineFunctionInfo.h
llvm::MachineSDNode
An SDNode that represents everything that will be needed to construct a MachineInstr.
Definition: SelectionDAGNodes.h:2897
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:463
llvm::AMDGPU::VOP3PEncoding::OpSel
OpSel
Definition: SIDefines.h:885
AMDGPUDAGToDAGISel
AMDGPU specific code to select AMDGPU machine instructions for SelectionDAG operations.
Definition: AMDGPUISelDAGToDAG.h:79
llvm::GCNSubtarget
Definition: GCNSubtarget.h:31
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::GCNSubtarget::getInstrInfo
const SIInstrInfo * getInstrInfo() const override
Definition: GCNSubtarget.h:216
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
TargetMachine.h
llvm::SelectionDAG
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:220
llvm::SIInstrInfo::isInlineConstant
bool isInlineConstant(const APInt &Imm) const
Definition: SIInstrInfo.cpp:3702
GCNSubtarget.h
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:34
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::SIInstrFlags::IsDOT
@ IsDOT
Definition: SIDefines.h:120
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:45
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::dwarf::Index
Index
Definition: Dwarf.h:490
llvm::sys::unicode::SBase
constexpr const char32_t SBase
Definition: UnicodeNameToCodepoint.cpp:256
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::APFloat
Definition: APFloat.h:716
llvm::CodeGenOpt::Default
@ Default
Definition: CodeGen.h:55
uint64_t
llvm::ConstantFPSDNode
Definition: SelectionDAGNodes.h:1631
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
Mode
SI Whole Quad Mode
Definition: SIWholeQuadMode.cpp:264
llvm::SelectionDAG::getMachineNode
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),...
Definition: SelectionDAG.cpp:9877
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::AMDGPU::isInlinableLiteral16
bool isInlinableLiteral16(int16_t Literal, bool HasInv2Pi)
Definition: AMDGPUBaseInfo.cpp:2349
SelectionDAGISel.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
uint32_t
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::CodeGenOpt::Level
Level
Definition: CodeGen.h:52
llvm::MCID::Select
@ Select
Definition: MCInstrDesc.h:164
llvm::AMDGPU::isInlinableLiteral64
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
Definition: AMDGPUBaseInfo.cpp:2306
llvm::ISD::BUILD_VECTOR
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:514
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:48
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:145
llvm::AMDGPU::Hwreg::Width
Width
Definition: SIDefines.h:436
llvm::SDValue::isUndef
bool isUndef() const
Definition: SelectionDAGNodes.h:1177
llvm::codeview::ModifierOptions::Const
@ Const
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
llvm::AMDGPU::isInlinableLiteral32
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
Definition: AMDGPUBaseInfo.cpp:2323
llvm::SelectionDAGISel
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
Definition: SelectionDAGISel.h:41
N
#define N
llvm::SelectionDAG::getTargetConstant
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:669
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58