| 1 | //===-- X86ISelLowering.h - X86 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-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file defines the interfaces that X86 uses to lower LLVM code into a |
| 10 | // selection DAG. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_LIB_TARGET_X86_X86ISELLOWERING_H |
| 15 | #define LLVM_LIB_TARGET_X86_X86ISELLOWERING_H |
| 16 | |
| 17 | #include "X86SelectionDAGInfo.h" |
| 18 | #include "llvm/CodeGen/MachineFunction.h" |
| 19 | #include "llvm/CodeGen/TargetLowering.h" |
| 20 | |
| 21 | namespace llvm { |
| 22 | class X86Subtarget; |
| 23 | class X86TargetMachine; |
| 24 | |
| 25 | namespace X86 { |
| 26 | /// Current rounding mode is represented in bits 11:10 of FPSR. These |
| 27 | /// values are same as corresponding constants for rounding mode used |
| 28 | /// in glibc. |
| 29 | enum RoundingMode { |
| 30 | rmInvalid = -1, // For handle Invalid rounding mode |
| 31 | rmToNearest = 0, // FE_TONEAREST |
| 32 | rmDownward = 1 << 10, // FE_DOWNWARD |
| 33 | rmUpward = 2 << 10, // FE_UPWARD |
| 34 | rmTowardZero = 3 << 10, // FE_TOWARDZERO |
| 35 | rmMask = 3 << 10 // Bit mask selecting rounding mode |
| 36 | }; |
| 37 | } |
| 38 | |
| 39 | /// Define some predicates that are used for node matching. |
| 40 | namespace X86 { |
| 41 | /// Returns true if Elt is a constant zero or floating point constant +0.0. |
| 42 | bool isZeroNode(SDValue Elt); |
| 43 | |
| 44 | /// Returns true of the given offset can be |
| 45 | /// fit into displacement field of the instruction. |
| 46 | bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M, |
| 47 | bool hasSymbolicDisplacement); |
| 48 | |
| 49 | /// Determines whether the callee is required to pop its |
| 50 | /// own arguments. Callee pop is necessary to support tail calls. |
| 51 | bool isCalleePop(CallingConv::ID CallingConv, |
| 52 | bool is64Bit, bool IsVarArg, bool GuaranteeTCO); |
| 53 | |
| 54 | /// If Op is a constant whose elements are all the same constant or |
| 55 | /// undefined, return true and return the constant value in \p SplatVal. |
| 56 | /// If we have undef bits that don't cover an entire element, we treat these |
| 57 | /// as zero if AllowPartialUndefs is set, else we fail and return false. |
| 58 | bool isConstantSplat(SDValue Op, APInt &SplatVal, |
| 59 | bool AllowPartialUndefs = true); |
| 60 | |
| 61 | /// Check if Op is a load operation that could be folded into some other x86 |
| 62 | /// instruction as a memory operand. Example: vpaddd (%rdi), %xmm0, %xmm0. |
| 63 | bool mayFoldLoad(SDValue Op, const X86Subtarget &Subtarget, |
| 64 | bool AssumeSingleUse = false, |
| 65 | bool IgnoreAlignment = false); |
| 66 | |
| 67 | /// Check if Op is a load operation that could be folded into a vector splat |
| 68 | /// instruction as a memory operand. Example: vbroadcastss 16(%rdi), %xmm2. |
| 69 | bool mayFoldLoadIntoBroadcastFromMem(SDValue Op, MVT EltVT, |
| 70 | const X86Subtarget &Subtarget, |
| 71 | bool AssumeSingleUse = false); |
| 72 | |
| 73 | /// Check if Op is a value that could be used to fold a store into some |
| 74 | /// other x86 instruction as a memory operand. Ex: pextrb $0, %xmm0, (%rdi). |
| 75 | bool mayFoldIntoStore(SDValue Op); |
| 76 | |
| 77 | /// Check if Op is an operation that could be folded into a zero extend x86 |
| 78 | /// instruction. |
| 79 | bool mayFoldIntoZeroExtend(SDValue Op); |
| 80 | |
| 81 | /// True if the target supports the extended frame for async Swift |
| 82 | /// functions. |
| 83 | bool isExtendedSwiftAsyncFrameSupported(const X86Subtarget &Subtarget, |
| 84 | const MachineFunction &MF); |
| 85 | |
| 86 | /// Convert LLVM rounding mode to X86 rounding mode. |
| 87 | int getRoundingModeX86(unsigned RM); |
| 88 | |
| 89 | } // end namespace X86 |
| 90 | |
| 91 | //===--------------------------------------------------------------------===// |
| 92 | // X86 Implementation of the TargetLowering interface |
| 93 | class X86TargetLowering final : public TargetLowering { |
| 94 | // Copying needed for an outgoing byval argument. |
| 95 | enum ByValCopyKind { |
| 96 | // Argument is already in the correct location, no copy needed. |
| 97 | NoCopy, |
| 98 | // Argument value is currently in the local stack frame, needs copying to |
| 99 | // outgoing arguemnt area. |
| 100 | CopyOnce, |
| 101 | // Argument value is currently in the outgoing argument area, but not at |
| 102 | // the correct offset, so needs copying via a temporary in local stack |
| 103 | // space. |
| 104 | CopyViaTemp, |
| 105 | }; |
| 106 | |
| 107 | public: |
| 108 | explicit X86TargetLowering(const X86TargetMachine &TM, |
| 109 | const X86Subtarget &STI); |
| 110 | |
| 111 | unsigned getJumpTableEncoding() const override; |
| 112 | bool useSoftFloat() const override; |
| 113 | |
| 114 | void markLibCallAttributes(MachineFunction *MF, unsigned CC, |
| 115 | ArgListTy &Args) const override; |
| 116 | |
| 117 | MVT getScalarShiftAmountTy(const DataLayout &, EVT VT) const override { |
| 118 | return MVT::i8; |
| 119 | } |
| 120 | |
| 121 | const MCExpr * |
| 122 | LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, |
| 123 | const MachineBasicBlock *MBB, unsigned uid, |
| 124 | MCContext &Ctx) const override; |
| 125 | |
| 126 | /// Returns relocation base for the given PIC jumptable. |
| 127 | SDValue getPICJumpTableRelocBase(SDValue Table, |
| 128 | SelectionDAG &DAG) const override; |
| 129 | const MCExpr * |
| 130 | getPICJumpTableRelocBaseExpr(const MachineFunction *MF, |
| 131 | unsigned JTI, MCContext &Ctx) const override; |
| 132 | |
| 133 | /// Return the desired alignment for ByVal aggregate |
| 134 | /// function arguments in the caller parameter area. For X86, aggregates |
| 135 | /// that contains are placed at 16-byte boundaries while the rest are at |
| 136 | /// 4-byte boundaries. |
| 137 | Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override; |
| 138 | |
| 139 | EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, |
| 140 | const AttributeList &FuncAttributes) const override; |
| 141 | |
| 142 | /// Returns true if it's safe to use load / store of the |
| 143 | /// specified type to expand memcpy / memset inline. This is mostly true |
| 144 | /// for all types except for some special cases. For example, on X86 |
| 145 | /// targets without SSE2 f64 load / store are done with fldl / fstpl which |
| 146 | /// also does type conversion. Note the specified type doesn't have to be |
| 147 | /// legal as the hook is used before type legalization. |
| 148 | bool isSafeMemOpType(MVT VT) const override; |
| 149 | |
| 150 | bool isMemoryAccessFast(EVT VT, Align Alignment) const; |
| 151 | |
| 152 | /// Returns true if the target allows unaligned memory accesses of the |
| 153 | /// specified type. Returns whether it is "fast" in the last argument. |
| 154 | bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment, |
| 155 | MachineMemOperand::Flags Flags, |
| 156 | unsigned *Fast) const override; |
| 157 | |
| 158 | /// This function returns true if the memory access is aligned or if the |
| 159 | /// target allows this specific unaligned memory access. If the access is |
| 160 | /// allowed, the optional final parameter returns a relative speed of the |
| 161 | /// access (as defined by the target). |
| 162 | bool allowsMemoryAccess( |
| 163 | LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace, |
| 164 | Align Alignment, |
| 165 | MachineMemOperand::Flags Flags = MachineMemOperand::MONone, |
| 166 | unsigned *Fast = nullptr) const override; |
| 167 | |
| 168 | bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, |
| 169 | const MachineMemOperand &MMO, |
| 170 | unsigned *Fast) const { |
| 171 | return allowsMemoryAccess(Context, DL, VT, AddrSpace: MMO.getAddrSpace(), |
| 172 | Alignment: MMO.getAlign(), Flags: MMO.getFlags(), Fast); |
| 173 | } |
| 174 | |
| 175 | /// Provide custom lowering hooks for some operations. |
| 176 | /// |
| 177 | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
| 178 | |
| 179 | /// Replace the results of node with an illegal result |
| 180 | /// type with new values built out of custom code. |
| 181 | /// |
| 182 | void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, |
| 183 | SelectionDAG &DAG) const override; |
| 184 | |
| 185 | SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; |
| 186 | |
| 187 | bool preferABDSToABSWithNSW(EVT VT) const override; |
| 188 | |
| 189 | bool preferSextInRegOfTruncate(EVT TruncVT, EVT VT, |
| 190 | EVT ExtVT) const override; |
| 191 | |
| 192 | bool isXAndYEqZeroPreferableToXAndYEqY(ISD::CondCode Cond, |
| 193 | EVT VT) const override; |
| 194 | |
| 195 | /// Return true if the target has native support for |
| 196 | /// the specified value type and it is 'desirable' to use the type for the |
| 197 | /// given node type. e.g. On x86 i16 is legal, but undesirable since i16 |
| 198 | /// instruction encodings are longer and some i16 instructions are slow. |
| 199 | bool isTypeDesirableForOp(unsigned Opc, EVT VT) const override; |
| 200 | |
| 201 | /// Return true if the target has native support for the |
| 202 | /// specified value type and it is 'desirable' to use the type. e.g. On x86 |
| 203 | /// i16 is legal, but undesirable since i16 instruction encodings are longer |
| 204 | /// and some i16 instructions are slow. |
| 205 | bool IsDesirableToPromoteOp(SDValue Op, EVT &PVT) const override; |
| 206 | |
| 207 | /// Return prefered fold type, Abs if this is a vector, AddAnd if its an |
| 208 | /// integer, None otherwise. |
| 209 | TargetLowering::AndOrSETCCFoldKind |
| 210 | isDesirableToCombineLogicOpOfSETCC(const SDNode *LogicOp, |
| 211 | const SDNode *SETCC0, |
| 212 | const SDNode *SETCC1) const override; |
| 213 | |
| 214 | /// Return the newly negated expression if the cost is not expensive and |
| 215 | /// set the cost in \p Cost to indicate that if it is cheaper or neutral to |
| 216 | /// do the negation. |
| 217 | SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, |
| 218 | bool LegalOperations, bool ForCodeSize, |
| 219 | NegatibleCost &Cost, |
| 220 | unsigned Depth) const override; |
| 221 | |
| 222 | MachineBasicBlock * |
| 223 | EmitInstrWithCustomInserter(MachineInstr &MI, |
| 224 | MachineBasicBlock *MBB) const override; |
| 225 | |
| 226 | /// Do not merge vector stores after legalization because that may conflict |
| 227 | /// with x86-specific store splitting optimizations. |
| 228 | bool mergeStoresAfterLegalization(EVT MemVT) const override { |
| 229 | return !MemVT.isVector(); |
| 230 | } |
| 231 | |
| 232 | bool canMergeStoresTo(unsigned AddressSpace, EVT MemVT, |
| 233 | const MachineFunction &MF) const override; |
| 234 | |
| 235 | bool isCheapToSpeculateCttz(Type *Ty) const override; |
| 236 | |
| 237 | bool isCheapToSpeculateCtlz(Type *Ty) const override; |
| 238 | |
| 239 | bool isCtlzFast() const override; |
| 240 | |
| 241 | bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const override { |
| 242 | // If the pair to store is a mixture of float and int values, we will |
| 243 | // save two bitwise instructions and one float-to-int instruction and |
| 244 | // increase one store instruction. There is potentially a more |
| 245 | // significant benefit because it avoids the float->int domain switch |
| 246 | // for input value. So It is more likely a win. |
| 247 | if ((LTy.isFloatingPoint() && HTy.isInteger()) || |
| 248 | (LTy.isInteger() && HTy.isFloatingPoint())) |
| 249 | return true; |
| 250 | // If the pair only contains int values, we will save two bitwise |
| 251 | // instructions and increase one store instruction (costing one more |
| 252 | // store buffer). Since the benefit is more blurred so we leave |
| 253 | // such pair out until we get testcase to prove it is a win. |
| 254 | return false; |
| 255 | } |
| 256 | |
| 257 | bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override; |
| 258 | |
| 259 | bool hasAndNotCompare(SDValue Y) const override; |
| 260 | |
| 261 | bool hasAndNot(SDValue Y) const override; |
| 262 | |
| 263 | bool hasBitTest(SDValue X, SDValue Y) const override; |
| 264 | |
| 265 | bool shouldProduceAndByConstByHoistingConstFromShiftsLHSOfAnd( |
| 266 | SDValue X, ConstantSDNode *XC, ConstantSDNode *CC, SDValue Y, |
| 267 | unsigned OldShiftOpcode, unsigned NewShiftOpcode, |
| 268 | SelectionDAG &DAG) const override; |
| 269 | |
| 270 | unsigned preferedOpcodeForCmpEqPiecesOfOperand( |
| 271 | EVT VT, unsigned ShiftOpc, bool MayTransformRotate, |
| 272 | const APInt &ShiftOrRotateAmt, |
| 273 | const std::optional<APInt> &AndMask) const override; |
| 274 | |
| 275 | bool preferScalarizeSplat(SDNode *N) const override; |
| 276 | |
| 277 | CondMergingParams |
| 278 | getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs, |
| 279 | const Value *Rhs) const override; |
| 280 | |
| 281 | bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override; |
| 282 | |
| 283 | bool shouldFoldMaskToVariableShiftPair(SDValue Y) const override; |
| 284 | |
| 285 | bool |
| 286 | shouldTransformSignedTruncationCheck(EVT XVT, |
| 287 | unsigned KeptBits) const override { |
| 288 | // For vectors, we don't have a preference.. |
| 289 | if (XVT.isVector()) |
| 290 | return false; |
| 291 | |
| 292 | auto VTIsOk = [](EVT VT) -> bool { |
| 293 | return VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32 || |
| 294 | VT == MVT::i64; |
| 295 | }; |
| 296 | |
| 297 | // We are ok with KeptBitsVT being byte/word/dword, what MOVS supports. |
| 298 | // XVT will be larger than KeptBitsVT. |
| 299 | MVT KeptBitsVT = MVT::getIntegerVT(BitWidth: KeptBits); |
| 300 | return VTIsOk(XVT) && VTIsOk(KeptBitsVT); |
| 301 | } |
| 302 | |
| 303 | ShiftLegalizationStrategy |
| 304 | preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N, |
| 305 | unsigned ExpansionFactor) const override; |
| 306 | |
| 307 | bool shouldSplatInsEltVarIndex(EVT VT) const override; |
| 308 | |
| 309 | bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override { |
| 310 | // Converting to sat variants holds little benefit on X86 as we will just |
| 311 | // need to saturate the value back using fp arithmatic. |
| 312 | return Op != ISD::FP_TO_UINT_SAT && isOperationLegalOrCustom(Op, VT); |
| 313 | } |
| 314 | |
| 315 | bool convertSetCCLogicToBitwiseLogic(EVT VT) const override { |
| 316 | return VT.isScalarInteger(); |
| 317 | } |
| 318 | |
| 319 | /// Vector-sized comparisons are fast using PCMPEQ + PMOVMSK or PTEST. |
| 320 | MVT hasFastEqualityCompare(unsigned NumBits) const override; |
| 321 | |
| 322 | /// Return the value type to use for ISD::SETCC. |
| 323 | EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, |
| 324 | EVT VT) const override; |
| 325 | |
| 326 | bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits, |
| 327 | const APInt &DemandedElts, |
| 328 | TargetLoweringOpt &TLO) const override; |
| 329 | |
| 330 | /// Determine which of the bits specified in Mask are known to be either |
| 331 | /// zero or one and return them in the KnownZero/KnownOne bitsets. |
| 332 | void computeKnownBitsForTargetNode(const SDValue Op, |
| 333 | KnownBits &Known, |
| 334 | const APInt &DemandedElts, |
| 335 | const SelectionDAG &DAG, |
| 336 | unsigned Depth = 0) const override; |
| 337 | |
| 338 | /// Determine the number of bits in the operation that are sign bits. |
| 339 | unsigned ComputeNumSignBitsForTargetNode(SDValue Op, |
| 340 | const APInt &DemandedElts, |
| 341 | const SelectionDAG &DAG, |
| 342 | unsigned Depth) const override; |
| 343 | |
| 344 | bool SimplifyDemandedVectorEltsForTargetNode(SDValue Op, |
| 345 | const APInt &DemandedElts, |
| 346 | APInt &KnownUndef, |
| 347 | APInt &KnownZero, |
| 348 | TargetLoweringOpt &TLO, |
| 349 | unsigned Depth) const override; |
| 350 | |
| 351 | bool SimplifyDemandedVectorEltsForTargetShuffle(SDValue Op, |
| 352 | const APInt &DemandedElts, |
| 353 | unsigned MaskIndex, |
| 354 | TargetLoweringOpt &TLO, |
| 355 | unsigned Depth) const; |
| 356 | |
| 357 | bool SimplifyDemandedBitsForTargetNode(SDValue Op, |
| 358 | const APInt &DemandedBits, |
| 359 | const APInt &DemandedElts, |
| 360 | KnownBits &Known, |
| 361 | TargetLoweringOpt &TLO, |
| 362 | unsigned Depth) const override; |
| 363 | |
| 364 | SDValue SimplifyMultipleUseDemandedBitsForTargetNode( |
| 365 | SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts, |
| 366 | SelectionDAG &DAG, unsigned Depth) const override; |
| 367 | |
| 368 | bool isGuaranteedNotToBeUndefOrPoisonForTargetNode( |
| 369 | SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, |
| 370 | bool PoisonOnly, unsigned Depth) const override; |
| 371 | |
| 372 | bool canCreateUndefOrPoisonForTargetNode( |
| 373 | SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, |
| 374 | bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const override; |
| 375 | |
| 376 | bool isSplatValueForTargetNode(SDValue Op, const APInt &DemandedElts, |
| 377 | APInt &UndefElts, const SelectionDAG &DAG, |
| 378 | unsigned Depth) const override; |
| 379 | |
| 380 | bool isTargetCanonicalConstantNode(SDValue Op) const override { |
| 381 | // Peek through bitcasts/extracts/inserts to see if we have a vector |
| 382 | // load/broadcast from memory. |
| 383 | while (Op.getOpcode() == ISD::BITCAST || |
| 384 | Op.getOpcode() == ISD::EXTRACT_SUBVECTOR || |
| 385 | (Op.getOpcode() == ISD::INSERT_SUBVECTOR && |
| 386 | Op.getOperand(i: 0).isUndef())) |
| 387 | Op = Op.getOperand(i: Op.getOpcode() == ISD::INSERT_SUBVECTOR ? 1 : 0); |
| 388 | |
| 389 | return Op.getOpcode() == X86ISD::VBROADCAST_LOAD || |
| 390 | Op.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD || |
| 391 | (Op.getOpcode() == ISD::LOAD && |
| 392 | getTargetConstantFromLoad(LD: cast<LoadSDNode>(Val&: Op))) || |
| 393 | TargetLowering::isTargetCanonicalConstantNode(Op); |
| 394 | } |
| 395 | |
| 396 | bool isTargetCanonicalSelect(SDNode *N) const override; |
| 397 | |
| 398 | const Constant *getTargetConstantFromLoad(LoadSDNode *LD) const override; |
| 399 | |
| 400 | SDValue unwrapAddress(SDValue N) const override; |
| 401 | |
| 402 | SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const; |
| 403 | |
| 404 | ConstraintType getConstraintType(StringRef Constraint) const override; |
| 405 | |
| 406 | /// Examine constraint string and operand type and determine a weight value. |
| 407 | /// The operand object must already have been set up with the operand type. |
| 408 | ConstraintWeight |
| 409 | getSingleConstraintMatchWeight(AsmOperandInfo &Info, |
| 410 | const char *Constraint) const override; |
| 411 | |
| 412 | const char *LowerXConstraint(EVT ConstraintVT) const override; |
| 413 | |
| 414 | /// Lower the specified operand into the Ops vector. If it is invalid, don't |
| 415 | /// add anything to Ops. If hasMemory is true it means one of the asm |
| 416 | /// constraint of the inline asm instruction being processed is 'm'. |
| 417 | void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, |
| 418 | std::vector<SDValue> &Ops, |
| 419 | SelectionDAG &DAG) const override; |
| 420 | |
| 421 | InlineAsm::ConstraintCode |
| 422 | getInlineAsmMemConstraint(StringRef ConstraintCode) const override { |
| 423 | if (ConstraintCode == "v" ) |
| 424 | return InlineAsm::ConstraintCode::v; |
| 425 | return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); |
| 426 | } |
| 427 | |
| 428 | /// Handle Lowering flag assembly outputs. |
| 429 | SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag, |
| 430 | const SDLoc &DL, |
| 431 | const AsmOperandInfo &Constraint, |
| 432 | SelectionDAG &DAG) const override; |
| 433 | |
| 434 | /// Given a physical register constraint |
| 435 | /// (e.g. {edx}), return the register number and the register class for the |
| 436 | /// register. This should only be used for C_Register constraints. On |
| 437 | /// error, this returns a register number of 0. |
| 438 | std::pair<unsigned, const TargetRegisterClass *> |
| 439 | getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, |
| 440 | StringRef Constraint, MVT VT) const override; |
| 441 | |
| 442 | /// Return true if the addressing mode represented |
| 443 | /// by AM is legal for this target, for a load/store of the specified type. |
| 444 | bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, |
| 445 | Type *Ty, unsigned AS, |
| 446 | Instruction *I = nullptr) const override; |
| 447 | |
| 448 | bool addressingModeSupportsTLS(const GlobalValue &GV) const override; |
| 449 | |
| 450 | /// Return true if the specified immediate is legal |
| 451 | /// icmp immediate, that is the target has icmp instructions which can |
| 452 | /// compare a register against the immediate without having to materialize |
| 453 | /// the immediate into a register. |
| 454 | bool isLegalICmpImmediate(int64_t Imm) const override; |
| 455 | |
| 456 | /// Return true if the specified immediate is legal |
| 457 | /// add immediate, that is the target has add instructions which can |
| 458 | /// add a register and the immediate without having to materialize |
| 459 | /// the immediate into a register. |
| 460 | bool isLegalAddImmediate(int64_t Imm) const override; |
| 461 | |
| 462 | bool isLegalStoreImmediate(int64_t Imm) const override; |
| 463 | |
| 464 | /// Add x86-specific opcodes to the default list. |
| 465 | bool isBinOp(unsigned Opcode) const override; |
| 466 | |
| 467 | /// Returns true if the opcode is a commutative binary operation. |
| 468 | bool isCommutativeBinOp(unsigned Opcode) const override; |
| 469 | |
| 470 | /// Return true if it's free to truncate a value of |
| 471 | /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in |
| 472 | /// register EAX to i16 by referencing its sub-register AX. |
| 473 | bool isTruncateFree(Type *Ty1, Type *Ty2) const override; |
| 474 | bool isTruncateFree(EVT VT1, EVT VT2) const override; |
| 475 | |
| 476 | bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override; |
| 477 | |
| 478 | /// Return true if any actual instruction that defines a |
| 479 | /// value of type Ty1 implicit zero-extends the value to Ty2 in the result |
| 480 | /// register. This does not necessarily include registers defined in |
| 481 | /// unknown ways, such as incoming arguments, or copies from unknown |
| 482 | /// virtual registers. Also, if isTruncateFree(Ty2, Ty1) is true, this |
| 483 | /// does not necessarily apply to truncate instructions. e.g. on x86-64, |
| 484 | /// all instructions that define 32-bit values implicit zero-extend the |
| 485 | /// result out to 64 bits. |
| 486 | bool isZExtFree(Type *Ty1, Type *Ty2) const override; |
| 487 | bool isZExtFree(EVT VT1, EVT VT2) const override; |
| 488 | bool isZExtFree(SDValue Val, EVT VT2) const override; |
| 489 | |
| 490 | bool shouldConvertPhiType(Type *From, Type *To) const override; |
| 491 | |
| 492 | /// Return true if folding a vector load into ExtVal (a sign, zero, or any |
| 493 | /// extend node) is profitable. |
| 494 | bool isVectorLoadExtDesirable(SDValue) const override; |
| 495 | |
| 496 | /// Return true if an FMA operation is faster than a pair of fmul and fadd |
| 497 | /// instructions. fmuladd intrinsics will be expanded to FMAs when this |
| 498 | /// method returns true, otherwise fmuladd is expanded to fmul + fadd. |
| 499 | bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, |
| 500 | EVT VT) const override; |
| 501 | |
| 502 | /// Return true if it's profitable to narrow operations of type SrcVT to |
| 503 | /// DestVT. e.g. on x86, it's profitable to narrow from i32 to i8 but not |
| 504 | /// from i32 to i16. |
| 505 | bool isNarrowingProfitable(SDNode *N, EVT SrcVT, EVT DestVT) const override; |
| 506 | |
| 507 | bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT, |
| 508 | unsigned SelectOpcode, SDValue X, |
| 509 | SDValue Y) const override; |
| 510 | |
| 511 | /// Given an intrinsic, checks if on the target the intrinsic will need to |
| 512 | /// map to a MemIntrinsicNode (touches memory). If this is the case, it |
| 513 | /// returns true and stores the intrinsic information into the IntrinsicInfo |
| 514 | /// that was passed to the function. |
| 515 | void getTgtMemIntrinsic(SmallVectorImpl<IntrinsicInfo> &Infos, |
| 516 | const CallBase &I, MachineFunction &MF, |
| 517 | unsigned Intrinsic) const override; |
| 518 | |
| 519 | /// Returns true if the target can instruction select the |
| 520 | /// specified FP immediate natively. If false, the legalizer will |
| 521 | /// materialize the FP immediate as a load from a constant pool. |
| 522 | bool isFPImmLegal(const APFloat &Imm, EVT VT, |
| 523 | bool ForCodeSize) const override; |
| 524 | |
| 525 | /// Targets can use this to indicate that they only support *some* |
| 526 | /// VECTOR_SHUFFLE operations, those with specific masks. By default, if a |
| 527 | /// target supports the VECTOR_SHUFFLE node, all mask values are assumed to |
| 528 | /// be legal. |
| 529 | bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override; |
| 530 | |
| 531 | /// Similar to isShuffleMaskLegal. Targets can use this to indicate if there |
| 532 | /// is a suitable VECTOR_SHUFFLE that can be used to replace a VAND with a |
| 533 | /// constant pool entry. |
| 534 | bool isVectorClearMaskLegal(ArrayRef<int> Mask, EVT VT) const override; |
| 535 | |
| 536 | /// Returns true if lowering to a jump table is allowed. |
| 537 | bool areJTsAllowed(const Function *Fn) const override; |
| 538 | |
| 539 | MVT getPreferredSwitchConditionType(LLVMContext &Context, |
| 540 | EVT ConditionVT) const override; |
| 541 | |
| 542 | /// If true, then instruction selection should |
| 543 | /// seek to shrink the FP constant of the specified type to a smaller type |
| 544 | /// in order to save space and / or reduce runtime. |
| 545 | bool ShouldShrinkFPConstant(EVT VT) const override; |
| 546 | |
| 547 | /// Return true if we believe it is correct and profitable to reduce the |
| 548 | /// load node to a smaller type. |
| 549 | bool |
| 550 | shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT, |
| 551 | std::optional<unsigned> ByteOffset) const override; |
| 552 | |
| 553 | /// Return true if the specified scalar FP type is computed in an SSE |
| 554 | /// register, not on the X87 floating point stack. |
| 555 | bool isScalarFPTypeInSSEReg(EVT VT) const; |
| 556 | |
| 557 | /// Returns true if it is beneficial to convert a load of a constant |
| 558 | /// to just the constant itself. |
| 559 | bool shouldConvertConstantLoadToIntImm(const APInt &Imm, |
| 560 | Type *Ty) const override; |
| 561 | |
| 562 | bool reduceSelectOfFPConstantLoads(EVT CmpOpVT) const override; |
| 563 | |
| 564 | bool convertSelectOfConstantsToMath(EVT VT) const override; |
| 565 | |
| 566 | bool decomposeMulByConstant(LLVMContext &Context, EVT VT, |
| 567 | SDValue C) const override; |
| 568 | |
| 569 | /// Return true if EXTRACT_SUBVECTOR is cheap for this result type |
| 570 | /// with this index. |
| 571 | bool (EVT ResVT, EVT SrcVT, |
| 572 | unsigned Index) const override; |
| 573 | |
| 574 | /// Scalar ops always have equal or better analysis/performance/power than |
| 575 | /// the vector equivalent, so this always makes sense if the scalar op is |
| 576 | /// supported. |
| 577 | bool shouldScalarizeBinop(SDValue) const override; |
| 578 | |
| 579 | /// Extract of a scalar FP value from index 0 of a vector is free. |
| 580 | bool (EVT VT, unsigned Index) const override { |
| 581 | EVT EltVT = VT.getScalarType(); |
| 582 | return (EltVT == MVT::f32 || EltVT == MVT::f64) && Index == 0; |
| 583 | } |
| 584 | |
| 585 | /// Overflow nodes should get combined/lowered to optimal instructions |
| 586 | /// (they should allow eliminating explicit compares by getting flags from |
| 587 | /// math ops). |
| 588 | bool shouldFormOverflowOp(unsigned Opcode, EVT VT, |
| 589 | bool MathUsed) const override; |
| 590 | |
| 591 | bool storeOfVectorConstantIsCheap(bool IsZero, EVT MemVT, unsigned NumElem, |
| 592 | unsigned AddrSpace) const override { |
| 593 | // If we can replace more than 2 scalar stores, there will be a reduction |
| 594 | // in instructions even after we add a vector constant load. |
| 595 | return IsZero || NumElem > 2; |
| 596 | } |
| 597 | |
| 598 | bool isLoadBitCastBeneficial(EVT LoadVT, EVT BitcastVT, |
| 599 | const SelectionDAG &DAG, |
| 600 | const MachineMemOperand &MMO) const override; |
| 601 | |
| 602 | bool isProfitableToCombineMinNumMaxNum(EVT VT) const override { |
| 603 | // X86 has instructions that correspond to cmp + select, so forming |
| 604 | // minnum/maxnum is not profitable. |
| 605 | return false; |
| 606 | } |
| 607 | |
| 608 | Register getRegisterByName(const char* RegName, LLT VT, |
| 609 | const MachineFunction &MF) const override; |
| 610 | |
| 611 | /// If a physical register, this returns the register that receives the |
| 612 | /// exception address on entry to an EH pad. |
| 613 | Register |
| 614 | getExceptionPointerRegister(const Constant *PersonalityFn) const override; |
| 615 | |
| 616 | /// If a physical register, this returns the register that receives the |
| 617 | /// exception typeid on entry to a landing pad. |
| 618 | Register |
| 619 | getExceptionSelectorRegister(const Constant *PersonalityFn) const override; |
| 620 | |
| 621 | bool needsFixedCatchObjects() const override; |
| 622 | |
| 623 | /// This method returns a target specific FastISel object, |
| 624 | /// or null if the target does not support "fast" ISel. |
| 625 | FastISel * |
| 626 | createFastISel(FunctionLoweringInfo &funcInfo, |
| 627 | const TargetLibraryInfo *libInfo, |
| 628 | const LibcallLoweringInfo *libcallLowering) const override; |
| 629 | |
| 630 | /// If the target has a standard location for the stack protector cookie, |
| 631 | /// returns the address of that location. Otherwise, returns nullptr. |
| 632 | Value *getIRStackGuard(IRBuilderBase &IRB, |
| 633 | const LibcallLoweringInfo &Libcalls) const override; |
| 634 | |
| 635 | bool useLoadStackGuardNode(const Module &M) const override; |
| 636 | bool useStackGuardXorFP() const override; |
| 637 | void |
| 638 | insertSSPDeclarations(Module &M, |
| 639 | const LibcallLoweringInfo &Libcalls) const override; |
| 640 | SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, |
| 641 | const SDLoc &DL) const override; |
| 642 | |
| 643 | |
| 644 | /// Return true if the target stores SafeStack pointer at a fixed offset in |
| 645 | /// some non-standard address space, and populates the address space and |
| 646 | /// offset as appropriate. |
| 647 | Value *getSafeStackPointerLocation( |
| 648 | IRBuilderBase &IRB, const LibcallLoweringInfo &Libcalls) const override; |
| 649 | |
| 650 | std::pair<SDValue, SDValue> BuildFILD(EVT DstVT, EVT SrcVT, const SDLoc &DL, |
| 651 | SDValue Chain, SDValue Pointer, |
| 652 | MachinePointerInfo PtrInfo, |
| 653 | Align Alignment, |
| 654 | SelectionDAG &DAG) const; |
| 655 | |
| 656 | /// Customize the preferred legalization strategy for certain types. |
| 657 | LegalizeTypeAction getPreferredVectorAction(MVT VT) const override; |
| 658 | |
| 659 | MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, |
| 660 | EVT VT) const override; |
| 661 | |
| 662 | unsigned getNumRegistersForCallingConv(LLVMContext &Context, |
| 663 | CallingConv::ID CC, |
| 664 | EVT VT) const override; |
| 665 | |
| 666 | unsigned getVectorTypeBreakdownForCallingConv( |
| 667 | LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, |
| 668 | unsigned &NumIntermediates, MVT &RegisterVT) const override; |
| 669 | |
| 670 | bool functionArgumentNeedsConsecutiveRegisters( |
| 671 | Type *Ty, CallingConv::ID CallConv, bool isVarArg, |
| 672 | const DataLayout &DL) const override; |
| 673 | |
| 674 | bool isIntDivCheap(EVT VT, AttributeList Attr) const override; |
| 675 | |
| 676 | bool supportSwiftError() const override; |
| 677 | |
| 678 | bool supportKCFIBundles() const override { return true; } |
| 679 | |
| 680 | MachineInstr *EmitKCFICheck(MachineBasicBlock &MBB, |
| 681 | MachineBasicBlock::instr_iterator &MBBI, |
| 682 | const TargetInstrInfo *TII) const override; |
| 683 | |
| 684 | bool hasStackProbeSymbol(const MachineFunction &MF) const override; |
| 685 | bool hasInlineStackProbe(const MachineFunction &MF) const override; |
| 686 | StringRef getStackProbeSymbolName(const MachineFunction &MF) const override; |
| 687 | |
| 688 | unsigned getStackProbeSize(const MachineFunction &MF) const; |
| 689 | |
| 690 | bool hasVectorBlend() const override { return true; } |
| 691 | |
| 692 | unsigned getMaxSupportedInterleaveFactor() const override { return 4; } |
| 693 | |
| 694 | bool isInlineAsmTargetBranch(const SmallVectorImpl<StringRef> &AsmStrs, |
| 695 | unsigned OpNo) const override; |
| 696 | |
| 697 | SDValue visitMaskedLoad(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, |
| 698 | MachineMemOperand *MMO, SDValue &NewLoad, |
| 699 | SDValue Ptr, SDValue PassThru, |
| 700 | SDValue Mask) const override; |
| 701 | SDValue visitMaskedStore(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, |
| 702 | MachineMemOperand *MMO, SDValue Ptr, SDValue Val, |
| 703 | SDValue Mask) const override; |
| 704 | |
| 705 | /// Lower interleaved load(s) into target specific |
| 706 | /// instructions/intrinsics. |
| 707 | bool lowerInterleavedLoad(Instruction *Load, Value *Mask, |
| 708 | ArrayRef<ShuffleVectorInst *> Shuffles, |
| 709 | ArrayRef<unsigned> Indices, unsigned Factor, |
| 710 | const APInt &GapMask) const override; |
| 711 | |
| 712 | /// Lower interleaved store(s) into target specific |
| 713 | /// instructions/intrinsics. |
| 714 | bool lowerInterleavedStore(Instruction *Store, Value *Mask, |
| 715 | ShuffleVectorInst *SVI, unsigned Factor, |
| 716 | const APInt &GapMask) const override; |
| 717 | |
| 718 | SDValue expandIndirectJTBranch(const SDLoc &dl, SDValue Value, SDValue Addr, |
| 719 | int JTI, SelectionDAG &DAG) const override; |
| 720 | |
| 721 | Align getPrefLoopAlignment(MachineLoop *ML) const override; |
| 722 | |
| 723 | EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const override { |
| 724 | if (VT == MVT::f80) |
| 725 | return EVT::getIntegerVT(Context, BitWidth: 96); |
| 726 | return TargetLoweringBase::getTypeToTransformTo(Context, VT); |
| 727 | } |
| 728 | |
| 729 | protected: |
| 730 | std::pair<const TargetRegisterClass *, uint8_t> |
| 731 | findRepresentativeClass(const TargetRegisterInfo *TRI, |
| 732 | MVT VT) const override; |
| 733 | |
| 734 | private: |
| 735 | /// Keep a reference to the X86Subtarget around so that we can |
| 736 | /// make the right decision when generating code for different targets. |
| 737 | const X86Subtarget &Subtarget; |
| 738 | |
| 739 | /// A list of legal FP immediates. |
| 740 | std::vector<APFloat> LegalFPImmediates; |
| 741 | |
| 742 | /// Indicate that this x86 target can instruction |
| 743 | /// select the specified FP immediate natively. |
| 744 | void addLegalFPImmediate(const APFloat& Imm) { |
| 745 | LegalFPImmediates.push_back(x: Imm); |
| 746 | } |
| 747 | |
| 748 | SDValue LowerCallResult(SDValue Chain, SDValue InGlue, |
| 749 | CallingConv::ID CallConv, bool isVarArg, |
| 750 | const SmallVectorImpl<ISD::InputArg> &Ins, |
| 751 | const SDLoc &dl, SelectionDAG &DAG, |
| 752 | SmallVectorImpl<SDValue> &InVals, |
| 753 | uint32_t *RegMask) const; |
| 754 | SDValue LowerMemArgument(SDValue Chain, CallingConv::ID CallConv, |
| 755 | const SmallVectorImpl<ISD::InputArg> &ArgInfo, |
| 756 | const SDLoc &dl, SelectionDAG &DAG, |
| 757 | const CCValAssign &VA, MachineFrameInfo &MFI, |
| 758 | unsigned i) const; |
| 759 | SDValue LowerMemOpCallTo(SDValue Chain, SDValue StackPtr, SDValue Arg, |
| 760 | const SDLoc &dl, SelectionDAG &DAG, |
| 761 | const CCValAssign &VA, |
| 762 | ISD::ArgFlagsTy Flags, bool isByval) const; |
| 763 | |
| 764 | // Call lowering helpers. |
| 765 | |
| 766 | /// Check whether the call is eligible for sibling call optimization. |
| 767 | bool |
| 768 | isEligibleForSiblingCallOpt(TargetLowering::CallLoweringInfo &CLI, |
| 769 | CCState &CCInfo, |
| 770 | SmallVectorImpl<CCValAssign> &ArgLocs) const; |
| 771 | SDValue EmitTailCallLoadRetAddr(SelectionDAG &DAG, SDValue &OutRetAddr, |
| 772 | SDValue Chain, bool IsTailCall, |
| 773 | bool Is64Bit, int FPDiff, |
| 774 | const SDLoc &dl) const; |
| 775 | |
| 776 | unsigned GetAlignedArgumentStackSize(unsigned StackSize, |
| 777 | SelectionDAG &DAG) const; |
| 778 | |
| 779 | unsigned getAddressSpace() const; |
| 780 | |
| 781 | SDValue FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG, bool IsSigned, |
| 782 | SDValue &Chain) const; |
| 783 | SDValue LRINT_LLRINTHelper(SDNode *N, SelectionDAG &DAG) const; |
| 784 | |
| 785 | SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; |
| 786 | SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const; |
| 787 | SDValue (SDValue Op, SelectionDAG &DAG) const; |
| 788 | SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; |
| 789 | |
| 790 | unsigned getGlobalWrapperKind(const GlobalValue *GV, |
| 791 | const unsigned char OpFlags) const; |
| 792 | SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; |
| 793 | SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; |
| 794 | SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; |
| 795 | SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; |
| 796 | SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const; |
| 797 | |
| 798 | /// Creates target global address or external symbol nodes for calls or |
| 799 | /// other uses. |
| 800 | SDValue LowerGlobalOrExternal(SDValue Op, SelectionDAG &DAG, bool ForCall, |
| 801 | bool *IsImpCall) const; |
| 802 | |
| 803 | SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; |
| 804 | SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; |
| 805 | SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const; |
| 806 | SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const; |
| 807 | SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const; |
| 808 | SDValue LowerLRINT_LLRINT(SDValue Op, SelectionDAG &DAG) const; |
| 809 | SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; |
| 810 | SDValue LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const; |
| 811 | SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const; |
| 812 | SDValue LowerConditionalBranch(SDValue Op, SelectionDAG &DAG) const; |
| 813 | SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; |
| 814 | SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; |
| 815 | SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; |
| 816 | SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const; |
| 817 | SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; |
| 818 | SDValue LowerADDROFRETURNADDR(SDValue Op, SelectionDAG &DAG) const; |
| 819 | SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; |
| 820 | SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const; |
| 821 | ByValCopyKind ByValNeedsCopyForTailCall(SelectionDAG &DAG, SDValue Src, |
| 822 | SDValue Dst, |
| 823 | ISD::ArgFlagsTy Flags) const; |
| 824 | SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const; |
| 825 | SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; |
| 826 | SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; |
| 827 | SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const; |
| 828 | SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; |
| 829 | SDValue LowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const; |
| 830 | SDValue LowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const; |
| 831 | SDValue LowerGET_FPENV_MEM(SDValue Op, SelectionDAG &DAG) const; |
| 832 | SDValue LowerSET_FPENV_MEM(SDValue Op, SelectionDAG &DAG) const; |
| 833 | SDValue LowerRESET_FPENV(SDValue Op, SelectionDAG &DAG) const; |
| 834 | SDValue LowerWin64_i128OP(SDValue Op, SelectionDAG &DAG) const; |
| 835 | SDValue LowerWin64_FP_TO_INT128(SDValue Op, SelectionDAG &DAG, |
| 836 | SDValue &Chain) const; |
| 837 | SDValue LowerWin64_INT128_TO_FP(SDValue Op, SelectionDAG &DAG) const; |
| 838 | SDValue LowerGC_TRANSITION(SDValue Op, SelectionDAG &DAG) const; |
| 839 | SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; |
| 840 | SDValue lowerFaddFsub(SDValue Op, SelectionDAG &DAG) const; |
| 841 | SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const; |
| 842 | SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const; |
| 843 | SDValue LowerFP_TO_BF16(SDValue Op, SelectionDAG &DAG) const; |
| 844 | |
| 845 | SDValue |
| 846 | LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
| 847 | const SmallVectorImpl<ISD::InputArg> &Ins, |
| 848 | const SDLoc &dl, SelectionDAG &DAG, |
| 849 | SmallVectorImpl<SDValue> &InVals) const override; |
| 850 | SDValue LowerCall(CallLoweringInfo &CLI, |
| 851 | SmallVectorImpl<SDValue> &InVals) const override; |
| 852 | |
| 853 | SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
| 854 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
| 855 | const SmallVectorImpl<SDValue> &OutVals, |
| 856 | const SDLoc &dl, SelectionDAG &DAG) const override; |
| 857 | |
| 858 | bool supportSplitCSR(MachineFunction *MF) const override { |
| 859 | return MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS && |
| 860 | MF->getFunction().hasFnAttribute(Kind: Attribute::NoUnwind); |
| 861 | } |
| 862 | void initializeSplitCSR(MachineBasicBlock *Entry) const override; |
| 863 | void insertCopiesSplitCSR( |
| 864 | MachineBasicBlock *Entry, |
| 865 | const SmallVectorImpl<MachineBasicBlock *> &Exits) const override; |
| 866 | |
| 867 | bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override; |
| 868 | |
| 869 | bool mayBeEmittedAsTailCall(const CallInst *CI) const override; |
| 870 | |
| 871 | EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, |
| 872 | ISD::NodeType ExtendKind) const override; |
| 873 | |
| 874 | bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, |
| 875 | bool isVarArg, |
| 876 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
| 877 | LLVMContext &Context, |
| 878 | const Type *RetTy) const override; |
| 879 | |
| 880 | const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override; |
| 881 | ArrayRef<MCPhysReg> getRoundingControlRegisters() const override; |
| 882 | |
| 883 | TargetLoweringBase::AtomicExpansionKind |
| 884 | shouldExpandAtomicLoadInIR(LoadInst *LI) const override; |
| 885 | TargetLoweringBase::AtomicExpansionKind |
| 886 | shouldExpandAtomicStoreInIR(StoreInst *SI) const override; |
| 887 | TargetLoweringBase::AtomicExpansionKind |
| 888 | shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override; |
| 889 | TargetLoweringBase::AtomicExpansionKind |
| 890 | shouldExpandLogicAtomicRMWInIR(const AtomicRMWInst *AI) const; |
| 891 | void emitBitTestAtomicRMWIntrinsic(AtomicRMWInst *AI) const override; |
| 892 | void emitCmpArithAtomicRMWIntrinsic(AtomicRMWInst *AI) const override; |
| 893 | |
| 894 | LoadInst * |
| 895 | lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *AI) const override; |
| 896 | |
| 897 | bool needsCmpXchgNb(Type *MemType) const; |
| 898 | |
| 899 | void SetupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, |
| 900 | MachineBasicBlock *DispatchBB, int FI) const; |
| 901 | |
| 902 | // Utility function to emit the low-level va_arg code for X86-64. |
| 903 | MachineBasicBlock * |
| 904 | EmitVAARGWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const; |
| 905 | |
| 906 | /// Utility function to emit the xmm reg save portion of va_start. |
| 907 | MachineBasicBlock *EmitLoweredCascadedSelect(MachineInstr &MI1, |
| 908 | MachineInstr &MI2, |
| 909 | MachineBasicBlock *BB) const; |
| 910 | |
| 911 | MachineBasicBlock *EmitLoweredSelect(MachineInstr &I, |
| 912 | MachineBasicBlock *BB) const; |
| 913 | |
| 914 | MachineBasicBlock *EmitLoweredCatchRet(MachineInstr &MI, |
| 915 | MachineBasicBlock *BB) const; |
| 916 | |
| 917 | MachineBasicBlock *EmitLoweredSegAlloca(MachineInstr &MI, |
| 918 | MachineBasicBlock *BB) const; |
| 919 | |
| 920 | MachineBasicBlock *EmitLoweredProbedAlloca(MachineInstr &MI, |
| 921 | MachineBasicBlock *BB) const; |
| 922 | |
| 923 | MachineBasicBlock *EmitLoweredTLSCall(MachineInstr &MI, |
| 924 | MachineBasicBlock *BB) const; |
| 925 | |
| 926 | MachineBasicBlock *EmitLoweredIndirectThunk(MachineInstr &MI, |
| 927 | MachineBasicBlock *BB) const; |
| 928 | |
| 929 | MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, |
| 930 | MachineBasicBlock *MBB) const; |
| 931 | |
| 932 | void emitSetJmpShadowStackFix(MachineInstr &MI, |
| 933 | MachineBasicBlock *MBB) const; |
| 934 | |
| 935 | MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, |
| 936 | MachineBasicBlock *MBB) const; |
| 937 | |
| 938 | MachineBasicBlock *emitLongJmpShadowStackFix(MachineInstr &MI, |
| 939 | MachineBasicBlock *MBB) const; |
| 940 | |
| 941 | MachineBasicBlock *EmitSjLjDispatchBlock(MachineInstr &MI, |
| 942 | MachineBasicBlock *MBB) const; |
| 943 | |
| 944 | MachineBasicBlock *emitPatchableEventCall(MachineInstr &MI, |
| 945 | MachineBasicBlock *MBB) const; |
| 946 | |
| 947 | /// Emit flags for the given setcc condition and operands. Also returns the |
| 948 | /// corresponding X86 condition code constant in X86CC. |
| 949 | SDValue emitFlagsForSetcc(SDValue Op0, SDValue Op1, ISD::CondCode CC, |
| 950 | const SDLoc &dl, SelectionDAG &DAG, |
| 951 | SDValue &X86CC) const; |
| 952 | |
| 953 | bool optimizeFMulOrFDivAsShiftAddBitcast(SDNode *N, SDValue FPConst, |
| 954 | SDValue IntPow2) const override; |
| 955 | |
| 956 | /// Check if replacement of SQRT with RSQRT should be disabled. |
| 957 | bool isFsqrtCheap(SDValue Op, SelectionDAG &DAG) const override; |
| 958 | |
| 959 | /// Use rsqrt* to speed up sqrt calculations. |
| 960 | SDValue getSqrtEstimate(SDValue Op, SelectionDAG &DAG, int Enabled, |
| 961 | int &RefinementSteps, bool &UseOneConstNR, |
| 962 | bool Reciprocal) const override; |
| 963 | |
| 964 | /// Use rcp* to speed up fdiv calculations. |
| 965 | SDValue getRecipEstimate(SDValue Op, SelectionDAG &DAG, int Enabled, |
| 966 | int &RefinementSteps) const override; |
| 967 | |
| 968 | /// Reassociate floating point divisions into multiply by reciprocal. |
| 969 | unsigned combineRepeatedFPDivisors() const override; |
| 970 | |
| 971 | SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, |
| 972 | SmallVectorImpl<SDNode *> &Created) const override; |
| 973 | |
| 974 | SDValue getMOVL(SelectionDAG &DAG, const SDLoc &dl, MVT VT, SDValue V1, |
| 975 | SDValue V2) const; |
| 976 | }; |
| 977 | |
| 978 | namespace X86 { |
| 979 | FastISel *createFastISel(FunctionLoweringInfo &funcInfo, |
| 980 | const TargetLibraryInfo *libInfo, |
| 981 | const LibcallLoweringInfo *libcallLowering); |
| 982 | } // end namespace X86 |
| 983 | |
| 984 | // X86 specific Gather/Scatter nodes. |
| 985 | // The class has the same order of operands as MaskedGatherScatterSDNode for |
| 986 | // convenience. |
| 987 | class X86MaskedGatherScatterSDNode : public MemIntrinsicSDNode { |
| 988 | public: |
| 989 | // This is a intended as a utility and should never be directly created. |
| 990 | X86MaskedGatherScatterSDNode() = delete; |
| 991 | ~X86MaskedGatherScatterSDNode() = delete; |
| 992 | |
| 993 | const SDValue &getBasePtr() const { return getOperand(Num: 3); } |
| 994 | const SDValue &getIndex() const { return getOperand(Num: 4); } |
| 995 | const SDValue &getMask() const { return getOperand(Num: 2); } |
| 996 | const SDValue &getScale() const { return getOperand(Num: 5); } |
| 997 | |
| 998 | static bool classof(const SDNode *N) { |
| 999 | return N->getOpcode() == X86ISD::MGATHER || |
| 1000 | N->getOpcode() == X86ISD::MSCATTER; |
| 1001 | } |
| 1002 | }; |
| 1003 | |
| 1004 | class X86MaskedGatherSDNode : public X86MaskedGatherScatterSDNode { |
| 1005 | public: |
| 1006 | const SDValue &getPassThru() const { return getOperand(Num: 1); } |
| 1007 | |
| 1008 | static bool classof(const SDNode *N) { |
| 1009 | return N->getOpcode() == X86ISD::MGATHER; |
| 1010 | } |
| 1011 | }; |
| 1012 | |
| 1013 | class X86MaskedScatterSDNode : public X86MaskedGatherScatterSDNode { |
| 1014 | public: |
| 1015 | const SDValue &getValue() const { return getOperand(Num: 1); } |
| 1016 | |
| 1017 | static bool classof(const SDNode *N) { |
| 1018 | return N->getOpcode() == X86ISD::MSCATTER; |
| 1019 | } |
| 1020 | }; |
| 1021 | |
| 1022 | /// Generate unpacklo/unpackhi shuffle mask. |
| 1023 | void createUnpackShuffleMask(EVT VT, SmallVectorImpl<int> &Mask, bool Lo, |
| 1024 | bool Unary); |
| 1025 | |
| 1026 | /// Similar to unpacklo/unpackhi, but without the 128-bit lane limitation |
| 1027 | /// imposed by AVX and specific to the unary pattern. Example: |
| 1028 | /// v8iX Lo --> <0, 0, 1, 1, 2, 2, 3, 3> |
| 1029 | /// v8iX Hi --> <4, 4, 5, 5, 6, 6, 7, 7> |
| 1030 | void createSplat2ShuffleMask(MVT VT, SmallVectorImpl<int> &Mask, bool Lo); |
| 1031 | |
| 1032 | } // end namespace llvm |
| 1033 | |
| 1034 | #endif // LLVM_LIB_TARGET_X86_X86ISELLOWERING_H |
| 1035 | |