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
21namespace 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 preferZeroCompareBranch() const override;
242
243 bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const override {
244 // If the pair to store is a mixture of float and int values, we will
245 // save two bitwise instructions and one float-to-int instruction and
246 // increase one store instruction. There is potentially a more
247 // significant benefit because it avoids the float->int domain switch
248 // for input value. So It is more likely a win.
249 if ((LTy.isFloatingPoint() && HTy.isInteger()) ||
250 (LTy.isInteger() && HTy.isFloatingPoint()))
251 return true;
252 // If the pair only contains int values, we will save two bitwise
253 // instructions and increase one store instruction (costing one more
254 // store buffer). Since the benefit is more blurred so we leave
255 // such pair out until we get testcase to prove it is a win.
256 return false;
257 }
258
259 bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;
260
261 bool hasAndNotCompare(SDValue Y) const override;
262
263 bool hasAndNot(SDValue Y) const override;
264
265 bool hasBitTest(SDValue X, SDValue Y) const override;
266
267 bool shouldProduceAndByConstByHoistingConstFromShiftsLHSOfAnd(
268 SDValue X, ConstantSDNode *XC, ConstantSDNode *CC, SDValue Y,
269 unsigned OldShiftOpcode, unsigned NewShiftOpcode,
270 SelectionDAG &DAG) const override;
271
272 unsigned preferedOpcodeForCmpEqPiecesOfOperand(
273 EVT VT, unsigned ShiftOpc, bool MayTransformRotate,
274 const APInt &ShiftOrRotateAmt,
275 const std::optional<APInt> &AndMask) const override;
276
277 bool preferIncOfAddToSubOfNot(EVT VT) const override;
278
279 bool preferScalarizeSplat(SDNode *N) const override;
280
281 CondMergingParams
282 getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs,
283 const Value *Rhs,
284 const Function *F) const override;
285
286 bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override;
287
288 bool shouldFoldMaskToVariableShiftPair(SDValue Y) const override;
289
290 bool
291 shouldTransformSignedTruncationCheck(EVT XVT,
292 unsigned KeptBits) const override {
293 // For vectors, we don't have a preference..
294 if (XVT.isVector())
295 return false;
296
297 auto VTIsOk = [](EVT VT) -> bool {
298 return VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32 ||
299 VT == MVT::i64;
300 };
301
302 // We are ok with KeptBitsVT being byte/word/dword, what MOVS supports.
303 // XVT will be larger than KeptBitsVT.
304 MVT KeptBitsVT = MVT::getIntegerVT(BitWidth: KeptBits);
305 return VTIsOk(XVT) && VTIsOk(KeptBitsVT);
306 }
307
308 ShiftLegalizationStrategy
309 preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N,
310 unsigned ExpansionFactor) const override;
311
312 bool shouldSplatInsEltVarIndex(EVT VT) const override;
313
314 bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override {
315 // Converting to sat variants holds little benefit on X86 as we will just
316 // need to saturate the value back using fp arithmatic.
317 return Op != ISD::FP_TO_UINT_SAT && isOperationLegalOrCustom(Op, VT);
318 }
319
320 bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
321 return VT.isScalarInteger();
322 }
323
324 /// Vector-sized comparisons are fast using PCMPEQ + PMOVMSK or PTEST.
325 MVT hasFastEqualityCompare(unsigned NumBits) const override;
326
327 /// Return the value type to use for ISD::SETCC.
328 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
329 EVT VT) const override;
330
331 bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,
332 const APInt &DemandedElts,
333 TargetLoweringOpt &TLO) const override;
334
335 /// Determine which of the bits specified in Mask are known to be either
336 /// zero or one and return them in the KnownZero/KnownOne bitsets.
337 void computeKnownBitsForTargetNode(const SDValue Op,
338 KnownBits &Known,
339 const APInt &DemandedElts,
340 const SelectionDAG &DAG,
341 unsigned Depth = 0) const override;
342
343 /// Determine the number of bits in the operation that are sign bits.
344 unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
345 const APInt &DemandedElts,
346 const SelectionDAG &DAG,
347 unsigned Depth) const override;
348
349 bool SimplifyDemandedVectorEltsForTargetNode(SDValue Op,
350 const APInt &DemandedElts,
351 APInt &KnownUndef,
352 APInt &KnownZero,
353 TargetLoweringOpt &TLO,
354 unsigned Depth) const override;
355
356 bool SimplifyDemandedVectorEltsForTargetShuffle(SDValue Op,
357 const APInt &DemandedElts,
358 unsigned MaskIndex,
359 TargetLoweringOpt &TLO,
360 unsigned Depth) const;
361
362 unsigned getPreferredShrunkVectorSizeInBits(
363 SDValue Op, const APInt &DemandedElts) const override;
364
365 bool SimplifyDemandedBitsForTargetNode(SDValue Op,
366 const APInt &DemandedBits,
367 const APInt &DemandedElts,
368 KnownBits &Known,
369 TargetLoweringOpt &TLO,
370 unsigned Depth) const override;
371
372 SDValue SimplifyMultipleUseDemandedBitsForTargetNode(
373 SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
374 SelectionDAG &DAG, unsigned Depth) const override;
375
376 bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(
377 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
378 UndefPoisonKind Kind, unsigned Depth) const override;
379
380 bool canCreateUndefOrPoisonForTargetNode(SDValue Op,
381 const APInt &DemandedElts,
382 const SelectionDAG &DAG,
383 UndefPoisonKind Kind,
384 bool ConsiderFlags,
385 unsigned Depth) const override;
386
387 bool isSplatValueForTargetNode(SDValue Op, const APInt &DemandedElts,
388 APInt &UndefElts, const SelectionDAG &DAG,
389 unsigned Depth) const override;
390
391 bool isTargetCanonicalConstantNode(SDValue Op) const override {
392 // Peek through bitcasts/extracts/inserts to see if we have a vector
393 // load/broadcast from memory.
394 while (Op.getOpcode() == ISD::BITCAST ||
395 Op.getOpcode() == ISD::EXTRACT_SUBVECTOR ||
396 (Op.getOpcode() == ISD::INSERT_SUBVECTOR &&
397 Op.getOperand(i: 0).isUndef()))
398 Op = Op.getOperand(i: Op.getOpcode() == ISD::INSERT_SUBVECTOR ? 1 : 0);
399
400 return Op.getOpcode() == X86ISD::VBROADCAST_LOAD ||
401 Op.getOpcode() == X86ISD::SUBV_BROADCAST_LOAD ||
402 (Op.getOpcode() == ISD::LOAD &&
403 getTargetConstantFromLoad(LD: cast<LoadSDNode>(Val&: Op))) ||
404 TargetLowering::isTargetCanonicalConstantNode(Op);
405 }
406
407 bool isTargetCanonicalSelect(SDNode *N) const override;
408
409 const Constant *getTargetConstantFromLoad(LoadSDNode *LD) const override;
410
411 SDValue unwrapAddress(SDValue N) const override;
412
413 SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const;
414
415 ConstraintType getConstraintType(StringRef Constraint) const override;
416
417 /// Examine constraint string and operand type and determine a weight value.
418 /// The operand object must already have been set up with the operand type.
419 ConstraintWeight
420 getSingleConstraintMatchWeight(AsmOperandInfo &Info,
421 const char *Constraint) const override;
422
423 const char *LowerXConstraint(EVT ConstraintVT) const override;
424
425 /// Lower the specified operand into the Ops vector. If it is invalid, don't
426 /// add anything to Ops. If hasMemory is true it means one of the asm
427 /// constraint of the inline asm instruction being processed is 'm'.
428 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
429 std::vector<SDValue> &Ops,
430 SelectionDAG &DAG) const override;
431
432 InlineAsm::ConstraintCode
433 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
434 if (ConstraintCode == "v")
435 return InlineAsm::ConstraintCode::v;
436 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
437 }
438
439 /// Handle Lowering flag assembly outputs.
440 SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag,
441 const SDLoc &DL,
442 const AsmOperandInfo &Constraint,
443 SelectionDAG &DAG) const override;
444
445 /// Given a physical register constraint
446 /// (e.g. {edx}), return the register number and the register class for the
447 /// register. This should only be used for C_Register constraints. On
448 /// error, this returns a register number of 0.
449 std::pair<unsigned, const TargetRegisterClass *>
450 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
451 StringRef Constraint, MVT VT) const override;
452
453 /// Return true if the addressing mode represented
454 /// by AM is legal for this target, for a load/store of the specified type.
455 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
456 Type *Ty, unsigned AS,
457 Instruction *I = nullptr) const override;
458
459 bool addressingModeSupportsTLS(const GlobalValue &GV) const override;
460
461 /// Return true if the specified immediate is legal
462 /// icmp immediate, that is the target has icmp instructions which can
463 /// compare a register against the immediate without having to materialize
464 /// the immediate into a register.
465 bool isLegalICmpImmediate(int64_t Imm) const override;
466
467 /// Return true if the specified immediate is legal
468 /// add immediate, that is the target has add instructions which can
469 /// add a register and the immediate without having to materialize
470 /// the immediate into a register.
471 bool isLegalAddImmediate(int64_t Imm) const override;
472
473 bool isLegalStoreImmediate(int64_t Imm) const override;
474
475 /// Add x86-specific opcodes to the default list.
476 bool isBinOp(unsigned Opcode) const override;
477
478 /// Returns true if the opcode is a commutative binary operation.
479 bool isCommutativeBinOp(unsigned Opcode) const override;
480
481 /// Return true if it's free to truncate a value of
482 /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in
483 /// register EAX to i16 by referencing its sub-register AX.
484 bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
485 bool isTruncateFree(EVT VT1, EVT VT2) const override;
486
487 bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
488
489 /// Return true if any actual instruction that defines a
490 /// value of type Ty1 implicit zero-extends the value to Ty2 in the result
491 /// register. This does not necessarily include registers defined in
492 /// unknown ways, such as incoming arguments, or copies from unknown
493 /// virtual registers. Also, if isTruncateFree(Ty2, Ty1) is true, this
494 /// does not necessarily apply to truncate instructions. e.g. on x86-64,
495 /// all instructions that define 32-bit values implicit zero-extend the
496 /// result out to 64 bits.
497 bool isZExtFree(Type *Ty1, Type *Ty2) const override;
498 bool isZExtFree(EVT VT1, EVT VT2) const override;
499 bool isZExtFree(SDValue Val, EVT VT2) const override;
500
501 bool shouldConvertPhiType(Type *From, Type *To) const override;
502
503 /// Return true if folding a vector load into ExtVal (a sign, zero, or any
504 /// extend node) is profitable.
505 bool isVectorLoadExtDesirable(SDValue) const override;
506
507 /// Return true if an FMA operation is faster than a pair of fmul and fadd
508 /// instructions. fmuladd intrinsics will be expanded to FMAs when this
509 /// method returns true, otherwise fmuladd is expanded to fmul + fadd.
510 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
511 EVT VT) const override;
512
513 /// Return true if it's profitable to narrow operations of type SrcVT to
514 /// DestVT. e.g. on x86, it's profitable to narrow from i32 to i8 but not
515 /// from i32 to i16.
516 bool isNarrowingProfitable(SDNode *N, EVT SrcVT, EVT DestVT) const override;
517
518 bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT,
519 unsigned SelectOpcode, SDValue X,
520 SDValue Y) const override;
521
522 /// Given an intrinsic, checks if on the target the intrinsic will need to
523 /// map to a MemIntrinsicNode (touches memory). If this is the case, it
524 /// returns true and stores the intrinsic information into the IntrinsicInfo
525 /// that was passed to the function.
526 void getTgtMemIntrinsic(SmallVectorImpl<IntrinsicInfo> &Infos,
527 const CallBase &I, MachineFunction &MF,
528 unsigned Intrinsic) const override;
529
530 /// Returns true if the target can instruction select the
531 /// specified FP immediate natively. If false, the legalizer will
532 /// materialize the FP immediate as a load from a constant pool.
533 bool isFPImmLegal(const APFloat &Imm, EVT VT,
534 bool ForCodeSize) const override;
535
536 /// Targets can use this to indicate that they only support *some*
537 /// VECTOR_SHUFFLE operations, those with specific masks. By default, if a
538 /// target supports the VECTOR_SHUFFLE node, all mask values are assumed to
539 /// be legal.
540 bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override;
541
542 /// Similar to isShuffleMaskLegal. Targets can use this to indicate if there
543 /// is a suitable VECTOR_SHUFFLE that can be used to replace a VAND with a
544 /// constant pool entry.
545 bool isVectorClearMaskLegal(ArrayRef<int> Mask, EVT VT) const override;
546
547 /// Returns true if lowering to a jump table is allowed.
548 bool areJTsAllowed(const Function *Fn) const override;
549
550 MVT getPreferredSwitchConditionType(LLVMContext &Context,
551 EVT ConditionVT) const override;
552
553 /// If true, then instruction selection should
554 /// seek to shrink the FP constant of the specified type to a smaller type
555 /// in order to save space and / or reduce runtime.
556 bool ShouldShrinkFPConstant(EVT VT) const override;
557
558 /// Return true if we believe it is correct and profitable to reduce the
559 /// load node to a smaller type.
560 bool
561 shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT,
562 std::optional<unsigned> ByteOffset) const override;
563
564 /// Return true if the specified scalar FP type is computed in an SSE
565 /// register, not on the X87 floating point stack.
566 bool isScalarFPTypeInSSEReg(EVT VT) const;
567
568 /// Returns true if it is beneficial to convert a load of a constant
569 /// to just the constant itself.
570 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
571 Type *Ty) const override;
572
573 bool reduceSelectOfFPConstantLoads(EVT CmpOpVT) const override;
574
575 bool convertSelectOfConstantsToMath(EVT VT) const override;
576
577 bool shouldNormalizeToSelectSequence(LLVMContext &Context, EVT VT,
578 EVT CCVT) const override;
579
580 bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
581 SDValue C) const override;
582
583 /// Return the cost of EXTRACT_SUBVECTOR for this result type with this
584 /// index.
585 ExtractSubvectorCost getExtractSubvectorCost(EVT ResVT, EVT SrcVT,
586 unsigned Index) const override;
587
588 /// Scalar ops always have equal or better analysis/performance/power than
589 /// the vector equivalent, so this always makes sense if the scalar op is
590 /// supported.
591 bool shouldScalarizeBinop(SDValue) const override;
592
593 /// Extract of a scalar FP value from index 0 of a vector is free.
594 bool isExtractVecEltCheap(EVT VT, unsigned Index) const override {
595 EVT EltVT = VT.getScalarType();
596 return (EltVT == MVT::f32 || EltVT == MVT::f64) && Index == 0;
597 }
598
599 /// Overflow nodes should get combined/lowered to optimal instructions
600 /// (they should allow eliminating explicit compares by getting flags from
601 /// math ops).
602 bool shouldFormOverflowOp(unsigned Opcode, EVT VT,
603 bool MathUsed) const override;
604
605 bool storeOfVectorConstantIsCheap(bool IsZero, EVT MemVT, unsigned NumElem,
606 unsigned AddrSpace) const override {
607 // If we can replace more than 2 scalar stores, there will be a reduction
608 // in instructions even after we add a vector constant load.
609 return IsZero || NumElem > 2;
610 }
611
612 bool isLoadBitCastBeneficial(EVT LoadVT, EVT BitcastVT,
613 const SelectionDAG &DAG,
614 const MachineMemOperand &MMO) const override;
615
616 bool isProfitableToCombineMinNumMaxNum(EVT VT) const override {
617 // X86 has instructions that correspond to cmp + select, so forming
618 // minnum/maxnum is not profitable.
619 return false;
620 }
621
622 Register getRegisterByName(const char* RegName, LLT VT,
623 const MachineFunction &MF) const override;
624
625 /// If a physical register, this returns the register that receives the
626 /// exception address on entry to an EH pad.
627 Register
628 getExceptionPointerRegister(ExceptionHandling EH,
629 const Constant *PersonalityFn) const override;
630
631 /// If a physical register, this returns the register that receives the
632 /// exception typeid on entry to a landing pad.
633 Register
634 getExceptionSelectorRegister(ExceptionHandling EH,
635 const Constant *PersonalityFn) const override;
636
637 bool needsFixedCatchObjects() const override;
638
639 /// This method returns a target specific FastISel object,
640 /// or null if the target does not support "fast" ISel.
641 FastISel *
642 createFastISel(FunctionLoweringInfo &funcInfo,
643 const TargetLibraryInfo *libInfo,
644 const LibcallLoweringInfo *libcallLowering) const override;
645
646 /// If the target has a standard location for the stack protector cookie,
647 /// returns the address of that location. Otherwise, returns nullptr.
648 Value *getIRStackGuard(IRBuilderBase &IRB,
649 const LibcallLoweringInfo &Libcalls) const override;
650
651 bool useLoadStackGuardNode(const Module &M) const override;
652 bool useStackGuardMixFP() const override;
653 void
654 insertSSPDeclarations(Module &M,
655 const LibcallLoweringInfo &Libcalls) const override;
656 SDValue emitStackGuardMixFP(SelectionDAG &DAG, SDValue Val,
657 const SDLoc &DL) const override;
658
659 /// Return true if the target stores SafeStack pointer at a fixed offset in
660 /// some non-standard address space, and populates the address space and
661 /// offset as appropriate.
662 Value *getSafeStackPointerLocation(
663 IRBuilderBase &IRB, const LibcallLoweringInfo &Libcalls) const override;
664
665 std::pair<SDValue, SDValue> BuildFILD(EVT DstVT, EVT SrcVT, const SDLoc &DL,
666 SDValue Chain, SDValue Pointer,
667 MachinePointerInfo PtrInfo,
668 Align Alignment,
669 SelectionDAG &DAG) const;
670
671 /// Customize the preferred legalization strategy for certain types.
672 LegalizeTypeAction getPreferredVectorAction(MVT VT) const override;
673
674 MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
675 EVT VT) const override;
676
677 unsigned getNumRegistersForCallingConv(LLVMContext &Context,
678 CallingConv::ID CC,
679 EVT VT) const override;
680
681 unsigned getVectorTypeBreakdownForCallingConv(
682 LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
683 unsigned &NumIntermediates, MVT &RegisterVT) const override;
684
685 bool functionArgumentNeedsConsecutiveRegisters(
686 Type *Ty, CallingConv::ID CallConv, bool isVarArg,
687 const DataLayout &DL) const override;
688
689 bool isIntDivCheap(EVT VT, AttributeList Attr) const override;
690
691 bool supportSwiftError() const override;
692
693 bool supportKCFIBundles() const override { return true; }
694
695 MachineInstr *EmitKCFICheck(MachineBasicBlock &MBB,
696 MachineBasicBlock::instr_iterator &MBBI,
697 const TargetInstrInfo *TII) const override;
698
699 bool hasStackProbeSymbol(const MachineFunction &MF) const override;
700 bool hasInlineStackProbe(const MachineFunction &MF) const override;
701 StringRef getStackProbeSymbolName(const MachineFunction &MF) const override;
702
703 unsigned getStackProbeSize(const MachineFunction &MF) const;
704
705 bool hasVectorBlend() const override { return true; }
706
707 unsigned getMaxSupportedInterleaveFactor() const override { return 4; }
708
709 bool isInlineAsmTargetBranch(const SmallVectorImpl<StringRef> &AsmStrs,
710 unsigned OpNo) const override;
711
712 SDValue visitMaskedLoad(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
713 MachineMemOperand *MMO, SDValue &NewLoad,
714 SDValue Ptr, SDValue PassThru,
715 SDValue Mask) const override;
716 SDValue visitMaskedStore(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
717 MachineMemOperand *MMO, SDValue Ptr, SDValue Val,
718 SDValue Mask) const override;
719
720 /// Lower interleaved load(s) into target specific
721 /// instructions/intrinsics.
722 bool lowerInterleavedLoad(Instruction *Load, Value *Mask,
723 ArrayRef<ShuffleVectorInst *> Shuffles,
724 ArrayRef<unsigned> Indices, unsigned Factor,
725 const APInt &GapMask) const override;
726
727 /// Lower interleaved store(s) into target specific
728 /// instructions/intrinsics.
729 bool lowerInterleavedStore(Instruction *Store, Value *Mask,
730 ShuffleVectorInst *SVI, unsigned Factor,
731 const APInt &GapMask) const override;
732
733 SDValue expandIndirectJTBranch(const SDLoc &dl, SDValue Value, SDValue Addr,
734 int JTI, SelectionDAG &DAG) const override;
735
736 Align
737 getPrefLoopAlignment(MachineLoop *ML,
738 const MachineBasicBlock *BlockToAlign) const override;
739
740 EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const override {
741 if (VT == MVT::f80)
742 return EVT::getIntegerVT(Context, BitWidth: 96);
743 return TargetLoweringBase::getTypeToTransformTo(Context, VT);
744 }
745
746 /// Return true if \p VT has the rsqrt* based estimate of the square root,
747 /// or of its reciprocal if \p Reciprocal is set.
748 bool hasSqrtEstimate(EVT VT, bool Reciprocal) const;
749
750 protected:
751 std::pair<const TargetRegisterClass *, uint8_t>
752 findRepresentativeClass(const TargetRegisterInfo *TRI,
753 MVT VT) const override;
754
755 private:
756 /// Keep a reference to the X86Subtarget around so that we can
757 /// make the right decision when generating code for different targets.
758 const X86Subtarget &Subtarget;
759
760 /// A list of legal FP immediates.
761 std::vector<APFloat> LegalFPImmediates;
762
763 /// Indicate that this x86 target can instruction
764 /// select the specified FP immediate natively.
765 void addLegalFPImmediate(const APFloat& Imm) {
766 LegalFPImmediates.push_back(x: Imm);
767 }
768
769 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
770 CallingConv::ID CallConv, bool isVarArg,
771 const SmallVectorImpl<ISD::InputArg> &Ins,
772 const SDLoc &dl, SelectionDAG &DAG,
773 SmallVectorImpl<SDValue> &InVals,
774 uint32_t *RegMask) const;
775 SDValue LowerMemArgument(SDValue Chain, CallingConv::ID CallConv,
776 const SmallVectorImpl<ISD::InputArg> &ArgInfo,
777 const SDLoc &dl, SelectionDAG &DAG,
778 const CCValAssign &VA, MachineFrameInfo &MFI,
779 unsigned i) const;
780 SDValue LowerMemOpCallTo(SDValue Chain, SDValue StackPtr, SDValue Arg,
781 const SDLoc &dl, SelectionDAG &DAG,
782 const CCValAssign &VA,
783 ISD::ArgFlagsTy Flags, bool isByval) const;
784
785 // Call lowering helpers.
786
787 /// Check whether the call is eligible for sibling call optimization.
788 bool
789 isEligibleForSiblingCallOpt(TargetLowering::CallLoweringInfo &CLI,
790 CCState &CCInfo,
791 SmallVectorImpl<CCValAssign> &ArgLocs) const;
792 SDValue EmitTailCallLoadRetAddr(SelectionDAG &DAG, SDValue &OutRetAddr,
793 SDValue Chain, bool IsTailCall,
794 bool Is64Bit, int FPDiff,
795 const SDLoc &dl) const;
796
797 unsigned GetAlignedArgumentStackSize(unsigned StackSize,
798 SelectionDAG &DAG) const;
799
800 unsigned getAddressSpace() const;
801
802 SDValue FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG, bool IsSigned,
803 SDValue &Chain) const;
804 SDValue LRINT_LLRINTHelper(SDNode *N, SelectionDAG &DAG) const;
805
806 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
807 SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
808 SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
809 SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
810
811 unsigned getGlobalWrapperKind(const GlobalValue *GV,
812 const unsigned char OpFlags) const;
813 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
814 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
815 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
816 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
817 SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const;
818
819 /// Creates target global address or external symbol nodes for calls or
820 /// other uses.
821 SDValue LowerGlobalOrExternal(SDValue Op, SelectionDAG &DAG, bool ForCall,
822 bool *IsImpCall) const;
823
824 SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
825 SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
826 SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const;
827 SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
828 SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const;
829 SDValue LowerLRINT_LLRINT(SDValue Op, SelectionDAG &DAG) const;
830 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
831 SDValue LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const;
832 SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
833 SDValue LowerConditionalBranch(SDValue Op, SelectionDAG &DAG) const;
834 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
835 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
836 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
837 SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const;
838 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
839 SDValue LowerADDROFRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
840 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
841 SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const;
842 ByValCopyKind ByValNeedsCopyForTailCall(SelectionDAG &DAG, SDValue Src,
843 SDValue Dst,
844 ISD::ArgFlagsTy Flags) const;
845 SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
846 SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
847 SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
848 SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;
849 SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
850 SDValue LowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
851 SDValue LowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
852 SDValue LowerGET_FPENV_MEM(SDValue Op, SelectionDAG &DAG) const;
853 SDValue LowerSET_FPENV_MEM(SDValue Op, SelectionDAG &DAG) const;
854 SDValue LowerRESET_FPENV(SDValue Op, SelectionDAG &DAG) const;
855 SDValue LowerWin64_i128OP(SDValue Op, SelectionDAG &DAG) const;
856 SDValue LowerWin64_FP_TO_INT128(SDValue Op, SelectionDAG &DAG,
857 SDValue &Chain) const;
858 SDValue LowerWin64_INT128_TO_FP(SDValue Op, SelectionDAG &DAG) const;
859 SDValue LowerGC_TRANSITION(SDValue Op, SelectionDAG &DAG) const;
860 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
861 SDValue lowerFaddFsub(SDValue Op, SelectionDAG &DAG) const;
862 SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
863 SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
864 SDValue LowerBF16_TO_FP(SDValue Op, SelectionDAG &DAG) const;
865 SDValue LowerFP_TO_BF16(SDValue Op, SelectionDAG &DAG) const;
866
867 SDValue
868 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
869 const SmallVectorImpl<ISD::InputArg> &Ins,
870 const SDLoc &dl, SelectionDAG &DAG,
871 SmallVectorImpl<SDValue> &InVals) const override;
872 SDValue LowerCall(CallLoweringInfo &CLI,
873 SmallVectorImpl<SDValue> &InVals) const override;
874
875 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
876 const SmallVectorImpl<ISD::OutputArg> &Outs,
877 const SmallVectorImpl<SDValue> &OutVals,
878 const SDLoc &dl, SelectionDAG &DAG) const override;
879
880 bool supportSplitCSR(MachineFunction *MF) const override {
881 return MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS &&
882 MF->getFunction().hasFnAttribute(Kind: Attribute::NoUnwind);
883 }
884 void initializeSplitCSR(MachineBasicBlock *Entry) const override;
885 void insertCopiesSplitCSR(
886 MachineBasicBlock *Entry,
887 const SmallVectorImpl<MachineBasicBlock *> &Exits) const override;
888
889 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
890
891 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
892
893 EVT getTypeForExtReturn(LLVMContext &Context, EVT VT,
894 ISD::NodeType ExtendKind) const override;
895
896 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
897 bool isVarArg,
898 const SmallVectorImpl<ISD::OutputArg> &Outs,
899 LLVMContext &Context,
900 const Type *RetTy) const override;
901
902 const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
903 ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
904
905 TargetLoweringBase::AtomicExpansionKind
906 shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
907
908 TargetLoweringBase::AtomicExpansionKind
909 shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
910 TargetLoweringBase::AtomicExpansionKind
911 shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override;
912 TargetLoweringBase::AtomicExpansionKind
913 shouldExpandLogicAtomicRMWInIR(const AtomicRMWInst *AI) const;
914 void emitBitTestAtomicRMWIntrinsic(AtomicRMWInst *AI) const override;
915 void emitCmpArithAtomicRMWIntrinsic(AtomicRMWInst *AI) const override;
916
917 LoadInst *
918 lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *AI) const override;
919
920 bool shouldIssueAtomicLoadForAtomicEmulationLoop() const override {
921 return false;
922 }
923
924 bool needsCmpXchgNb(Type *MemType) const;
925
926 void SetupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB,
927 MachineBasicBlock *DispatchBB, int FI) const;
928
929 // Utility function to emit the low-level va_arg code for X86-64.
930 MachineBasicBlock *
931 EmitVAARGWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const;
932
933 /// Utility function to emit the xmm reg save portion of va_start.
934 MachineBasicBlock *EmitLoweredCascadedSelect(MachineInstr &MI1,
935 MachineInstr &MI2,
936 MachineBasicBlock *BB) const;
937
938 MachineBasicBlock *EmitLoweredSelect(MachineInstr &I,
939 MachineBasicBlock *BB) const;
940
941 MachineBasicBlock *EmitLoweredCatchRet(MachineInstr &MI,
942 MachineBasicBlock *BB) const;
943
944 MachineBasicBlock *EmitLoweredSegAlloca(MachineInstr &MI,
945 MachineBasicBlock *BB) const;
946
947 MachineBasicBlock *EmitLoweredProbedAlloca(MachineInstr &MI,
948 MachineBasicBlock *BB) const;
949
950 MachineBasicBlock *EmitLoweredTLSCall(MachineInstr &MI,
951 MachineBasicBlock *BB) const;
952
953 MachineBasicBlock *EmitLoweredIndirectThunk(MachineInstr &MI,
954 MachineBasicBlock *BB) const;
955
956 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
957 MachineBasicBlock *MBB) const;
958
959 void emitSetJmpShadowStackFix(MachineInstr &MI,
960 MachineBasicBlock *MBB) const;
961
962 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,
963 MachineBasicBlock *MBB) const;
964
965 MachineBasicBlock *emitLongJmpShadowStackFix(MachineInstr &MI,
966 MachineBasicBlock *MBB) const;
967
968 MachineBasicBlock *EmitSjLjDispatchBlock(MachineInstr &MI,
969 MachineBasicBlock *MBB) const;
970
971 MachineBasicBlock *emitPatchableEventCall(MachineInstr &MI,
972 MachineBasicBlock *MBB) const;
973
974 /// Emit flags for the given setcc condition and operands. Also returns the
975 /// corresponding X86 condition code constant in X86CC.
976 SDValue emitFlagsForSetcc(SDValue Op0, SDValue Op1, ISD::CondCode CC,
977 const SDLoc &dl, SelectionDAG &DAG,
978 SDValue &X86CC) const;
979
980 bool optimizeFMulOrFDivAsShiftAddBitcast(SDNode *N, SDValue FPConst,
981 SDValue IntPow2) const override;
982
983 /// Check if replacement of SQRT with RSQRT should be disabled.
984 bool isFsqrtCheap(SDValue Op, SelectionDAG &DAG) const override;
985
986 /// Use rsqrt* to speed up sqrt calculations.
987 SDValue getSqrtEstimate(SDValue Op, SelectionDAG &DAG, int Enabled,
988 int &RefinementSteps, bool &UseOneConstNR,
989 bool Reciprocal) const override;
990
991 /// Use rcp* to speed up fdiv calculations.
992 SDValue getRecipEstimate(SDValue Op, SelectionDAG &DAG, int Enabled,
993 int &RefinementSteps) const override;
994
995 /// Reassociate floating point divisions into multiply by reciprocal.
996 unsigned combineRepeatedFPDivisors() const override;
997
998 SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
999 SmallVectorImpl<SDNode *> &Created) const override;
1000
1001 SDValue getMOVL(SelectionDAG &DAG, const SDLoc &dl, MVT VT, SDValue V1,
1002 SDValue V2) const;
1003 };
1004
1005 namespace X86 {
1006 FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
1007 const TargetLibraryInfo *libInfo,
1008 const LibcallLoweringInfo *libcallLowering);
1009 } // end namespace X86
1010
1011 // X86 specific Gather/Scatter nodes.
1012 // The class has the same order of operands as MaskedGatherScatterSDNode for
1013 // convenience.
1014 class X86MaskedGatherScatterSDNode : public MemIntrinsicSDNode {
1015 public:
1016 // This is a intended as a utility and should never be directly created.
1017 X86MaskedGatherScatterSDNode() = delete;
1018 ~X86MaskedGatherScatterSDNode() = delete;
1019
1020 const SDValue &getBasePtr() const { return getOperand(Num: 3); }
1021 const SDValue &getIndex() const { return getOperand(Num: 4); }
1022 const SDValue &getMask() const { return getOperand(Num: 2); }
1023 const SDValue &getScale() const { return getOperand(Num: 5); }
1024
1025 static bool classof(const SDNode *N) {
1026 return N->getOpcode() == X86ISD::MGATHER ||
1027 N->getOpcode() == X86ISD::MSCATTER;
1028 }
1029 };
1030
1031 class X86MaskedGatherSDNode : public X86MaskedGatherScatterSDNode {
1032 public:
1033 const SDValue &getPassThru() const { return getOperand(Num: 1); }
1034
1035 static bool classof(const SDNode *N) {
1036 return N->getOpcode() == X86ISD::MGATHER;
1037 }
1038 };
1039
1040 class X86MaskedScatterSDNode : public X86MaskedGatherScatterSDNode {
1041 public:
1042 const SDValue &getValue() const { return getOperand(Num: 1); }
1043
1044 static bool classof(const SDNode *N) {
1045 return N->getOpcode() == X86ISD::MSCATTER;
1046 }
1047 };
1048
1049 /// Generate unpacklo/unpackhi shuffle mask.
1050 void createUnpackShuffleMask(EVT VT, SmallVectorImpl<int> &Mask, bool Lo,
1051 bool Unary);
1052
1053 /// Similar to unpacklo/unpackhi, but without the 128-bit lane limitation
1054 /// imposed by AVX and specific to the unary pattern. Example:
1055 /// v8iX Lo --> <0, 0, 1, 1, 2, 2, 3, 3>
1056 /// v8iX Hi --> <4, 4, 5, 5, 6, 6, 7, 7>
1057 void createSplat2ShuffleMask(MVT VT, SmallVectorImpl<int> &Mask, bool Lo);
1058
1059} // end namespace llvm
1060
1061#endif // LLVM_LIB_TARGET_X86_X86ISELLOWERING_H
1062