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