294 lines · c
1//=- LoongArchISelLowering.h - LoongArch DAG Lowering Interface -*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the interfaces that LoongArch uses to lower LLVM code into10// a selection DAG.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H15#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H16 17#include "LoongArch.h"18#include "llvm/CodeGen/CallingConvLower.h"19#include "llvm/CodeGen/SelectionDAG.h"20#include "llvm/CodeGen/TargetLowering.h"21 22namespace llvm {23class LoongArchSubtarget;24 25class LoongArchTargetLowering : public TargetLowering {26 const LoongArchSubtarget &Subtarget;27 28public:29 explicit LoongArchTargetLowering(const TargetMachine &TM,30 const LoongArchSubtarget &STI);31 32 const LoongArchSubtarget &getSubtarget() const { return Subtarget; }33 34 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;35 36 // Provide custom lowering hooks for some operations.37 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;38 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,39 SelectionDAG &DAG) const override;40 41 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;42 43 // Lower incoming arguments, copy physregs into vregs.44 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,45 bool IsVarArg,46 const SmallVectorImpl<ISD::InputArg> &Ins,47 const SDLoc &DL, SelectionDAG &DAG,48 SmallVectorImpl<SDValue> &InVals) const override;49 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,50 bool IsVarArg,51 const SmallVectorImpl<ISD::OutputArg> &Outs,52 LLVMContext &Context, const Type *RetTy) const override;53 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,54 const SmallVectorImpl<ISD::OutputArg> &Outs,55 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,56 SelectionDAG &DAG) const override;57 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,58 SmallVectorImpl<SDValue> &InVals) const override;59 bool isCheapToSpeculateCttz(Type *Ty) const override;60 bool isCheapToSpeculateCtlz(Type *Ty) const override;61 bool hasAndNot(SDValue Y) const override;62 TargetLowering::AtomicExpansionKind63 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;64 void emitExpandAtomicRMW(AtomicRMWInst *AI) const override;65 66 Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI,67 Value *AlignedAddr, Value *Incr,68 Value *Mask, Value *ShiftAmt,69 AtomicOrdering Ord) const override;70 71 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,72 EVT VT) const override;73 TargetLowering::AtomicExpansionKind74 shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override;75 Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder,76 AtomicCmpXchgInst *CI,77 Value *AlignedAddr, Value *CmpVal,78 Value *NewVal, Value *Mask,79 AtomicOrdering Ord) const override;80 81 bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,82 MachineFunction &MF,83 unsigned Intrinsic) const override;84 85 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,86 EVT VT) const override;87 88 Register89 getExceptionPointerRegister(const Constant *PersonalityFn) const override;90 91 Register92 getExceptionSelectorRegister(const Constant *PersonalityFn) const override;93 94 bool isFsqrtCheap(SDValue Operand, SelectionDAG &DAG) const override {95 return true;96 }97 98 SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,99 int &RefinementSteps, bool &UseOneConstNR,100 bool Reciprocal) const override;101 102 SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,103 int &RefinementSteps) const override;104 105 ISD::NodeType getExtendForAtomicOps() const override {106 return ISD::SIGN_EXTEND;107 }108 109 ISD::NodeType getExtendForAtomicCmpSwapArg() const override;110 111 Register getRegisterByName(const char *RegName, LLT VT,112 const MachineFunction &MF) const override;113 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;114 115 bool decomposeMulByConstant(LLVMContext &Context, EVT VT,116 SDValue C) const override;117 118 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;119 120 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,121 unsigned AS,122 Instruction *I = nullptr) const override;123 124 bool isLegalICmpImmediate(int64_t Imm) const override;125 bool isLegalAddImmediate(int64_t Imm) const override;126 bool isZExtFree(SDValue Val, EVT VT2) const override;127 bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;128 bool signExtendConstant(const ConstantInt *CI) const override;129 130 bool hasAndNotCompare(SDValue Y) const override;131 132 bool convertSelectOfConstantsToMath(EVT VT) const override { return true; }133 134 bool allowsMisalignedMemoryAccesses(135 EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1),136 MachineMemOperand::Flags Flags = MachineMemOperand::MONone,137 unsigned *Fast = nullptr) const override;138 139 bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override {140 if (!VT.isSimple())141 return false;142 143 // Not for i1 vectors144 if (VT.getSimpleVT().getScalarType() == MVT::i1)145 return false;146 147 return isTypeLegal(VT.getSimpleVT());148 }149 bool shouldConsiderGEPOffsetSplit() const override { return true; }150 bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const override;151 bool shouldExtendTypeInLibCall(EVT Type) const override;152 153 bool shouldAlignPointerArgs(CallInst *CI, unsigned &MinSize,154 Align &PrefAlign) const override;155 156 bool isFPImmVLDILegal(const APFloat &Imm, EVT VT) const;157 LegalizeTypeAction getPreferredVectorAction(MVT VT) const override;158 159 bool SimplifyDemandedBitsForTargetNode(SDValue Op, const APInt &DemandedBits,160 const APInt &DemandedElts,161 KnownBits &Known,162 TargetLoweringOpt &TLO,163 unsigned Depth) const override;164 165 bool shouldScalarizeBinop(SDValue VecOp) const override;166 bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,167 unsigned Index) const override;168 bool isExtractVecEltCheap(EVT VT, unsigned Index) const override;169 170 /// Check if a constant splat can be generated using [x]vldi, where imm[12]171 /// is 1.172 std::pair<bool, uint64_t>173 isImmVLDILegalForMode1(const APInt &SplatValue,174 const unsigned SplatBitSize) const;175 176private:177 /// Target-specific function used to lower LoongArch calling conventions.178 typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI,179 unsigned ValNo, MVT ValVT,180 CCValAssign::LocInfo LocInfo,181 ISD::ArgFlagsTy ArgFlags, CCState &State,182 bool IsRet, Type *OrigTy);183 184 void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo,185 const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,186 LoongArchCCAssignFn Fn) const;187 void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo,188 const SmallVectorImpl<ISD::OutputArg> &Outs,189 bool IsRet, CallLoweringInfo *CLI,190 LoongArchCCAssignFn Fn) const;191 192 template <class NodeTy>193 SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M,194 bool IsLocal = true) const;195 SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,196 unsigned Opc, bool UseGOT, bool Large = false) const;197 SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,198 unsigned Opc, bool Large = false) const;199 SDValue getTLSDescAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,200 unsigned Opc, bool Large = false) const;201 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;202 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;203 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;204 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;205 SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;206 SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;207 208 MachineBasicBlock *209 EmitInstrWithCustomInserter(MachineInstr &MI,210 MachineBasicBlock *BB) const override;211 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;212 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;213 SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;214 SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;215 SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;216 SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;217 SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;218 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;219 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;220 SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;221 SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;222 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;223 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;224 SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const;225 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;226 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;227 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;228 SDValue lowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;229 SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;230 SDValue lowerBITREVERSE(SDValue Op, SelectionDAG &DAG) const;231 SDValue lowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;232 SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;233 SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;234 SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;235 SDValue lowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) const;236 SDValue lowerFP16_TO_FP(SDValue Op, SelectionDAG &DAG) const;237 SDValue lowerFP_TO_BF16(SDValue Op, SelectionDAG &DAG) const;238 SDValue lowerBF16_TO_FP(SDValue Op, SelectionDAG &DAG) const;239 SDValue lowerVECREDUCE_ADD(SDValue Op, SelectionDAG &DAG) const;240 SDValue lowerVECREDUCE(SDValue Op, SelectionDAG &DAG) const;241 SDValue lowerConstantFP(SDValue Op, SelectionDAG &DAG) const;242 SDValue lowerRotate(SDValue Op, SelectionDAG &DAG) const;243 244 bool isFPImmLegal(const APFloat &Imm, EVT VT,245 bool ForCodeSize) const override;246 247 bool shouldInsertFencesForAtomic(const Instruction *I) const override;248 249 ConstraintType getConstraintType(StringRef Constraint) const override;250 251 InlineAsm::ConstraintCode252 getInlineAsmMemConstraint(StringRef ConstraintCode) const override;253 254 std::pair<unsigned, const TargetRegisterClass *>255 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,256 StringRef Constraint, MVT VT) const override;257 258 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,259 std::vector<SDValue> &Ops,260 SelectionDAG &DAG) const override;261 262 bool isEligibleForTailCallOptimization(263 CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,264 const SmallVectorImpl<CCValAssign> &ArgLocs) const;265 266 bool softPromoteHalfType() const override { return true; }267 268 bool269 splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val,270 SDValue *Parts, unsigned NumParts, MVT PartVT,271 std::optional<CallingConv::ID> CC) const override;272 273 SDValue274 joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL,275 const SDValue *Parts, unsigned NumParts,276 MVT PartVT, EVT ValueVT,277 std::optional<CallingConv::ID> CC) const override;278 279 /// Return the register type for a given MVT, ensuring vectors are treated280 /// as a series of gpr sized integers.281 MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,282 EVT VT) const override;283 284 /// Return the number of registers for a given MVT, ensuring vectors are285 /// treated as a series of gpr sized integers.286 unsigned getNumRegistersForCallingConv(LLVMContext &Context,287 CallingConv::ID CC,288 EVT VT) const override;289};290 291} // end namespace llvm292 293#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H294