LLVM  14.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.
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 isNoNanSrc(SDValue N) const;
114  bool isInlineImmediate(const SDNode *N, bool Negated = false) const;
115  bool isNegInlineImmediate(const SDNode *N) const {
116  return isInlineImmediate(N, true);
117  }
118 
119  bool isInlineImmediate16(int64_t Imm) const {
120  return AMDGPU::isInlinableLiteral16(Imm, Subtarget->hasInv2PiInlineImm());
121  }
122 
123  bool isInlineImmediate32(int64_t Imm) const {
124  return AMDGPU::isInlinableLiteral32(Imm, Subtarget->hasInv2PiInlineImm());
125  }
126 
127  bool isInlineImmediate64(int64_t Imm) const {
128  return AMDGPU::isInlinableLiteral64(Imm, Subtarget->hasInv2PiInlineImm());
129  }
130 
131  bool isInlineImmediate(const APFloat &Imm) const {
132  return Subtarget->getInstrInfo()->isInlineConstant(Imm);
133  }
134 
135  bool isVGPRImm(const SDNode *N) const;
136  bool isUniformLoad(const SDNode *N) const;
137  bool isUniformBr(const SDNode *N) const;
138 
139  // Returns true if ISD::AND SDNode `N`'s masking of the shift amount operand's
140  // `ShAmtBits` bits is unneeded.
141  bool isUnneededShiftMask(const SDNode *N, unsigned ShAmtBits) const;
142 
143  bool isBaseWithConstantOffset64(SDValue Addr, SDValue &LHS,
144  SDValue &RHS) const;
145 
146  MachineSDNode *buildSMovImm64(SDLoc &DL, uint64_t Val, EVT VT) const;
147 
148  SDNode *glueCopyToOp(SDNode *N, SDValue NewChain, SDValue Glue) const;
149  SDNode *glueCopyToM0(SDNode *N, SDValue Val) const;
150  SDNode *glueCopyToM0LDSInit(SDNode *N) const;
151 
152  const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const;
153  virtual bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset);
154  virtual bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset);
155  bool isDSOffsetLegal(SDValue Base, unsigned Offset) const;
156  bool isDSOffset2Legal(SDValue Base, unsigned Offset0, unsigned Offset1,
157  unsigned Size) const;
158  bool SelectDS1Addr1Offset(SDValue Ptr, SDValue &Base, SDValue &Offset) const;
159  bool SelectDS64Bit4ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0,
160  SDValue &Offset1) const;
161  bool SelectDS128Bit8ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0,
162  SDValue &Offset1) const;
163  bool SelectDSReadWrite2(SDValue Ptr, SDValue &Base, SDValue &Offset0,
164  SDValue &Offset1, unsigned Size) const;
165  bool SelectMUBUF(SDValue Addr, SDValue &SRsrc, SDValue &VAddr,
166  SDValue &SOffset, SDValue &Offset, SDValue &Offen,
167  SDValue &Idxen, SDValue &Addr64) const;
168  bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, SDValue &VAddr,
169  SDValue &SOffset, SDValue &Offset) const;
170  bool SelectMUBUFScratchOffen(SDNode *Parent, SDValue Addr, SDValue &RSrc,
171  SDValue &VAddr, SDValue &SOffset,
172  SDValue &ImmOffset) const;
173  bool SelectMUBUFScratchOffset(SDNode *Parent, SDValue Addr, SDValue &SRsrc,
174  SDValue &Soffset, SDValue &Offset) const;
175 
176  bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset,
177  SDValue &Offset) const;
178 
179  bool SelectFlatOffsetImpl(SDNode *N, SDValue Addr, SDValue &VAddr,
180  SDValue &Offset, uint64_t FlatVariant) const;
181  bool SelectFlatOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
182  SDValue &Offset) const;
183  bool SelectGlobalOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
184  SDValue &Offset) const;
185  bool SelectScratchOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
186  SDValue &Offset) const;
187  bool SelectGlobalSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
188  SDValue &VOffset, SDValue &Offset) const;
189  bool SelectScratchSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
190  SDValue &Offset) const;
191 
192  bool SelectSMRDOffset(SDValue ByteOffsetNode, SDValue &Offset,
193  bool &Imm) const;
194  SDValue Expand32BitAddress(SDValue Addr) const;
195  bool SelectSMRD(SDValue Addr, SDValue &SBase, SDValue &Offset,
196  bool &Imm) const;
197  bool SelectSMRDImm(SDValue Addr, SDValue &SBase, SDValue &Offset) const;
198  bool SelectSMRDImm32(SDValue Addr, SDValue &SBase, SDValue &Offset) const;
199  bool SelectSMRDSgpr(SDValue Addr, SDValue &SBase, SDValue &Offset) const;
200  bool SelectSMRDBufferImm(SDValue Addr, SDValue &Offset) const;
201  bool SelectSMRDBufferImm32(SDValue Addr, SDValue &Offset) const;
202  bool SelectMOVRELOffset(SDValue Index, SDValue &Base, SDValue &Offset) const;
203 
204  bool SelectVOP3Mods_NNaN(SDValue In, SDValue &Src, SDValue &SrcMods) const;
205  bool SelectVOP3ModsImpl(SDValue In, SDValue &Src, unsigned &SrcMods,
206  bool AllowAbs = true) const;
207  bool SelectVOP3Mods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
208  bool SelectVOP3BMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
209  bool SelectVOP3NoMods(SDValue In, SDValue &Src) const;
210  bool SelectVOP3Mods0(SDValue In, SDValue &Src, SDValue &SrcMods,
211  SDValue &Clamp, SDValue &Omod) const;
212  bool SelectVOP3BMods0(SDValue In, SDValue &Src, SDValue &SrcMods,
213  SDValue &Clamp, SDValue &Omod) const;
214  bool SelectVOP3NoMods0(SDValue In, SDValue &Src, SDValue &SrcMods,
215  SDValue &Clamp, SDValue &Omod) 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) const;
221 
222  bool SelectVOP3OpSel(SDValue In, SDValue &Src, SDValue &SrcMods) const;
223 
224  bool SelectVOP3OpSelMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
225  bool SelectVOP3PMadMixModsImpl(SDValue In, SDValue &Src,
226  unsigned &Mods) const;
227  bool SelectVOP3PMadMixMods(SDValue In, SDValue &Src, SDValue &SrcMods) const;
228 
229  SDValue getHi16Elt(SDValue In) const;
230 
231  SDValue getMaterializedScalarImm32(int64_t Val, const SDLoc &DL) const;
232 
233  void SelectADD_SUB_I64(SDNode *N);
234  void SelectAddcSubb(SDNode *N);
235  void SelectUADDO_USUBO(SDNode *N);
236  void SelectDIV_SCALE(SDNode *N);
237  void SelectMAD_64_32(SDNode *N);
238  void SelectMUL_LOHI(SDNode *N);
239  void SelectFMA_W_CHAIN(SDNode *N);
240  void SelectFMUL_W_CHAIN(SDNode *N);
241  SDNode *getBFE32(bool IsSigned, const SDLoc &DL, SDValue Val, uint32_t Offset,
242  uint32_t Width);
243  void SelectS_BFEFromShifts(SDNode *N);
244  void SelectS_BFE(SDNode *N);
245  bool isCBranchSCC(const SDNode *N) const;
246  void SelectBRCOND(SDNode *N);
247  void SelectFMAD_FMA(SDNode *N);
248  void SelectATOMIC_CMP_SWAP(SDNode *N);
249  void SelectDSAppendConsume(SDNode *N, unsigned IntrID);
250  void SelectDS_GWS(SDNode *N, unsigned IntrID);
251  void SelectInterpP1F16(SDNode *N);
252  void SelectINTRINSIC_W_CHAIN(SDNode *N);
253  void SelectINTRINSIC_WO_CHAIN(SDNode *N);
254  void SelectINTRINSIC_VOID(SDNode *N);
255 
256 protected:
257  // Include the pieces autogenerated from the target description.
258 #include "AMDGPUGenDAGISel.inc"
259 };
260 
261 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUISELDAGTODAG_H
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1555
llvm::AMDGPUSubtarget::hasInv2PiInlineImm
bool hasInv2PiInlineImm() const
Definition: AMDGPUSubtarget.h:180
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1085
SIMachineFunctionInfo.h
llvm::MachineSDNode
An SDNode that represents everything that will be needed to construct a MachineInstr.
Definition: SelectionDAGNodes.h:2762
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:454
AMDGPUDAGToDAGISel
AMDGPU specific code to select AMDGPU machine instructions for SelectionDAG operations.
Definition: AMDGPUISelDAGToDAG.h:79
llvm::AMDGPU::SIModeRegisterDefaults
Definition: AMDGPUBaseInfo.h:915
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::GCNSubtarget
Definition: GCNSubtarget.h:31
llvm::GCNSubtarget::getInstrInfo
const SIInstrInfo * getInstrInfo() const override
Definition: GCNSubtarget.h:207
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:216
llvm::SIInstrInfo::isInlineConstant
bool isInlineConstant(const APInt &Imm) const
Definition: SIInstrInfo.cpp:3421
GCNSubtarget.h
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:35
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::APFloat
Definition: APFloat.h:701
llvm::CodeGenOpt::Default
@ Default
Definition: CodeGen.h:55
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
uint64_t
llvm::ConstantFPSDNode
Definition: SelectionDAGNodes.h:1604
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:80
Mode
SI Whole Quad Mode
Definition: SIWholeQuadMode.cpp:262
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:8972
llvm::MachineFunction
Definition: MachineFunction.h:234
llvm::AMDGPU::isInlinableLiteral16
bool isInlinableLiteral16(int16_t Literal, bool HasInv2Pi)
Definition: AMDGPUBaseInfo.cpp:1769
SelectionDAGISel.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
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:162
llvm::AMDGPU::isInlinableLiteral64
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
Definition: AMDGPUBaseInfo.cpp:1726
llvm::ISD::BUILD_VECTOR
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:491
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:46
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:137
llvm::AMDGPU::Hwreg::Width
Width
Definition: SIDefines.h:414
llvm::SDValue::isUndef
bool isUndef() const
Definition: SelectionDAGNodes.h:1156
llvm::codeview::ModifierOptions::Const
@ Const
llvm::AMDGPU::isInlinableLiteral32
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
Definition: AMDGPUBaseInfo.cpp:1743
llvm::SelectionDAGISel
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
Definition: SelectionDAGISel.h:39
N
#define N
llvm::SelectionDAG::getTargetConstant
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:637
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58