[SampleProfileLoader] Fix integer overflow in generateMDProfMetadata (#90217)
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVISelDAGToDAG.h
blob7d4aec2dfdc9841efd74857d179c8d51d5c116f2
1 //===---- RISCVISelDAGToDAG.h - A dag to dag inst selector for RISC-V -----===//
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 // This file defines an instruction selector for the RISC-V target.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H
14 #define LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H
16 #include "RISCV.h"
17 #include "RISCVTargetMachine.h"
18 #include "llvm/CodeGen/SelectionDAGISel.h"
19 #include "llvm/Support/KnownBits.h"
21 // RISC-V specific code to select RISC-V machine instructions for
22 // SelectionDAG operations.
23 namespace llvm {
24 class RISCVDAGToDAGISel : public SelectionDAGISel {
25 const RISCVSubtarget *Subtarget = nullptr;
27 public:
28 static char ID;
30 RISCVDAGToDAGISel() = delete;
32 explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine,
33 CodeGenOptLevel OptLevel)
34 : SelectionDAGISel(ID, TargetMachine, OptLevel) {}
36 bool runOnMachineFunction(MachineFunction &MF) override {
37 Subtarget = &MF.getSubtarget<RISCVSubtarget>();
38 return SelectionDAGISel::runOnMachineFunction(MF);
41 void PreprocessISelDAG() override;
42 void PostprocessISelDAG() override;
44 void Select(SDNode *Node) override;
46 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
47 InlineAsm::ConstraintCode ConstraintID,
48 std::vector<SDValue> &OutOps) override;
50 bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset);
51 bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);
52 bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset,
53 bool IsINX = false);
54 bool SelectAddrRegImmINX(SDValue Addr, SDValue &Base, SDValue &Offset) {
55 return SelectAddrRegImm(Addr, Base, Offset, true);
57 bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);
59 bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,
60 SDValue &Base, SDValue &Index, SDValue &Scale);
62 template <unsigned MaxShift>
63 bool SelectAddrRegRegScale(SDValue Addr, SDValue &Base, SDValue &Index,
64 SDValue &Scale) {
65 return SelectAddrRegRegScale(Addr, MaxShift, Base, Index, Scale);
68 template <unsigned MaxShift, unsigned Bits>
69 bool SelectAddrRegZextRegScale(SDValue Addr, SDValue &Base, SDValue &Index,
70 SDValue &Scale) {
71 if (SelectAddrRegRegScale(Addr, MaxShift, Base, Index, Scale)) {
72 if (Index.getOpcode() == ISD::AND) {
73 auto *C = dyn_cast<ConstantSDNode>(Index.getOperand(1));
74 if (C && C->getZExtValue() == maskTrailingOnes<uint64_t>(Bits)) {
75 Index = Index.getOperand(0);
76 return true;
80 return false;
83 bool tryShrinkShlLogicImm(SDNode *Node);
84 bool trySignedBitfieldExtract(SDNode *Node);
85 bool tryIndexedLoad(SDNode *Node);
87 bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);
88 bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) {
89 return selectShiftMask(N, Subtarget->getXLen(), ShAmt);
91 bool selectShiftMask32(SDValue N, SDValue &ShAmt) {
92 return selectShiftMask(N, 32, ShAmt);
95 bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val);
96 bool selectSETNE(SDValue N, SDValue &Val) {
97 return selectSETCC(N, ISD::SETNE, Val);
99 bool selectSETEQ(SDValue N, SDValue &Val) {
100 return selectSETCC(N, ISD::SETEQ, Val);
103 bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val);
104 template <unsigned Bits> bool selectSExtBits(SDValue N, SDValue &Val) {
105 return selectSExtBits(N, Bits, Val);
107 bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val);
108 template <unsigned Bits> bool selectZExtBits(SDValue N, SDValue &Val) {
109 return selectZExtBits(N, Bits, Val);
112 bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val);
113 template <unsigned ShAmt> bool selectSHXADDOp(SDValue N, SDValue &Val) {
114 return selectSHXADDOp(N, ShAmt, Val);
117 bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val);
118 template <unsigned ShAmt> bool selectSHXADD_UWOp(SDValue N, SDValue &Val) {
119 return selectSHXADD_UWOp(N, ShAmt, Val);
122 bool hasAllNBitUsers(SDNode *Node, unsigned Bits,
123 const unsigned Depth = 0) const;
124 bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); }
125 bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); }
127 bool selectSimm5Shl2(SDValue N, SDValue &Simm5, SDValue &Shl2);
129 bool selectVLOp(SDValue N, SDValue &VL);
131 bool selectVSplat(SDValue N, SDValue &SplatVal);
132 bool selectVSplatSimm5(SDValue N, SDValue &SplatVal);
133 bool selectVSplatUimm(SDValue N, unsigned Bits, SDValue &SplatVal);
134 template <unsigned Bits> bool selectVSplatUimmBits(SDValue N, SDValue &Val) {
135 return selectVSplatUimm(N, Bits, Val);
137 bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal);
138 bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal);
139 // Matches the splat of a value which can be extended or truncated, such that
140 // only the bottom 8 bits are preserved.
141 bool selectLow8BitsVSplat(SDValue N, SDValue &SplatVal);
142 bool selectFPImm(SDValue N, SDValue &Imm);
144 bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm);
145 template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) {
146 return selectRVVSimm5(N, Width, Imm);
149 void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm,
150 const SDLoc &DL, unsigned CurOp,
151 bool IsMasked, bool IsStridedOrIndexed,
152 SmallVectorImpl<SDValue> &Operands,
153 bool IsLoad = false, MVT *IndexVT = nullptr);
155 void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided);
156 void selectVLSEGFF(SDNode *Node, bool IsMasked);
157 void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered);
158 void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided);
159 void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered);
161 void selectVSETVLI(SDNode *Node);
163 void selectSF_VC_X_SE(SDNode *Node);
165 // Return the RISC-V condition code that matches the given DAG integer
166 // condition code. The CondCode must be one of those supported by the RISC-V
167 // ISA (see translateSetCCForBranch).
168 static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) {
169 switch (CC) {
170 default:
171 llvm_unreachable("Unsupported CondCode");
172 case ISD::SETEQ:
173 return RISCVCC::COND_EQ;
174 case ISD::SETNE:
175 return RISCVCC::COND_NE;
176 case ISD::SETLT:
177 return RISCVCC::COND_LT;
178 case ISD::SETGE:
179 return RISCVCC::COND_GE;
180 case ISD::SETULT:
181 return RISCVCC::COND_LTU;
182 case ISD::SETUGE:
183 return RISCVCC::COND_GEU;
187 // Include the pieces autogenerated from the target description.
188 #include "RISCVGenDAGISel.inc"
190 private:
191 bool doPeepholeSExtW(SDNode *Node);
192 bool doPeepholeMaskedRVV(MachineSDNode *Node);
193 bool doPeepholeMergeVVMFold();
194 bool doPeepholeNoRegPassThru();
195 bool performCombineVMergeAndVOps(SDNode *N);
198 namespace RISCV {
199 struct VLSEGPseudo {
200 uint16_t NF : 4;
201 uint16_t Masked : 1;
202 uint16_t Strided : 1;
203 uint16_t FF : 1;
204 uint16_t Log2SEW : 3;
205 uint16_t LMUL : 3;
206 uint16_t Pseudo;
209 struct VLXSEGPseudo {
210 uint16_t NF : 4;
211 uint16_t Masked : 1;
212 uint16_t Ordered : 1;
213 uint16_t Log2SEW : 3;
214 uint16_t LMUL : 3;
215 uint16_t IndexLMUL : 3;
216 uint16_t Pseudo;
219 struct VSSEGPseudo {
220 uint16_t NF : 4;
221 uint16_t Masked : 1;
222 uint16_t Strided : 1;
223 uint16_t Log2SEW : 3;
224 uint16_t LMUL : 3;
225 uint16_t Pseudo;
228 struct VSXSEGPseudo {
229 uint16_t NF : 4;
230 uint16_t Masked : 1;
231 uint16_t Ordered : 1;
232 uint16_t Log2SEW : 3;
233 uint16_t LMUL : 3;
234 uint16_t IndexLMUL : 3;
235 uint16_t Pseudo;
238 struct VLEPseudo {
239 uint16_t Masked : 1;
240 uint16_t Strided : 1;
241 uint16_t FF : 1;
242 uint16_t Log2SEW : 3;
243 uint16_t LMUL : 3;
244 uint16_t Pseudo;
247 struct VSEPseudo {
248 uint16_t Masked :1;
249 uint16_t Strided : 1;
250 uint16_t Log2SEW : 3;
251 uint16_t LMUL : 3;
252 uint16_t Pseudo;
255 struct VLX_VSXPseudo {
256 uint16_t Masked : 1;
257 uint16_t Ordered : 1;
258 uint16_t Log2SEW : 3;
259 uint16_t LMUL : 3;
260 uint16_t IndexLMUL : 3;
261 uint16_t Pseudo;
264 #define GET_RISCVVSSEGTable_DECL
265 #define GET_RISCVVLSEGTable_DECL
266 #define GET_RISCVVLXSEGTable_DECL
267 #define GET_RISCVVSXSEGTable_DECL
268 #define GET_RISCVVLETable_DECL
269 #define GET_RISCVVSETable_DECL
270 #define GET_RISCVVLXTable_DECL
271 #define GET_RISCVVSXTable_DECL
272 } // namespace RISCV
274 } // namespace llvm
276 #endif