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