1 //===-- RISCVISelLowering.h - RISCV DAG Lowering Interface ------*- C++ -*-===//
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 the interfaces that RISCV uses to lower LLVM code into a
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_RISCV_RISCVISELLOWERING_H
15 #define LLVM_LIB_TARGET_RISCV_RISCVISELLOWERING_H
18 #include "llvm/CodeGen/SelectionDAG.h"
19 #include "llvm/CodeGen/TargetLowering.h"
24 enum NodeType
: unsigned {
25 FIRST_NUMBER
= ISD::BUILTIN_OP_END
,
35 // RV64I shifts, directly matching the semantics of the named RISC-V
40 // 32-bit operations from RV64M that can't be simply matched with a pattern
41 // at instruction selection time.
45 // FPR32<->GPR transfer operations for RV64. Needed as an i32<->f32 bitcast
46 // is not legal on RV64. FMV_W_X_RV64 matches the semantics of the FMV.W.X.
47 // FMV_X_ANYEXTW_RV64 is similar to FMV.X.W but has an any-extended result.
48 // This is a more convenient semantic for producing dagcombines that remove
49 // unnecessary GPR->FPR->GPR moves.
52 // READ_CYCLE_WIDE - A read of the 64-bit cycle CSR on a 32-bit target
53 // (returns (Lo, Hi)). It takes a chain operand.
58 class RISCVTargetLowering
: public TargetLowering
{
59 const RISCVSubtarget
&Subtarget
;
62 explicit RISCVTargetLowering(const TargetMachine
&TM
,
63 const RISCVSubtarget
&STI
);
65 bool getTgtMemIntrinsic(IntrinsicInfo
&Info
, const CallInst
&I
,
67 unsigned Intrinsic
) const override
;
68 bool isLegalAddressingMode(const DataLayout
&DL
, const AddrMode
&AM
, Type
*Ty
,
70 Instruction
*I
= nullptr) const override
;
71 bool isLegalICmpImmediate(int64_t Imm
) const override
;
72 bool isLegalAddImmediate(int64_t Imm
) const override
;
73 bool isTruncateFree(Type
*SrcTy
, Type
*DstTy
) const override
;
74 bool isTruncateFree(EVT SrcVT
, EVT DstVT
) const override
;
75 bool isZExtFree(SDValue Val
, EVT VT2
) const override
;
76 bool isSExtCheaperThanZExt(EVT SrcVT
, EVT DstVT
) const override
;
78 bool hasBitPreservingFPLogic(EVT VT
) const override
;
80 // Provide custom lowering hooks for some operations.
81 SDValue
LowerOperation(SDValue Op
, SelectionDAG
&DAG
) const override
;
82 void ReplaceNodeResults(SDNode
*N
, SmallVectorImpl
<SDValue
> &Results
,
83 SelectionDAG
&DAG
) const override
;
85 SDValue
PerformDAGCombine(SDNode
*N
, DAGCombinerInfo
&DCI
) const override
;
87 unsigned ComputeNumSignBitsForTargetNode(SDValue Op
,
88 const APInt
&DemandedElts
,
89 const SelectionDAG
&DAG
,
90 unsigned Depth
) const override
;
92 // This method returns the name of a target specific DAG node.
93 const char *getTargetNodeName(unsigned Opcode
) const override
;
95 std::pair
<unsigned, const TargetRegisterClass
*>
96 getRegForInlineAsmConstraint(const TargetRegisterInfo
*TRI
,
97 StringRef Constraint
, MVT VT
) const override
;
99 void LowerAsmOperandForConstraint(SDValue Op
, std::string
&Constraint
,
100 std::vector
<SDValue
> &Ops
,
101 SelectionDAG
&DAG
) const override
;
104 EmitInstrWithCustomInserter(MachineInstr
&MI
,
105 MachineBasicBlock
*BB
) const override
;
107 EVT
getSetCCResultType(const DataLayout
&DL
, LLVMContext
&Context
,
108 EVT VT
) const override
;
110 bool convertSetCCLogicToBitwiseLogic(EVT VT
) const override
{
111 return VT
.isScalarInteger();
114 bool shouldInsertFencesForAtomic(const Instruction
*I
) const override
{
115 return isa
<LoadInst
>(I
) || isa
<StoreInst
>(I
);
117 Instruction
*emitLeadingFence(IRBuilder
<> &Builder
, Instruction
*Inst
,
118 AtomicOrdering Ord
) const override
;
119 Instruction
*emitTrailingFence(IRBuilder
<> &Builder
, Instruction
*Inst
,
120 AtomicOrdering Ord
) const override
;
122 ISD::NodeType
getExtendForAtomicOps() const override
{
123 return ISD::SIGN_EXTEND
;
126 bool shouldExpandShift(SelectionDAG
&DAG
, SDNode
*N
) const override
{
127 if (DAG
.getMachineFunction().getFunction().hasMinSize())
131 bool isDesirableToCommuteWithShift(const SDNode
*N
,
132 CombineLevel Level
) const override
;
134 /// If a physical register, this returns the register that receives the
135 /// exception address on entry to an EH pad.
137 getExceptionPointerRegister(const Constant
*PersonalityFn
) const override
;
139 /// If a physical register, this returns the register that receives the
140 /// exception typeid on entry to a landing pad.
142 getExceptionSelectorRegister(const Constant
*PersonalityFn
) const override
;
145 void analyzeInputArgs(MachineFunction
&MF
, CCState
&CCInfo
,
146 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
148 void analyzeOutputArgs(MachineFunction
&MF
, CCState
&CCInfo
,
149 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
150 bool IsRet
, CallLoweringInfo
*CLI
) const;
151 // Lower incoming arguments, copy physregs into vregs
152 SDValue
LowerFormalArguments(SDValue Chain
, CallingConv::ID CallConv
,
154 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
155 const SDLoc
&DL
, SelectionDAG
&DAG
,
156 SmallVectorImpl
<SDValue
> &InVals
) const override
;
157 bool CanLowerReturn(CallingConv::ID CallConv
, MachineFunction
&MF
,
159 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
160 LLVMContext
&Context
) const override
;
161 SDValue
LowerReturn(SDValue Chain
, CallingConv::ID CallConv
, bool IsVarArg
,
162 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
163 const SmallVectorImpl
<SDValue
> &OutVals
, const SDLoc
&DL
,
164 SelectionDAG
&DAG
) const override
;
165 SDValue
LowerCall(TargetLowering::CallLoweringInfo
&CLI
,
166 SmallVectorImpl
<SDValue
> &InVals
) const override
;
167 bool shouldConvertConstantLoadToIntImm(const APInt
&Imm
,
168 Type
*Ty
) const override
{
172 template <class NodeTy
>
173 SDValue
getAddr(NodeTy
*N
, SelectionDAG
&DAG
, bool IsLocal
= true) const;
175 SDValue
getStaticTLSAddr(GlobalAddressSDNode
*N
, SelectionDAG
&DAG
,
177 SDValue
getDynamicTLSAddr(GlobalAddressSDNode
*N
, SelectionDAG
&DAG
) const;
179 bool shouldConsiderGEPOffsetSplit() const override
{ return true; }
180 SDValue
lowerGlobalAddress(SDValue Op
, SelectionDAG
&DAG
) const;
181 SDValue
lowerBlockAddress(SDValue Op
, SelectionDAG
&DAG
) const;
182 SDValue
lowerConstantPool(SDValue Op
, SelectionDAG
&DAG
) const;
183 SDValue
lowerGlobalTLSAddress(SDValue Op
, SelectionDAG
&DAG
) const;
184 SDValue
lowerSELECT(SDValue Op
, SelectionDAG
&DAG
) const;
185 SDValue
lowerVASTART(SDValue Op
, SelectionDAG
&DAG
) const;
186 SDValue
lowerFRAMEADDR(SDValue Op
, SelectionDAG
&DAG
) const;
187 SDValue
lowerRETURNADDR(SDValue Op
, SelectionDAG
&DAG
) const;
188 SDValue
lowerShiftLeftParts(SDValue Op
, SelectionDAG
&DAG
) const;
189 SDValue
lowerShiftRightParts(SDValue Op
, SelectionDAG
&DAG
, bool IsSRA
) const;
191 bool isEligibleForTailCallOptimization(
192 CCState
&CCInfo
, CallLoweringInfo
&CLI
, MachineFunction
&MF
,
193 const SmallVector
<CCValAssign
, 16> &ArgLocs
) const;
195 TargetLowering::AtomicExpansionKind
196 shouldExpandAtomicRMWInIR(AtomicRMWInst
*AI
) const override
;
197 virtual Value
*emitMaskedAtomicRMWIntrinsic(
198 IRBuilder
<> &Builder
, AtomicRMWInst
*AI
, Value
*AlignedAddr
, Value
*Incr
,
199 Value
*Mask
, Value
*ShiftAmt
, AtomicOrdering Ord
) const override
;
200 TargetLowering::AtomicExpansionKind
201 shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst
*CI
) const override
;
203 emitMaskedAtomicCmpXchgIntrinsic(IRBuilder
<> &Builder
, AtomicCmpXchgInst
*CI
,
204 Value
*AlignedAddr
, Value
*CmpVal
,
205 Value
*NewVal
, Value
*Mask
,
206 AtomicOrdering Ord
) const override
;