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