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