1 //===---- RISCVISelDAGToDAG.h - A dag to dag inst selector for RISC-V -----===//
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
7 //===----------------------------------------------------------------------===//
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
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.
24 class RISCVDAGToDAGISel
: public SelectionDAGISel
{
25 const RISCVSubtarget
*Subtarget
= nullptr;
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
,
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
,
65 return SelectAddrRegRegScale(Addr
, MaxShift
, Base
, Index
, Scale
);
68 template <unsigned MaxShift
, unsigned Bits
>
69 bool SelectAddrRegZextRegScale(SDValue Addr
, SDValue
&Base
, SDValue
&Index
,
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);
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
) {
171 llvm_unreachable("Unsupported CondCode");
173 return RISCVCC::COND_EQ
;
175 return RISCVCC::COND_NE
;
177 return RISCVCC::COND_LT
;
179 return RISCVCC::COND_GE
;
181 return RISCVCC::COND_LTU
;
183 return RISCVCC::COND_GEU
;
187 // Include the pieces autogenerated from the target description.
188 #include "RISCVGenDAGISel.inc"
191 bool doPeepholeSExtW(SDNode
*Node
);
192 bool doPeepholeMaskedRVV(MachineSDNode
*Node
);
193 bool doPeepholeMergeVVMFold();
194 bool doPeepholeNoRegPassThru();
195 bool performCombineVMergeAndVOps(SDNode
*N
);
202 uint16_t Strided
: 1;
204 uint16_t Log2SEW
: 3;
209 struct VLXSEGPseudo
{
212 uint16_t Ordered
: 1;
213 uint16_t Log2SEW
: 3;
215 uint16_t IndexLMUL
: 3;
222 uint16_t Strided
: 1;
223 uint16_t Log2SEW
: 3;
228 struct VSXSEGPseudo
{
231 uint16_t Ordered
: 1;
232 uint16_t Log2SEW
: 3;
234 uint16_t IndexLMUL
: 3;
240 uint16_t Strided
: 1;
242 uint16_t Log2SEW
: 3;
249 uint16_t Strided
: 1;
250 uint16_t Log2SEW
: 3;
255 struct VLX_VSXPseudo
{
257 uint16_t Ordered
: 1;
258 uint16_t Log2SEW
: 3;
260 uint16_t IndexLMUL
: 3;
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