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 ConstraintType
getConstraintType(StringRef Constraint
) const override
;
97 unsigned getInlineAsmMemConstraint(StringRef ConstraintCode
) const override
;
99 std::pair
<unsigned, const TargetRegisterClass
*>
100 getRegForInlineAsmConstraint(const TargetRegisterInfo
*TRI
,
101 StringRef Constraint
, MVT VT
) const override
;
103 void LowerAsmOperandForConstraint(SDValue Op
, std::string
&Constraint
,
104 std::vector
<SDValue
> &Ops
,
105 SelectionDAG
&DAG
) const override
;
108 EmitInstrWithCustomInserter(MachineInstr
&MI
,
109 MachineBasicBlock
*BB
) const override
;
111 EVT
getSetCCResultType(const DataLayout
&DL
, LLVMContext
&Context
,
112 EVT VT
) const override
;
114 bool convertSetCCLogicToBitwiseLogic(EVT VT
) const override
{
115 return VT
.isScalarInteger();
118 bool shouldInsertFencesForAtomic(const Instruction
*I
) const override
{
119 return isa
<LoadInst
>(I
) || isa
<StoreInst
>(I
);
121 Instruction
*emitLeadingFence(IRBuilder
<> &Builder
, Instruction
*Inst
,
122 AtomicOrdering Ord
) const override
;
123 Instruction
*emitTrailingFence(IRBuilder
<> &Builder
, Instruction
*Inst
,
124 AtomicOrdering Ord
) const override
;
126 ISD::NodeType
getExtendForAtomicOps() const override
{
127 return ISD::SIGN_EXTEND
;
130 bool shouldExpandShift(SelectionDAG
&DAG
, SDNode
*N
) const override
{
131 if (DAG
.getMachineFunction().getFunction().hasMinSize())
135 bool isDesirableToCommuteWithShift(const SDNode
*N
,
136 CombineLevel Level
) const override
;
138 /// If a physical register, this returns the register that receives the
139 /// exception address on entry to an EH pad.
141 getExceptionPointerRegister(const Constant
*PersonalityFn
) const override
;
143 /// If a physical register, this returns the register that receives the
144 /// exception typeid on entry to a landing pad.
146 getExceptionSelectorRegister(const Constant
*PersonalityFn
) const override
;
148 bool shouldExtendTypeInLibCall(EVT Type
) const override
;
151 void analyzeInputArgs(MachineFunction
&MF
, CCState
&CCInfo
,
152 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
154 void analyzeOutputArgs(MachineFunction
&MF
, CCState
&CCInfo
,
155 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
156 bool IsRet
, CallLoweringInfo
*CLI
) const;
157 // Lower incoming arguments, copy physregs into vregs
158 SDValue
LowerFormalArguments(SDValue Chain
, CallingConv::ID CallConv
,
160 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
161 const SDLoc
&DL
, SelectionDAG
&DAG
,
162 SmallVectorImpl
<SDValue
> &InVals
) const override
;
163 bool CanLowerReturn(CallingConv::ID CallConv
, MachineFunction
&MF
,
165 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
166 LLVMContext
&Context
) const override
;
167 SDValue
LowerReturn(SDValue Chain
, CallingConv::ID CallConv
, bool IsVarArg
,
168 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
169 const SmallVectorImpl
<SDValue
> &OutVals
, const SDLoc
&DL
,
170 SelectionDAG
&DAG
) const override
;
171 SDValue
LowerCall(TargetLowering::CallLoweringInfo
&CLI
,
172 SmallVectorImpl
<SDValue
> &InVals
) const override
;
173 bool shouldConvertConstantLoadToIntImm(const APInt
&Imm
,
174 Type
*Ty
) const override
{
178 template <class NodeTy
>
179 SDValue
getAddr(NodeTy
*N
, SelectionDAG
&DAG
, bool IsLocal
= true) const;
181 SDValue
getStaticTLSAddr(GlobalAddressSDNode
*N
, SelectionDAG
&DAG
,
183 SDValue
getDynamicTLSAddr(GlobalAddressSDNode
*N
, SelectionDAG
&DAG
) const;
185 bool shouldConsiderGEPOffsetSplit() const override
{ return true; }
186 SDValue
lowerGlobalAddress(SDValue Op
, SelectionDAG
&DAG
) const;
187 SDValue
lowerBlockAddress(SDValue Op
, SelectionDAG
&DAG
) const;
188 SDValue
lowerConstantPool(SDValue Op
, SelectionDAG
&DAG
) const;
189 SDValue
lowerGlobalTLSAddress(SDValue Op
, SelectionDAG
&DAG
) const;
190 SDValue
lowerSELECT(SDValue Op
, SelectionDAG
&DAG
) const;
191 SDValue
lowerVASTART(SDValue Op
, SelectionDAG
&DAG
) const;
192 SDValue
lowerFRAMEADDR(SDValue Op
, SelectionDAG
&DAG
) const;
193 SDValue
lowerRETURNADDR(SDValue Op
, SelectionDAG
&DAG
) const;
194 SDValue
lowerShiftLeftParts(SDValue Op
, SelectionDAG
&DAG
) const;
195 SDValue
lowerShiftRightParts(SDValue Op
, SelectionDAG
&DAG
, bool IsSRA
) const;
197 bool isEligibleForTailCallOptimization(
198 CCState
&CCInfo
, CallLoweringInfo
&CLI
, MachineFunction
&MF
,
199 const SmallVector
<CCValAssign
, 16> &ArgLocs
) const;
201 TargetLowering::AtomicExpansionKind
202 shouldExpandAtomicRMWInIR(AtomicRMWInst
*AI
) const override
;
203 virtual Value
*emitMaskedAtomicRMWIntrinsic(
204 IRBuilder
<> &Builder
, AtomicRMWInst
*AI
, Value
*AlignedAddr
, Value
*Incr
,
205 Value
*Mask
, Value
*ShiftAmt
, AtomicOrdering Ord
) const override
;
206 TargetLowering::AtomicExpansionKind
207 shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst
*CI
) const override
;
209 emitMaskedAtomicCmpXchgIntrinsic(IRBuilder
<> &Builder
, AtomicCmpXchgInst
*CI
,
210 Value
*AlignedAddr
, Value
*CmpVal
,
211 Value
*NewVal
, Value
*Mask
,
212 AtomicOrdering Ord
) const override
;