22#include "llvm/Config/llvm-config.h"
27#include "llvm/IR/IntrinsicsX86.h"
39#define DEBUG_TYPE "x86-isel"
40#define PASS_NAME "X86 DAG->DAG Instruction Selection"
42STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
51 struct X86ISelAddressMode {
59 int Base_FrameIndex = 0;
65 const GlobalValue *GV =
nullptr;
68 const char *ES =
nullptr;
73 bool NegateIndex =
false;
78 bool IsForLEA =
false;
80 X86ISelAddressMode() =
default;
82 bool hasSymbolicDisplacement()
const {
83 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr ||
84 MCSym !=
nullptr || JT != -1 || BlockAddr !=
nullptr;
87 bool hasBaseOrIndexReg()
const {
88 return BaseType == FrameIndexBase ||
89 IndexReg.getNode() !=
nullptr || Base_Reg.getNode() !=
nullptr;
94 if (BaseType != RegBase)
return false;
95 if (RegisterSDNode *RegNode =
97 return RegNode->getReg() == X86::RIP;
101 void setBaseReg(SDValue
Reg) {
106#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
107 void dump(SelectionDAG *DAG =
nullptr) {
108 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
109 dbgs() <<
"Base_Reg ";
110 if (Base_Reg.getNode())
111 Base_Reg.getNode()->dump(DAG);
114 if (BaseType == FrameIndexBase)
115 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
116 dbgs() <<
" Scale " << Scale <<
'\n'
120 if (IndexReg.getNode())
121 IndexReg.getNode()->dump(DAG);
124 dbgs() <<
" Disp " << Disp <<
'\n'
146 dbgs() <<
" JT" << JT <<
" Align" << Alignment.value() <<
'\n';
160 const X86Subtarget *Subtarget;
166 bool IndirectTlsSegRefs;
169 X86DAGToDAGISel() =
delete;
171 explicit X86DAGToDAGISel(X86TargetMachine &tm,
CodeGenOptLevel OptLevel)
172 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr),
173 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
179 "indirect-tls-seg-refs");
186 void emitFunctionEntryCode()
override;
188 bool IsProfitableToFold(SDValue
N, SDNode *U, SDNode *Root)
const override;
190 void PreprocessISelDAG()
override;
191 void PostprocessISelDAG()
override;
194#include "X86GenDAGISel.inc"
197 void Select(SDNode *
N)
override;
199 bool foldOffsetIntoAddress(
uint64_t Offset, X86ISelAddressMode &AM);
200 bool matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
201 bool AllowSegmentRegForX32 =
false);
202 bool matchWrapper(SDValue
N, X86ISelAddressMode &AM);
203 bool matchAddress(SDValue
N, X86ISelAddressMode &AM);
204 bool matchVectorAddress(SDValue
N, X86ISelAddressMode &AM);
205 bool matchAdd(SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
206 bool hasMaterializingUse(SDValue V)
const;
207 SDValue matchIndexRecursively(SDValue
N, X86ISelAddressMode &AM,
209 bool matchAddressRecursively(SDValue
N, X86ISelAddressMode &AM,
211 bool matchVectorAddressRecursively(SDValue
N, X86ISelAddressMode &AM,
213 bool matchAddressBase(SDValue
N, X86ISelAddressMode &AM);
214 bool selectAddr(SDNode *Parent, SDValue
N, SDValue &
Base, SDValue &Scale,
215 SDValue &Index, SDValue &Disp, SDValue &Segment,
216 bool HasNDDM =
true);
217 bool selectNDDAddr(SDNode *Parent, SDValue
N, SDValue &
Base, SDValue &Scale,
218 SDValue &Index, SDValue &Disp, SDValue &Segment);
219 bool selectVectorAddr(MemSDNode *Parent, SDValue BasePtr, SDValue IndexOp,
220 SDValue ScaleOp, SDValue &
Base, SDValue &Scale,
221 SDValue &Index, SDValue &Disp, SDValue &Segment);
222 bool selectMOV64Imm32(SDValue
N, SDValue &
Imm);
223 bool selectLEAAddr(SDValue
N, SDValue &
Base,
224 SDValue &Scale, SDValue &Index, SDValue &Disp,
226 bool selectLEA64_Addr(SDValue
N, SDValue &
Base, SDValue &Scale,
227 SDValue &Index, SDValue &Disp, SDValue &Segment);
228 bool selectTLSADDRAddr(SDValue
N, SDValue &
Base,
229 SDValue &Scale, SDValue &Index, SDValue &Disp,
231 bool selectRelocImm(SDValue
N, SDValue &
Op);
233 bool tryFoldLoad(SDNode *Root, SDNode *
P, SDValue
N,
234 SDValue &
Base, SDValue &Scale,
235 SDValue &Index, SDValue &Disp,
239 bool tryFoldLoad(SDNode *
P, SDValue
N,
240 SDValue &
Base, SDValue &Scale,
241 SDValue &Index, SDValue &Disp,
243 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
246 bool tryFoldBroadcast(SDNode *Root, SDNode *
P, SDValue
N,
247 SDValue &
Base, SDValue &Scale,
248 SDValue &Index, SDValue &Disp,
251 bool isProfitableToFormMaskedOp(SDNode *
N)
const;
254 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
256 std::vector<SDValue> &OutOps)
override;
258 void emitSpecialCodeForMain();
260 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
261 MVT VT, SDValue &
Base, SDValue &Scale,
262 SDValue &Index, SDValue &Disp,
264 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
265 Base = CurDAG->getTargetFrameIndex(
266 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
267 else if (AM.Base_Reg.
getNode())
270 Base = CurDAG->getRegister(0, VT);
272 Scale = getI8Imm(AM.Scale,
DL);
274#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
275#define GET_NDM_IF_ENABLED(OPC) \
276 (Subtarget->hasNDD() && Subtarget->hasNDDM() ? OPC##_ND : OPC)
278 if (AM.NegateIndex) {
296 SDValue Neg = SDValue(CurDAG->getMachineNode(NegOpc,
DL, VT, MVT::i32,
304 Index = CurDAG->getRegister(0, VT);
309 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(),
313 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
314 AM.Disp, AM.SymbolFlags);
316 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
317 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
318 }
else if (AM.MCSym) {
319 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
320 assert(AM.SymbolFlags == 0 &&
"oo");
321 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
322 }
else if (AM.JT != -1) {
323 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
324 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
325 }
else if (AM.BlockAddr)
326 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
329 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
332 Segment = AM.Segment;
334 Segment = CurDAG->getRegister(0, MVT::i16);
339 bool isAMXSDNode(SDNode *
N)
const {
343 for (
unsigned Idx = 0,
E =
N->getNumValues(); Idx !=
E; ++Idx) {
344 if (
N->getValueType(Idx) == MVT::x86amx)
347 for (
unsigned Idx = 0,
E =
N->getNumOperands(); Idx !=
E; ++Idx) {
348 SDValue
Op =
N->getOperand(Idx);
349 if (
Op.getValueType() == MVT::x86amx)
361 bool shouldAvoidImmediateInstFormsForSize(SDNode *
N)
const {
362 uint32_t UseCount = 0;
367 if (!CurDAG->shouldOptForSize())
371 for (
const SDNode *User :
N->users()) {
377 if (
User->isMachineOpcode()) {
384 User->getOperand(1).getNode() ==
N) {
395 if (
User->getNumOperands() != 2)
408 if (
User->getOpcode() == X86ISD::ADD ||
410 User->getOpcode() == X86ISD::SUB ||
414 SDValue OtherOp =
User->getOperand(0);
416 OtherOp =
User->getOperand(1);
419 RegisterSDNode *RegNode;
423 if ((RegNode->
getReg() == X86::ESP) ||
424 (RegNode->
getReg() == X86::RSP))
433 return (UseCount > 1);
437 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &
DL) {
438 return CurDAG->getTargetConstant(
Imm,
DL, MVT::i8);
442 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &
DL) {
443 return CurDAG->getTargetConstant(
Imm,
DL, MVT::i32);
448 return CurDAG->getTargetConstant(
Imm,
DL, MVT::i64);
451 SDValue getExtractVEXTRACTImmediate(SDNode *
N,
unsigned VecWidth,
453 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
455 MVT VecVT =
N->getOperand(0).getSimpleValueType();
459 SDValue getInsertVINSERTImmediate(SDNode *
N,
unsigned VecWidth,
461 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
463 MVT VecVT =
N->getSimpleValueType(0);
467 SDValue getPermuteVINSERTCommutedImmediate(SDNode *
N,
unsigned VecWidth,
469 assert(VecWidth == 128 &&
"Unexpected vector width");
471 MVT VecVT =
N->getSimpleValueType(0);
473 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
476 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
479 SDValue getSBBZero(SDNode *
N) {
481 MVT VT =
N->getSimpleValueType(0);
484 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
486 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
487 if (VT == MVT::i64) {
489 CurDAG->getMachineNode(
490 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, Zero,
491 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
496 unsigned Opcode =
N->getOpcode();
497 assert((Opcode == X86ISD::SBB || Opcode == X86ISD::SETCC_CARRY) &&
498 "Unexpected opcode for SBB materialization");
499 unsigned FlagOpIndex = Opcode == X86ISD::SBB ? 2 : 1;
501 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
502 N->getOperand(FlagOpIndex), SDValue());
506 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
507 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
508 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
510 CurDAG->getMachineNode(
Opc, dl, VTs,
511 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
517 bool isUnneededShiftMask(SDNode *
N,
unsigned Width)
const {
519 const APInt &Val =
N->getConstantOperandAPInt(1);
524 APInt
Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
525 return Mask.countr_one() >= Width;
534 bool isDef32(SDNode *
N)
const {
535 unsigned Opc =
N->getOpcode();
540 !((
Opc == X86ISD::BSF ||
Opc == X86ISD::BSR) &&
548 SDNode *getGlobalBaseReg();
552 const X86TargetMachine &getTargetMachine()
const {
553 return static_cast<const X86TargetMachine &
>(TM);
558 const X86InstrInfo *getInstrInfo()
const {
559 return Subtarget->getInstrInfo();
568 bool ComplexPatternFuncMutatesDAG()
const override {
572 bool isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const;
575 bool useNonTemporalLoad(LoadSDNode *
N)
const {
576 if (!
N->isNonTemporal())
579 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
581 if (
N->getAlign().value() < StoreSize)
590 return Subtarget->hasSSE41();
592 return Subtarget->hasAVX2();
594 return Subtarget->hasAVX512();
598 bool foldLoadStoreIntoMemOperand(SDNode *Node);
599 MachineSDNode *matchBEXTRFromAndImm(SDNode *Node);
600 bool matchBitExtract(SDNode *Node);
601 bool shrinkAndImmediate(SDNode *
N);
602 bool isMaskZeroExtended(SDNode *
N)
const;
603 bool tryShiftAmountMod(SDNode *
N);
604 bool tryShrinkShlLogicImm(SDNode *
N);
605 bool tryVPTERNLOG(SDNode *
N);
606 bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentB,
607 SDNode *ParentC, SDValue
A, SDValue
B, SDValue
C,
609 bool tryVPTESTM(SDNode *Root, SDValue Setcc, SDValue Mask);
610 bool tryMatchBitSelect(SDNode *
N);
612 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
613 const SDLoc &dl, MVT VT, SDNode *Node);
614 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
615 const SDLoc &dl, MVT VT, SDNode *Node,
618 bool tryOptimizeRem8Extend(SDNode *
N);
620 bool onlyUsesZeroFlag(SDValue Flags)
const;
621 bool hasNoSignFlagUses(SDValue Flags)
const;
622 bool hasNoCarryFlagUses(SDValue Flags)
const;
623 bool checkTCRetEnoughRegs(SDNode *
N)
const;
629 explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm,
631 : SelectionDAGISelLegacy(
632 ID, std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
636char X86DAGToDAGISelLegacy::ID = 0;
643 unsigned Opcode =
N->getOpcode();
644 if (Opcode == X86ISD::CMPM || Opcode == X86ISD::CMPMM ||
645 Opcode == X86ISD::STRICT_CMPM || Opcode ==
ISD::SETCC ||
646 Opcode == X86ISD::CMPMM_SAE || Opcode == X86ISD::VFPCLASS) {
650 EVT OpVT =
N->getOperand(0).getValueType();
653 if (Opcode == X86ISD::STRICT_CMPM)
654 OpVT =
N->getOperand(1).getValueType();
656 return Subtarget->hasVLX();
661 if (Opcode == X86ISD::VFPCLASSS || Opcode == X86ISD::FSETCCM ||
662 Opcode == X86ISD::FSETCCM_SAE)
670bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
682X86DAGToDAGISel::IsProfitableToFold(SDValue
N, SDNode *U, SDNode *Root)
const {
683 if (OptLevel == CodeGenOptLevel::None)
698 switch (
U->getOpcode()) {
712 SDValue Op1 =
U->getOperand(1);
725 if (
Imm->getAPIntValue().isSignedIntN(8))
734 Imm->getAPIntValue().getBitWidth() == 64 &&
735 Imm->getAPIntValue().isIntN(32))
742 (
Imm->getAPIntValue() == UINT8_MAX ||
743 Imm->getAPIntValue() == UINT16_MAX ||
744 Imm->getAPIntValue() == UINT32_MAX))
750 (-
Imm->getAPIntValue()).isSignedIntN(8))
753 if ((
U->getOpcode() == X86ISD::ADD ||
U->getOpcode() == X86ISD::SUB) &&
754 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
755 hasNoCarryFlagUses(SDValue(U, 1)))
769 if (Op1.
getOpcode() == X86ISD::Wrapper) {
780 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
784 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
789 SDValue U0 =
U->getOperand(0);
790 SDValue U1 =
U->getOperand(1);
793 if (
C &&
C->getSExtValue() == -2)
799 if (
C &&
C->getSExtValue() == -2)
834bool X86DAGToDAGISel::isProfitableToFormMaskedOp(SDNode *
N)
const {
836 (
N->getOpcode() ==
ISD::VSELECT ||
N->getOpcode() == X86ISD::SELECTS) &&
837 "Unexpected opcode!");
842 return N->getOperand(1).hasOneUse();
852 Ops.push_back(
Load.getOperand(0));
855 "Unexpected chain operand");
858 Ops.push_back(
Load.getOperand(0));
864 Ops.push_back(NewChain);
869 Load.getOperand(1),
Load.getOperand(2));
887 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
899 if (!Callee.getValue(1).hasOneUse())
930 Callee.getValue(1).hasOneUse())
948 const unsigned NumBytes =
BitWidth / 8;
952 const uint8_t OptionalPrefixBytes[] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
953 0x65, 0x66, 0x67, 0xf0, 0xf2};
955 for (
unsigned I = 0;
I != NumBytes; ++
I)
956 Bytes[
I] = (
Imm >> (
I * 8)) & 0xFF;
958 for (
unsigned I = 0;
I + 3 < NumBytes; ++
I) {
959 if (Bytes[
I] != 0xf3)
966 if (J + 2 < NumBytes && Bytes[J] == 0x0f && Bytes[J + 1] == 0x1e &&
967 (Bytes[J + 2] == 0xfa || Bytes[J + 2] == 0xfb))
975 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
990void X86DAGToDAGISel::PreprocessISelDAG() {
991 bool MadeChange =
false;
993 E = CurDAG->allnodes_end();
I !=
E; ) {
1011 MVT VT =
N->getSimpleValueType(0);
1013 "ISD::Constant must have a scalar integer type");
1022 "cf-protection-branch");
1023 if (CFProtectionBranch ||
1024 Subtarget->getCLOpts().indirect_branch_tracking) {
1028 SDValue Complement =
1029 CurDAG->getConstant(ComplementImm, dl, VT,
false,
true);
1030 Complement = CurDAG->getNOT(dl, Complement, VT);
1032 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Complement);
1042 if (
N->getOpcode() == X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
1043 SDValue Res = CurDAG->getNode(
ISD::AND, SDLoc(
N),
N->getValueType(0),
1044 N->getOperand(0),
N->getOperand(1));
1046 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1070 auto mayPreventLoadFold = [&]() {
1072 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1073 !
N->getOperand(1).hasOneUse();
1076 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1084 MVT VT =
N->getSimpleValueType(0);
1092 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1094 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1101 switch (
N->getOpcode()) {
1102 case X86ISD::VBROADCAST: {
1103 MVT VT =
N->getSimpleValueType(0);
1105 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1108 SDValue NarrowBCast =
1109 CurDAG->getNode(X86ISD::VBROADCAST, dl, NarrowVT,
N->getOperand(0));
1112 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1115 CurDAG->getIntPtrConstant(Index, dl));
1118 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1126 case X86ISD::VBROADCAST_LOAD: {
1127 MVT VT =
N->getSimpleValueType(0);
1129 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1133 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1134 SDValue
Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1135 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1136 X86ISD::VBROADCAST_LOAD, dl, VTs,
Ops, MemNode->getMemoryVT(),
1137 MemNode->getMemOperand());
1140 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1143 CurDAG->getIntPtrConstant(Index, dl));
1146 SDValue To[] = {Res, NarrowBCast.
getValue(1)};
1147 CurDAG->ReplaceAllUsesWith(
N, To);
1159 MVT VT =
N->getSimpleValueType(0);
1165 SDNode *MaxLd =
nullptr;
1166 SDValue Ptr = Ld->getBasePtr();
1167 SDValue Chain = Ld->getChain();
1168 for (SDNode *User : Ptr->
users()) {
1170 MVT UserVT =
User->getSimpleValueType(0);
1172 UserLd->getBasePtr() == Ptr && UserLd->getChain() == Chain &&
1173 !
User->hasAnyUseOfValue(1) &&
1187 CurDAG->getIntPtrConstant(0, dl));
1188 SDValue Res = CurDAG->getBitcast(VT, Extract);
1191 SDValue To[] = {Res, SDValue(MaxLd, 1)};
1192 CurDAG->ReplaceAllUsesWith(
N, To);
1201 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1202 if (EleVT == MVT::i1)
1205 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1206 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1207 "We can't replace VSELECT with BLENDV in vXi16!");
1209 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1211 R = CurDAG->getNode(X86ISD::VPTERNLOG, SDLoc(
N),
N->getValueType(0),
1212 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1213 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1215 R = CurDAG->getNode(X86ISD::BLENDV, SDLoc(
N),
N->getValueType(0),
1216 N->getOperand(0),
N->getOperand(1),
1220 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1233 if (!
N->getSimpleValueType(0).isVector())
1237 switch (
N->getOpcode()) {
1247 if (
N->isStrictFPOpcode())
1249 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1250 {
N->getOperand(0),
N->getOperand(1)});
1253 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1256 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1266 if (!
N->getValueType(0).isVector())
1270 switch (
N->getOpcode()) {
1272 case ISD::SHL: NewOpc = X86ISD::VSHLV;
break;
1273 case ISD::SRA: NewOpc = X86ISD::VSRAV;
break;
1274 case ISD::SRL: NewOpc = X86ISD::VSRLV;
break;
1276 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1277 N->getOperand(0),
N->getOperand(1));
1279 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1288 if (!
N->getValueType(0).isVector())
1292 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1294 "Unexpected opcode for mask vector!");
1302 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1305 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1325 switch (
N->getOpcode()) {
1341 bool IsStrict =
N->isStrictFPOpcode();
1344 Res = CurDAG->getNode(X86ISD::STRICT_VRNDSCALE, dl,
1345 {
N->getValueType(0), MVT::Other},
1346 {
N->getOperand(0),
N->getOperand(1),
1347 CurDAG->getTargetConstant(
Imm, dl, MVT::i32)});
1349 Res = CurDAG->getNode(X86ISD::VRNDSCALE, dl,
N->getValueType(0),
1351 CurDAG->getTargetConstant(
Imm, dl, MVT::i32));
1353 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1361 case X86ISD::FXOR: {
1364 MVT VT =
N->getSimpleValueType(0);
1365 if (VT.
isVector() || VT == MVT::f128)
1368 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1369 : VT == MVT::f32 ? MVT::v4f32
1379 if (Subtarget->hasSSE2()) {
1380 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1384 switch (
N->getOpcode()) {
1386 case X86ISD::FANDN:
Opc = X86ISD::ANDNP;
break;
1391 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1394 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1397 CurDAG->getIntPtrConstant(0, dl));
1399 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1406 MVT VT =
N->getSimpleValueType(0);
1409 assert(Subtarget->hasAVX512() &&
"Mask vectors need AVX512");
1412 if (isMaskZeroExtended(
N))
1415 SDValue N0 =
N->getOperand(0);
1416 SDValue N1 =
N->getOperand(1);
1424 MVT WideVT =
Cmp.getSimpleValueType();
1425 SDValue ZeroIdx = CurDAG->getIntPtrConstant(0, dl);
1426 auto Widen = [&](SDValue
V) {
1429 V.getOperand(0).getValueType() == WideVT)
1430 return V.getOperand(0);
1432 CurDAG->getUNDEF(WideVT), V, ZeroIdx);
1434 SDValue Wide0 =
Widen(N0);
1435 SDValue Wide1 =
Widen(N1);
1436 SDValue Res = CurDAG->getNode(
ISD::AND, dl, WideVT, Wide0, Wide1);
1439 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1446 if (OptLevel != CodeGenOptLevel::None &&
1449 !Subtarget->useIndirectThunkCalls() &&
1450 ((
N->getOpcode() == X86ISD::CALL && !Subtarget->slowTwoMemOps() &&
1451 !Subtarget->slowIndirectCall()) ||
1452 (
N->getOpcode() == X86ISD::TC_RETURN &&
1453 (Subtarget->is64Bit() ||
1454 !getTargetMachine().isPositionIndependent())))) {
1474 bool HasCallSeq =
N->getOpcode() == X86ISD::CALL;
1479 if (
N->getOpcode() == X86ISD::TC_RETURN && !checkTCRetEnoughRegs(
N))
1495 switch (
N->getOpcode()) {
1500 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1501 MVT DstVT =
N->getSimpleValueType(0);
1509 const X86TargetLowering *X86Lowering =
1510 static_cast<const X86TargetLowering *
>(TLI);
1513 if (SrcIsSSE && DstIsSSE)
1516 if (!SrcIsSSE && !DstIsSSE) {
1521 if (
N->getConstantOperandVal(1))
1529 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1531 MachinePointerInfo MPI =
1537 SDValue
Store = CurDAG->getTruncStore(
1538 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1540 MemTmp, MPI, MemVT);
1547 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Result);
1556 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1557 MVT DstVT =
N->getSimpleValueType(0);
1565 const X86TargetLowering *X86Lowering =
1566 static_cast<const X86TargetLowering *
>(TLI);
1569 if (SrcIsSSE && DstIsSSE)
1572 if (!SrcIsSSE && !DstIsSSE) {
1577 if (
N->getConstantOperandVal(2))
1585 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1587 MachinePointerInfo MPI =
1596 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1597 SDValue
Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1598 Store = CurDAG->getMemIntrinsicNode(X86ISD::FST, dl, VTs,
Ops, MemVT,
1601 if (
N->getFlags().hasNoFPExcept()) {
1603 Flags.setNoFPExcept(
true);
1604 Store->setFlags(Flags);
1607 assert(SrcVT == MemVT &&
"Unexpected VT!");
1608 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1613 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1615 Result = CurDAG->getMemIntrinsicNode(
1616 X86ISD::FLD, dl, VTs,
Ops, MemVT, MPI,
1618 if (
N->getFlags().hasNoFPExcept()) {
1620 Flags.setNoFPExcept(
true);
1624 assert(DstVT == MemVT &&
"Unexpected VT!");
1625 Result = CurDAG->getLoad(DstVT, dl,
Store, MemTmp, MPI);
1633 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1647 CurDAG->RemoveDeadNodes();
1651bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1652 unsigned Opc =
N->getMachineOpcode();
1653 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1654 Opc != X86::MOVSX64rr8)
1666 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1667 : X86::MOVSX32rr8_NOREX;
1672 if (
Opc == X86::MOVSX64rr8) {
1675 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1677 ReplaceUses(
N, Extend);
1686void X86DAGToDAGISel::PostprocessISelDAG() {
1688 if (TM.getOptLevel() == CodeGenOptLevel::None)
1693 bool MadeChange =
false;
1694 while (Position != CurDAG->allnodes_begin()) {
1695 SDNode *
N = &*--Position;
1697 if (
N->use_empty() || !
N->isMachineOpcode())
1700 if (tryOptimizeRem8Extend(
N)) {
1705 unsigned Opc =
N->getMachineOpcode();
1716 case X86::CTEST16rr:
1717 case X86::CTEST32rr:
1718 case X86::CTEST64rr: {
1724#define CASE_ND(OP) \
1727 switch (
And.getMachineOpcode()) {
1734 if (
And->hasAnyUseOfValue(1))
1737 Ops[0] =
And.getOperand(0);
1738 Ops[1] =
And.getOperand(1);
1739 MachineSDNode *
Test =
1740 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1741 ReplaceUses(
N,
Test);
1749 if (
And->hasAnyUseOfValue(1))
1752 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1753#define FROM_TO(A, B) \
1754 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1756 switch (
And.getMachineOpcode()) {
1766 And.getOperand(3),
And.getOperand(4),
1767 And.getOperand(5),
And.getOperand(0)};
1770 Ops.push_back(
N->getOperand(2));
1771 Ops.push_back(
N->getOperand(3));
1774 Ops.push_back(
And.getOperand(6));
1777 Ops.push_back(
N->getOperand(4));
1779 MachineSDNode *
Test = CurDAG->getMachineNode(
1780 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1781 CurDAG->setNodeMemRefs(
1783 ReplaceUses(
And.getValue(2), SDValue(
Test, 1));
1784 ReplaceUses(SDValue(
N, 0), SDValue(
Test, 0));
1794 case X86::KORTESTBkk:
1795 case X86::KORTESTWkk:
1796 case X86::KORTESTDkk:
1797 case X86::KORTESTQkk: {
1799 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1814#define FROM_TO(A, B) \
1826 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1829 MachineSDNode *KTest = CurDAG->getMachineNode(
1831 ReplaceUses(
N, KTest);
1836 case TargetOpcode::SUBREG_TO_REG: {
1837 unsigned SubRegIdx =
N->getConstantOperandVal(1);
1838 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1841 SDValue Move =
N->getOperand(0);
1855 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1856 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1857 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1858 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1859 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1860 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1861 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1862 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1867 if (!
In.isMachineOpcode() ||
1868 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1873 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1881 CurDAG->UpdateNodeOperands(
N, In,
N->getOperand(1));
1888 CurDAG->RemoveDeadNodes();
1893void X86DAGToDAGISel::emitSpecialCodeForMain() {
1894 if (Subtarget->isTargetCygMing()) {
1895 TargetLowering::ArgListTy
Args;
1896 auto &
DL = CurDAG->getDataLayout();
1898 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1899 CLI.setChain(CurDAG->getRoot())
1900 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1901 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1903 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1905 CurDAG->setRoot(
Result.second);
1909void X86DAGToDAGISel::emitFunctionEntryCode() {
1912 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1913 emitSpecialCodeForMain();
1927 X86ISelAddressMode &AM) {
1932 int64_t Val = AM.Disp +
Offset;
1935 if (Val != 0 && (AM.ES || AM.MCSym))
1939 if (Subtarget->is64Bit()) {
1942 AM.hasSymbolicDisplacement()))
1946 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1965 if (Subtarget->isTarget64BitILP32() &&
1967 !AM.hasBaseOrIndexReg())
1969 }
else if (Subtarget->is16Bit()) {
1972 if (Val < -(int64_t)UINT16_MAX || Val > (int64_t)UINT16_MAX)
1982bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1983 bool AllowSegmentRegForX32) {
1984 SDValue
Address =
N->getOperand(1);
1996 !IndirectTlsSegRefs &&
1997 (Subtarget->isTargetGlibc() || Subtarget->isTargetMusl() ||
1998 Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())) {
1999 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
2001 switch (
N->getPointerInfo().getAddrSpace()) {
2003 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
2006 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
2019bool X86DAGToDAGISel::matchWrapper(SDValue
N, X86ISelAddressMode &AM) {
2022 if (AM.hasSymbolicDisplacement())
2025 bool IsRIPRelTLS =
false;
2026 bool IsRIPRel =
N.getOpcode() == X86ISD::WrapperRIP;
2028 SDValue Val =
N.getOperand(0);
2043 if (IsRIPRel && AM.hasBaseOrIndexReg())
2047 X86ISelAddressMode Backup = AM;
2052 AM.GV =
G->getGlobal();
2053 AM.SymbolFlags =
G->getTargetFlags();
2056 AM.CP = CP->getConstVal();
2057 AM.Alignment = CP->getAlign();
2058 AM.SymbolFlags = CP->getTargetFlags();
2059 Offset = CP->getOffset();
2061 AM.ES = S->getSymbol();
2062 AM.SymbolFlags = S->getTargetFlags();
2064 AM.MCSym = S->getMCSymbol();
2066 AM.JT = J->getIndex();
2067 AM.SymbolFlags = J->getTargetFlags();
2069 AM.BlockAddr = BA->getBlockAddress();
2070 AM.SymbolFlags = BA->getTargetFlags();
2071 Offset = BA->getOffset();
2076 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
2077 TM.isLargeGlobalValue(AM.GV)) {
2082 if (foldOffsetIntoAddress(
Offset, AM)) {
2088 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
2096bool X86DAGToDAGISel::matchAddress(SDValue
N, X86ISelAddressMode &AM) {
2097 if (matchAddressRecursively(
N, AM, 0))
2104 if (Subtarget->isTarget64BitILP32() &&
2105 AM.BaseType == X86ISelAddressMode::RegBase &&
2106 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
2107 SDValue Save_Base_Reg = AM.Base_Reg;
2109 AM.Base_Reg = SDValue();
2110 if (matchLoadInAddress(LoadN, AM,
true))
2111 AM.Base_Reg = Save_Base_Reg;
2120 if (AM.Scale == 2 && !AM.NegateIndex &&
2121 AM.BaseType == X86ISelAddressMode::RegBase &&
2122 AM.Base_Reg.
getNode() ==
nullptr) {
2123 AM.Base_Reg = AM.IndexReg;
2130 (!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2131 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2132 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2144 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2157bool X86DAGToDAGISel::hasMaterializingUse(SDValue V)
const {
2158 const TargetInstrInfo *
TII = Subtarget->getInstrInfo();
2159 for (SDUse &U :
V->uses()) {
2160 if (
U.getResNo() !=
V.getResNo())
2162 SDNode *
User =
U.getUser();
2168 if (St->getValue() == V)
2179 if (!
User->isMachineOpcode())
2181 const MCInstrDesc &
Desc =
TII->get(
User->getMachineOpcode());
2182 if (!
Desc.mayStore())
2185 if (MemRefBegin < 0)
2188 for (
unsigned I = 0,
E =
User->getNumOperands();
I !=
E; ++
I) {
2189 if (
I >=
static_cast<unsigned>(MemRefBegin) &&
I < MemRefEnd)
2191 SDValue Opnd =
User->getOperand(
I);
2201bool X86DAGToDAGISel::matchAdd(SDValue &
N, X86ISelAddressMode &AM,
2205 HandleSDNode Handle(
N);
2207 auto IsAddOrAddLike = [&](SDValue
V) {
2208 return V.getOpcode() ==
ISD::ADD || CurDAG->isADDLike(V);
2217 auto SplitsMaterializedValue = [&](SDValue
Op) {
2218 if (!AM.IsForLEA || !hasMaterializingUse(
Op))
2222 if (IsAddOrAddLike(
Op))
2223 return IsAddOrAddLike(
Op.getOperand(0)) ||
2224 IsAddOrAddLike(
Op.getOperand(1));
2229 return C->getZExtValue() >= 1 &&
C->getZExtValue() <= 3 &&
2230 IsAddOrAddLike(
Op.getOperand(0));
2240 auto MatchOperand = [&](SDValue
Op) {
2250 if (SplitsMaterializedValue(
Op) && !AM.isRIPRelative())
2251 return matchAddressBase(
Op, AM);
2252 return matchAddressRecursively(
Op, AM,
Depth + 1);
2255 X86ISelAddressMode Backup = AM;
2256 if (!MatchOperand(
N.getOperand(0)) &&
2257 !MatchOperand(Handle.getValue().getOperand(1)))
2262 if (!MatchOperand(Handle.getValue().getOperand(1)) &&
2263 !MatchOperand(Handle.getValue().getOperand(0)))
2270 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2273 N = Handle.getValue();
2279 N = Handle.getValue();
2289 if (
N->getNodeId() == -1 ||
2309 X86ISelAddressMode &AM) {
2316 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2317 Mask != (0xffu << ScaleLog))
2320 MVT XVT =
X.getSimpleValueType();
2321 MVT VT =
N.getSimpleValueType();
2346 AM.Scale = (1 << ScaleLog);
2354 X86ISelAddressMode &AM) {
2365 bool FoundAnyExtend =
false;
2369 FoundAnyExtend =
true;
2387 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2390 MVT VT =
N.getSimpleValueType();
2392 if (FoundAnyExtend) {
2413 AM.Scale = 1 << ShiftAmt;
2414 AM.IndexReg = NewAnd;
2448 X86ISelAddressMode &AM) {
2454 unsigned MaskIdx, MaskLen;
2457 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2463 unsigned AMShiftAmt = MaskIdx;
2467 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2471 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2472 if (MaskLZ < ScaleDown)
2474 MaskLZ -= ScaleDown;
2482 bool ReplacingAnyExtend =
false;
2484 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2485 X.getOperand(0).getSimpleValueType().getSizeInBits();
2488 X =
X.getOperand(0);
2489 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2490 ReplacingAnyExtend =
true;
2492 APInt MaskedHighBits =
2499 MVT VT =
N.getSimpleValueType();
2500 if (ReplacingAnyExtend) {
2501 assert(
X.getValueType() != VT);
2508 MVT XVT =
X.getSimpleValueType();
2529 AM.Scale = 1 << AMShiftAmt;
2530 AM.IndexReg = NewExt;
2540 X86ISelAddressMode &AM,
2548 if (!Subtarget.hasTBM() &&
2549 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2553 unsigned MaskIdx, MaskLen;
2561 unsigned AMShiftAmt = MaskIdx;
2565 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2567 MVT XVT =
X.getSimpleValueType();
2568 MVT VT =
N.getSimpleValueType();
2593 AM.Scale = 1 << AMShiftAmt;
2594 AM.IndexReg = NewExt;
2600SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue
N,
2601 X86ISelAddressMode &AM,
2603 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2604 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2605 "Illegal index scale");
2611 EVT VT =
N.getValueType();
2612 unsigned Opc =
N.getOpcode();
2615 if (CurDAG->isBaseWithConstantOffset(
N)) {
2618 if (!foldOffsetIntoAddress(
Offset, AM))
2619 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2623 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2624 if (AM.Scale <= 4) {
2626 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2631 if (
Opc == X86ISD::VSHLI) {
2632 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2633 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2634 if ((AM.Scale * ScaleAmt) <= 8) {
2635 AM.Scale *= ScaleAmt;
2636 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2643 SDValue Src =
N.getOperand(0);
2644 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2646 if (CurDAG->isBaseWithConstantOffset(Src)) {
2647 SDValue AddSrc = Src.getOperand(0);
2649 int64_t
Offset = AddVal->getSExtValue();
2652 SDValue ExtSrc = CurDAG->getNode(
Opc,
DL, VT, AddSrc);
2653 SDValue ExtVal = CurDAG->getSignedConstant(
Offset,
DL, VT);
2654 SDValue ExtAdd = CurDAG->getNode(
ISD::ADD,
DL, VT, ExtSrc, ExtVal);
2658 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2659 CurDAG->RemoveDeadNode(
N.getNode());
2670 SDValue Src =
N.getOperand(0);
2671 unsigned SrcOpc = Src.getOpcode();
2672 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2673 CurDAG->isADDLike(Src,
true)) &&
2675 if (CurDAG->isBaseWithConstantOffset(Src)) {
2676 SDValue AddSrc = Src.getOperand(0);
2678 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2689 if ((AM.Scale * ScaleAmt) <= 8 &&
2691 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2692 AM.Scale *= ScaleAmt;
2693 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2694 SDValue ExtShift = CurDAG->getNode(
ISD::SHL,
DL, VT, ExtShVal,
2702 SDValue ExtSrc = CurDAG->getNode(
Opc,
DL, VT, AddSrc);
2703 SDValue ExtVal = CurDAG->getConstant(
Offset,
DL, VT);
2704 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2708 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2709 CurDAG->RemoveDeadNode(
N.getNode());
2710 return Res ? Res : ExtSrc;
2720bool X86DAGToDAGISel::matchAddressRecursively(SDValue
N, X86ISelAddressMode &AM,
2723 dbgs() <<
"MatchAddress: ";
2728 return matchAddressBase(
N, AM);
2733 if (AM.isRIPRelative()) {
2737 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2741 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2746 switch (
N.getOpcode()) {
2749 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2752 AM.MCSym = ESNode->getMCSymbol();
2759 if (!foldOffsetIntoAddress(Val, AM))
2764 case X86ISD::Wrapper:
2765 case X86ISD::WrapperRIP:
2766 if (!matchWrapper(
N, AM))
2776 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2777 AM.Base_Reg.
getNode() ==
nullptr &&
2779 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2786 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2790 unsigned Val = CN->getZExtValue();
2795 if (Val == 1 || Val == 2 || Val == 3) {
2797 AM.Scale = 1 << Val;
2798 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2806 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2810 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2811 "Unexpected value size!");
2813 SDValue
And =
N.getOperand(0);
2815 SDValue
X =
And.getOperand(0);
2823 uint64_t Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2835 if (
N.getResNo() != 0)
break;
2838 case X86ISD::MUL_IMM:
2840 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2841 AM.Base_Reg.
getNode() ==
nullptr &&
2842 AM.IndexReg.
getNode() ==
nullptr) {
2844 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2845 CN->getZExtValue() == 9) {
2846 AM.Scale = unsigned(CN->getZExtValue())-1;
2848 SDValue MulVal =
N.getOperand(0);
2858 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2859 if (foldOffsetIntoAddress(Disp, AM))
2860 Reg =
N.getOperand(0);
2862 Reg =
N.getOperand(0);
2865 AM.IndexReg = AM.Base_Reg =
Reg;
2883 HandleSDNode Handle(
N);
2886 X86ISelAddressMode Backup = AM;
2887 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2888 N = Handle.getValue();
2892 N = Handle.getValue();
2894 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2900 SDValue
RHS =
N.getOperand(1);
2913 std::optional<unsigned> NegScale;
2916 uint64_t ShVal = ShAmt->getZExtValue();
2917 if (ShVal >= 1 && ShVal <= 3) {
2918 NegScale = 1u << ShVal;
2936 RHS.getOperand(0).getValueType() == MVT::i32))
2939 bool BaseIsNegatedValue = NegScale &&
2940 AM.BaseType == X86ISelAddressMode::RegBase &&
2947 if (((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2949 AM.BaseType == X86ISelAddressMode::FrameIndexBase) &&
2950 !BaseIsNegatedValue)
2954 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2955 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2968 AM.NegateIndex =
true;
2969 AM.Scale = NegScale.value_or(1);
2976 if (!CurDAG->isADDLike(
N))
2980 if (!matchAdd(
N, AM,
Depth))
2989 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2993 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2994 "Unexpected value size!");
2999 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
3000 SDValue Shift =
N.getOperand(0);
3028 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
3031 SDValue Src =
N.getOperand(0);
3036 if (SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
3038 AM.IndexReg =
Index;
3044 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
3046 Mask = MaskC->getAPIntValue();
3047 Src = Src.getOperand(0);
3050 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
3052 SDValue ShlSrc = Src.getOperand(0);
3053 SDValue ShlAmt = Src.getOperand(1);
3057 unsigned ShAmtV = ShAmtC->getZExtValue();
3065 if (!Src->getFlags().hasNoUnsignedWrap() &&
3066 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
3074 MVT VT =
N.getSimpleValueType();
3077 SDValue Res = ShlSrc;
3078 if (!
Mask.isAllOnes()) {
3079 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
3081 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
3086 SDValue NewShl = CurDAG->getNode(
ISD::SHL,
DL, VT, Zext, ShlAmt);
3088 CurDAG->ReplaceAllUsesWith(
N, NewShl);
3089 CurDAG->RemoveDeadNode(
N.getNode());
3092 AM.Scale = 1 << ShAmtV;
3096 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
3100 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
3103 Src.getOperand(0), AM))
3108 Src.getOperand(0), AM))
3113 Src.getOperand(0), AM, *Subtarget))
3121 return matchAddressBase(
N, AM);
3126bool X86DAGToDAGISel::matchAddressBase(SDValue
N, X86ISelAddressMode &AM) {
3128 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
3141 AM.BaseType = X86ISelAddressMode::RegBase;
3146bool X86DAGToDAGISel::matchVectorAddressRecursively(SDValue
N,
3147 X86ISelAddressMode &AM,
3150 dbgs() <<
"MatchVectorAddress: ";
3155 return matchAddressBase(
N, AM);
3158 switch (
N.getOpcode()) {
3161 if (!foldOffsetIntoAddress(Val, AM))
3165 case X86ISD::Wrapper:
3166 if (!matchWrapper(
N, AM))
3172 HandleSDNode Handle(
N);
3174 X86ISelAddressMode Backup = AM;
3175 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
3176 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
3182 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
3184 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
3189 N = Handle.getValue();
3194 return matchAddressBase(
N, AM);
3200bool X86DAGToDAGISel::matchVectorAddress(SDValue
N, X86ISelAddressMode &AM) {
3201 return matchVectorAddressRecursively(
N, AM, 0);
3204bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent, SDValue BasePtr,
3205 SDValue IndexOp, SDValue ScaleOp,
3206 SDValue &
Base, SDValue &Scale,
3207 SDValue &Index, SDValue &Disp,
3209 X86ISelAddressMode AM;
3215 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
3217 AM.IndexReg = IndexOp;
3221 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3223 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3225 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3228 MVT VT =
BasePtr.getSimpleValueType();
3231 if (matchVectorAddress(BasePtr, AM))
3234 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3245bool X86DAGToDAGISel::selectAddr(SDNode *Parent, SDValue
N, SDValue &
Base,
3246 SDValue &Scale, SDValue &Index, SDValue &Disp,
3247 SDValue &Segment,
bool HasNDDM) {
3248 X86ISelAddressMode AM;
3255 Parent->
getOpcode() != X86ISD::TLSCALL &&
3256 Parent->
getOpcode() != X86ISD::ENQCMD &&
3257 Parent->
getOpcode() != X86ISD::ENQCMDS &&
3258 Parent->
getOpcode() != X86ISD::EH_SJLJ_SETJMP &&
3259 Parent->
getOpcode() != X86ISD::EH_SJLJ_LONGJMP) {
3260 unsigned AddrSpace =
3263 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3265 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3267 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3272 MVT VT =
N.getSimpleValueType();
3274 if (matchAddress(
N, AM))
3277 if (!HasNDDM && !AM.isRIPRelative())
3280 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3284bool X86DAGToDAGISel::selectNDDAddr(SDNode *Parent, SDValue
N, SDValue &
Base,
3285 SDValue &Scale, SDValue &Index,
3286 SDValue &Disp, SDValue &Segment) {
3287 return selectAddr(Parent,
N,
Base, Scale, Index, Disp, Segment,
3288 Subtarget->hasNDDM());
3291bool X86DAGToDAGISel::selectMOV64Imm32(SDValue
N, SDValue &
Imm) {
3300 if (
N->getOpcode() != X86ISD::Wrapper)
3303 N =
N.getOperand(0);
3320 return CR->getUnsignedMax().ult(1ull << 32);
3322 return !TM.isLargeGlobalValue(GV);
3325bool X86DAGToDAGISel::selectLEA64_Addr(SDValue
N, SDValue &
Base, SDValue &Scale,
3326 SDValue &Index, SDValue &Disp,
3331 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3337 SubReg = X86::sub_8bit;
3339 SubReg = X86::sub_16bit;
3341 SubReg = X86::sub_32bit;
3344 if (RN &&
RN->getReg() == 0)
3345 Base = CurDAG->getRegister(0, MVT::i64);
3350 SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF,
DL,
3352 Base = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef,
Base);
3355 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3357 if (RN &&
RN->getReg() == 0)
3358 Index = CurDAG->getRegister(0, MVT::i64);
3361 "Expect to be extending 8/16/32-bit registers for use in LEA");
3362 SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF,
DL,
3364 Index = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef, Index);
3372bool X86DAGToDAGISel::selectLEAAddr(SDValue
N,
3373 SDValue &
Base, SDValue &Scale,
3374 SDValue &Index, SDValue &Disp,
3376 X86ISelAddressMode AM;
3381 MVT VT =
N.getSimpleValueType();
3385 SDValue
Copy = AM.Segment;
3386 SDValue
T = CurDAG->getRegister(0, MVT::i32);
3388 if (matchAddress(
N, AM))
3393 unsigned Complexity = 0;
3394 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3396 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3412 if (AM.hasSymbolicDisplacement()) {
3414 if (Subtarget->is64Bit())
3424 auto isMathWithFlags = [](SDValue
V) {
3425 switch (
V.getOpcode()) {
3439 return !SDValue(
V.getNode(), 1).use_empty();
3446 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3454 if (Complexity <= 2)
3457 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3462bool X86DAGToDAGISel::selectTLSADDRAddr(SDValue
N, SDValue &
Base,
3463 SDValue &Scale, SDValue &Index,
3464 SDValue &Disp, SDValue &Segment) {
3468 X86ISelAddressMode AM;
3470 AM.GV = GA->getGlobal();
3471 AM.Disp += GA->getOffset();
3472 AM.SymbolFlags = GA->getTargetFlags();
3475 AM.ES = SA->getSymbol();
3476 AM.SymbolFlags = SA->getTargetFlags();
3479 if (Subtarget->is32Bit()) {
3481 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3484 MVT VT =
N.getSimpleValueType();
3485 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3489bool X86DAGToDAGISel::selectRelocImm(SDValue
N, SDValue &
Op) {
3493 EVT VT =
N.getValueType();
3494 bool WasTruncated =
false;
3496 WasTruncated =
true;
3497 N =
N.getOperand(0);
3500 if (
N.getOpcode() != X86ISD::Wrapper)
3506 unsigned Opc =
N.getOperand(0)->getOpcode();
3508 Op =
N.getOperand(0);
3511 return !WasTruncated;
3516 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3517 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3521 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3522 GA->getOffset(), GA->getTargetFlags());
3526bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P, SDValue
N,
3527 SDValue &
Base, SDValue &Scale,
3528 SDValue &Index, SDValue &Disp,
3530 assert(Root &&
P &&
"Unknown root/parent nodes");
3532 !IsProfitableToFold(
N,
P, Root) ||
3533 !IsLegalToFold(
N,
P, Root, OptLevel))
3536 return selectAddr(
N.getNode(),
3537 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3540bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P, SDValue
N,
3541 SDValue &
Base, SDValue &Scale,
3542 SDValue &Index, SDValue &Disp,
3544 assert(Root &&
P &&
"Unknown root/parent nodes");
3545 if (
N->getOpcode() != X86ISD::VBROADCAST_LOAD ||
3546 !IsProfitableToFold(
N,
P, Root) ||
3547 !IsLegalToFold(
N,
P, Root, OptLevel))
3550 return selectAddr(
N.getNode(),
3551 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3557SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3560 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3563bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3565 N =
N->getOperand(0).getNode();
3566 if (
N->getOpcode() != X86ISD::Wrapper)
3573 auto *GV = GA->getGlobal();
3576 return CR->getSignedMin().sge(-1ull << Width) &&
3577 CR->getSignedMax().slt(1ull << Width);
3583 !TM.isLargeGlobalValue(GV);
3587 assert(
N->isMachineOpcode() &&
"Unexpected node");
3588 unsigned Opc =
N->getMachineOpcode();
3589 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3594 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3599bool X86DAGToDAGISel::onlyUsesZeroFlag(SDValue Flags)
const {
3601 for (SDUse &Use :
Flags->uses()) {
3603 if (
Use.getResNo() !=
Flags.getResNo())
3611 for (SDUse &FlagUse :
User->uses()) {
3613 if (FlagUse.getResNo() != 1)
3616 if (!FlagUse.getUser()->isMachineOpcode())
3636bool X86DAGToDAGISel::hasNoSignFlagUses(SDValue Flags)
const {
3638 for (SDUse &Use :
Flags->uses()) {
3640 if (
Use.getResNo() !=
Flags.getResNo())
3648 for (SDUse &FlagUse :
User->uses()) {
3650 if (FlagUse.getResNo() != 1)
3653 if (!FlagUse.getUser()->isMachineOpcode())
3693 bool X86DAGToDAGISel::hasNoCarryFlagUses(SDValue Flags)
const {
3695 for (SDUse &Use :
Flags->uses()) {
3697 if (
Use.getResNo() !=
Flags.getResNo())
3701 unsigned UserOpc =
User->getOpcode();
3708 for (SDUse &FlagUse :
User->uses()) {
3710 if (FlagUse.getResNo() != 1)
3713 if (!FlagUse.getUser()->isMachineOpcode())
3733 case X86ISD::SETCC: CCOpNo = 0;
break;
3734 case X86ISD::SETCC_CARRY: CCOpNo = 0;
break;
3735 case X86ISD::CMOV: CCOpNo = 2;
break;
3736 case X86ISD::BRCOND: CCOpNo = 2;
break;
3749 unsigned Depth = 0) {
3770bool X86DAGToDAGISel::checkTCRetEnoughRegs(SDNode *
N)
const {
3771 assert(
N->getOpcode() == X86ISD::TC_RETURN);
3782 const X86RegisterInfo *RI = Subtarget->getRegisterInfo();
3786 if (Subtarget->is64Bit()) {
3789 ? &X86::GR64_TCW64RegClass
3790 : &X86::GR64_TCRegClass;
3798 ? &X86::GR32RegClass
3799 : &X86::GR32_TCRegClass;
3806 unsigned LoadGPRs = 2;
3808 if (Subtarget->is32Bit()) {
3813 }
else if (
BasePtr.getOpcode() == X86ISD::Wrapper &&
3815 if (getTargetMachine().isPositionIndependent())
3823 for (
unsigned I = 3,
E =
N->getNumOperands();
I !=
E; ++
I) {
3825 if (!RI->isGeneralPurposeRegister(*MF,
RN->getReg()))
3827 if (++
ArgGPRs + LoadGPRs > AvailGPRs)
3843 if (StoredVal.
getResNo() != 0)
return false;
3860 if (!
Load.hasOneUse())
3868 bool FoundLoad =
false;
3872 const unsigned int Max = 1024;
3914 if (Chain ==
Load.getValue(1)) {
3920 if (
Op ==
Load.getValue(1)) {
3936 if (
Op.getNode() != LoadNode)
3968bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3970 SDValue StoredVal = StoreNode->getOperand(1);
3976 EVT MemVT = StoreNode->getMemoryVT();
3977 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3981 bool IsCommutable =
false;
3982 bool IsNegate =
false;
3996 IsCommutable =
true;
4000 unsigned LoadOpNo = IsNegate ? 1 : 0;
4001 LoadSDNode *LoadNode =
nullptr;
4004 LoadNode, InputChain)) {
4011 LoadNode, InputChain))
4015 SDValue
Base, Scale,
Index, Disp, Segment;
4016 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
4020 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
4041 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
4043 const SDValue
Ops[] = {
Base, Scale,
Index, Disp, Segment, InputChain};
4044 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
4051 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
4055 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
4057 ((
Opc == X86ISD::ADD) == IsOne)
4058 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
4059 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
4060 const SDValue
Ops[] = {
Base, Scale,
Index, Disp, Segment, InputChain};
4061 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
4072 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
4075 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
4078 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
4081 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
4084 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
4087 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
4090 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
4092 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
4098 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
4101 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
4104 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
4107 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
4110 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
4113 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
4116 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
4119 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
4126 unsigned NewOpc = SelectRegOpcode(
Opc);
4127 SDValue Operand = StoredVal->
getOperand(1-LoadOpNo);
4132 int64_t OperandV = OperandC->getSExtValue();
4137 if ((
Opc == X86ISD::ADD ||
Opc == X86ISD::SUB) &&
4139 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
4141 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
4142 OperandV = -OperandV;
4143 Opc =
Opc == X86ISD::ADD ? X86ISD::SUB : X86ISD::ADD;
4146 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
4147 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
4148 NewOpc = SelectImmOpcode(
Opc);
4152 if (
Opc == X86ISD::ADC ||
Opc == X86ISD::SBB) {
4154 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
4158 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
4159 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
4163 Segment, Operand, InputChain};
4164 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
4173 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
4175 CurDAG->setNodeMemRefs(Result, MemOps);
4178 ReplaceUses(SDValue(LoadNode, 1), SDValue(Result, 1));
4179 ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));
4180 ReplaceUses(SDValue(StoredVal.
getNode(), 1), SDValue(Result, 0));
4181 CurDAG->RemoveDeadNode(Node);
4193bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
4196 "Should be either an and-mask, a standalone low-bits mask, or "
4197 "right-shift after clearing high bits.");
4200 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
4203 MVT NVT =
Node->getSimpleValueType(0);
4206 if (NVT != MVT::i32 && NVT != MVT::i64)
4214 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
4215 auto checkUses = [AllowExtraUsesByDefault](
4216 SDValue
Op,
unsigned NUses,
4217 std::optional<bool> AllowExtraUses) {
4218 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
4219 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
4221 auto checkOneUse = [checkUses](SDValue
Op,
4222 std::optional<bool> AllowExtraUses =
4224 return checkUses(
Op, 1, AllowExtraUses);
4226 auto checkTwoUse = [checkUses](SDValue
Op,
4227 std::optional<bool> AllowExtraUses =
4229 return checkUses(
Op, 2, AllowExtraUses);
4232 auto peekThroughOneUseTruncation = [checkOneUse](SDValue
V) {
4234 assert(
V.getSimpleValueType() == MVT::i32 &&
4235 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
4236 "Expected i64 -> i32 truncation");
4237 V =
V.getOperand(0);
4243 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
4244 &NegateNBits](SDValue
Mask) ->
bool {
4246 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
4252 SDValue
M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4257 NBits =
M0->getOperand(1);
4258 NegateNBits =
false;
4262 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](SDValue
V) {
4263 V = peekThroughOneUseTruncation(V);
4264 return CurDAG->MaskedValueIsAllOnes(
4270 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
4271 &NBits, &NegateNBits](SDValue
Mask) ->
bool {
4273 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
4276 if (!isAllOnes(
Mask->getOperand(1)))
4279 SDValue
M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4283 if (!isAllOnes(
M0->getOperand(0)))
4285 NBits =
M0->getOperand(1);
4286 NegateNBits =
false;
4292 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](SDValue ShiftAmt,
4293 unsigned Bitwidth) {
4298 NBits = NBits.getOperand(0);
4304 if (!V0 ||
V0->getZExtValue() != Bitwidth)
4306 NBits = NBits.getOperand(1);
4307 NegateNBits =
false;
4313 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
4314 canonicalizeShiftAmt](SDValue
Mask) ->
bool {
4316 Mask = peekThroughOneUseTruncation(Mask);
4317 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
4319 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
4324 SDValue
M1 =
Mask.getOperand(1);
4326 if (!checkOneUse(
M1))
4328 canonicalizeShiftAmt(
M1, Bitwidth);
4333 return !NegateNBits;
4341 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
4342 AllowExtraUsesByDefault, &NegateNBits,
4343 &
X](SDNode *
Node) ->
bool {
4346 SDValue N0 =
Node->getOperand(0);
4350 SDValue N1 =
Node->getOperand(1);
4355 canonicalizeShiftAmt(N1, Bitwidth);
4359 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
4360 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4366 auto matchLowBitMask = [matchPatternA, matchPatternB,
4367 matchPatternC](SDValue
Mask) ->
bool {
4368 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4372 X =
Node->getOperand(0);
4373 SDValue
Mask =
Node->getOperand(1);
4375 if (matchLowBitMask(Mask)) {
4379 if (!matchLowBitMask(Mask))
4382 }
else if (matchLowBitMask(SDValue(Node, 0))) {
4383 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4384 }
else if (!matchPatternD(Node))
4389 if (NegateNBits && !Subtarget->hasBMI2())
4394 if (NBits.getSimpleValueType() != MVT::i8) {
4401 ConstantSDNode *
Imm =
nullptr;
4402 if (NBits->getOpcode() ==
ISD::AND)
4404 NBits = NBits->getOperand(0);
4408 SDValue ImplDef = SDValue(
4409 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4412 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4414 NBits = SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4415 MVT::i32, ImplDef, NBits, SRIdxVal),
4421 CurDAG->getNode(
ISD::AND,
DL, MVT::i32, NBits,
4422 CurDAG->getConstant(
Imm->getZExtValue(),
DL, MVT::i32));
4429 SDValue BitWidthC = CurDAG->getConstant(NVT.
getSizeInBits(),
DL, MVT::i32);
4432 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4436 if (Subtarget->hasBMI2()) {
4438 if (NVT != MVT::i32) {
4444 SDValue Extract = CurDAG->getNode(X86ISD::BZHI,
DL, NVT,
X, NBits);
4445 ReplaceNode(Node, Extract.
getNode());
4446 SelectCode(Extract.
getNode());
4455 SDValue RealX = peekThroughOneUseTruncation(
X);
4461 MVT XVT =
X.getSimpleValueType();
4471 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4473 SDValue Control = CurDAG->getNode(
ISD::SHL,
DL, MVT::i32, NBits, C8);
4479 SDValue ShiftAmt =
X.getOperand(1);
4480 X =
X.getOperand(0);
4483 "Expected shift amount to be i8");
4487 SDValue OrigShiftAmt = ShiftAmt;
4492 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4497 if (XVT != MVT::i32) {
4503 SDValue Extract = CurDAG->getNode(X86ISD::BEXTR,
DL, XVT,
X, Control);
4511 ReplaceNode(Node, Extract.
getNode());
4512 SelectCode(Extract.
getNode());
4518MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4519 MVT NVT =
Node->getSimpleValueType(0);
4522 SDValue N0 =
Node->getOperand(0);
4523 SDValue N1 =
Node->getOperand(1);
4532 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4533 if (!PreferBEXTR && !Subtarget->hasBMI2())
4545 if (NVT != MVT::i32 && NVT != MVT::i64)
4551 if (!MaskCst || !ShiftCst)
4559 uint64_t Shift = ShiftCst->getZExtValue();
4564 if (Shift == 8 && MaskSize == 8)
4575 if (!PreferBEXTR && MaskSize <= 32)
4579 unsigned ROpc, MOpc;
4581#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4583 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4587 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4592 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4593 Control = SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4599 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4600 if (Subtarget->hasTBM()) {
4601 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4602 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4604 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4610 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4611 Control = SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4615 MachineSDNode *NewNode;
4617 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4618 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4620 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4621 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4622 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4624 ReplaceUses(Input.
getValue(1), SDValue(NewNode, 2));
4626 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4628 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4633 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4637 CurDAG->getMachineNode(NewOpc, dl, NVT, SDValue(NewNode, 0), ShAmt);
4644MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4645 bool MayFoldLoad,
const SDLoc &dl,
4646 MVT VT, SDNode *Node) {
4647 SDValue N0 =
Node->getOperand(0);
4648 SDValue N1 =
Node->getOperand(1);
4649 SDValue
Imm =
Node->getOperand(2);
4651 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4654 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4655 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4656 SDValue
Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4658 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4659 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4661 ReplaceUses(N1.
getValue(1), SDValue(CNode, 2));
4667 SDValue
Ops[] = { N0, N1,
Imm };
4668 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4669 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4676MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4677 bool MayFoldLoad,
const SDLoc &dl,
4678 MVT VT, SDNode *Node,
4680 SDValue N0 =
Node->getOperand(0);
4681 SDValue N2 =
Node->getOperand(2);
4682 SDValue
Imm =
Node->getOperand(4);
4684 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4687 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4688 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4689 SDValue
Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4691 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4692 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4693 InGlue = SDValue(CNode, 3);
4695 ReplaceUses(N2.
getValue(1), SDValue(CNode, 2));
4701 SDValue
Ops[] = { N0, N2,
Imm, InGlue };
4702 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4703 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4704 InGlue = SDValue(CNode, 2);
4708bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4709 EVT VT =
N->getValueType(0);
4716 unsigned Size = VT == MVT::i64 ? 64 : 32;
4719 SDValue ShiftAmt = OrigShiftAmt;
4729 SDValue NewShiftAmt;
4738 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4742 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4743 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4747 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4755 SDValue
AllOnes = CurDAG->getAllOnesConstant(
DL, OpVT);
4756 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4757 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4763 Add0C->getZExtValue() != 0) {
4766 if (Add0C->getZExtValue() %
Size == 0)
4769 Add0C->getZExtValue() % 32 == 0) {
4777 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4781 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4788 SDValue
Zero = CurDAG->getConstant(0,
DL, SubVT);
4789 SDValue Neg = CurDAG->getNode(
ISD::SUB,
DL, SubVT, Zero,
X);
4803 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4810 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4811 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4815 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4817 if (UpdatedNode !=
N) {
4820 ReplaceNode(
N, UpdatedNode);
4827 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4835bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4836 MVT NVT =
N->getSimpleValueType(0);
4837 unsigned Opcode =
N->getOpcode();
4842 SDValue Shift =
N->getOperand(0);
4849 int64_t Val = Cst->getSExtValue();
4854 bool FoundAnyExtend =
false;
4858 FoundAnyExtend =
true;
4866 if (NVT != MVT::i32 && NVT != MVT::i64)
4873 uint64_t ShAmt = ShlCst->getZExtValue();
4877 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4878 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4883 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4887 ShiftedVal = (
uint64_t)Val >> ShAmt;
4891 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4894 ShiftedVal = Val >> ShAmt;
4900 ShiftedVal = (
uint64_t)Val >> ShAmt;
4908 if (!CanShrinkImmediate(ShiftedVal))
4918 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4924 NeededMask &= ~Cst->getAPIntValue();
4926 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4931 if (FoundAnyExtend) {
4937 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4939 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4941 SDValue NewSHL = CurDAG->getNode(
ISD::SHL, dl, NVT, NewBinOp,
4948bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4949 SDNode *ParentB, SDNode *ParentC,
4950 SDValue
A, SDValue
B, SDValue
C,
4952 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4953 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4955 auto tryFoldLoadOrBCast =
4956 [
this](SDNode *Root, SDNode *
P, SDValue &
L, SDValue &
Base, SDValue &Scale,
4957 SDValue &
Index, SDValue &Disp, SDValue &Segment) {
4958 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4964 L =
L.getOperand(0);
4967 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
4972 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4976 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4979 bool FoldedLoad =
false;
4980 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4981 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4983 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4988 uint8_t OldImm =
Imm;
4989 Imm = OldImm & 0xa5;
4990 if (OldImm & 0x02)
Imm |= 0x10;
4991 if (OldImm & 0x10)
Imm |= 0x02;
4992 if (OldImm & 0x08)
Imm |= 0x40;
4993 if (OldImm & 0x40)
Imm |= 0x08;
4994 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4999 uint8_t OldImm =
Imm;
5000 Imm = OldImm & 0x99;
5001 if (OldImm & 0x02)
Imm |= 0x04;
5002 if (OldImm & 0x04)
Imm |= 0x02;
5003 if (OldImm & 0x20)
Imm |= 0x40;
5004 if (OldImm & 0x40)
Imm |= 0x20;
5009 SDValue TImm = CurDAG->getTargetConstant(
Imm,
DL, MVT::i8);
5013 MachineSDNode *MNode;
5015 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5018 if (
C.getOpcode() == X86ISD::VBROADCAST_LOAD) {
5020 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
5021 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
5023 bool UseD = EltSize == 32;
5025 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
5027 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
5029 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
5035 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
5037 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
5039 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
5044 SDValue
Ops[] = {
A,
B, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, TImm,
C.
getOperand(0)};
5045 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
5048 ReplaceUses(
C.getValue(1), SDValue(MNode, 1));
5055 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
5057 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
5059 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
5063 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
5066 ReplaceUses(SDValue(Root, 0), SDValue(MNode, 0));
5067 CurDAG->RemoveDeadNode(Root);
5073bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
5074 MVT NVT =
N->getSimpleValueType(0);
5077 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
5085 auto getFoldableLogicOp = [](SDValue
Op) {
5088 Op =
Op.getOperand(0);
5090 if (!
Op.hasOneUse())
5093 unsigned Opc =
Op.getOpcode();
5095 Opc == X86ISD::ANDNP)
5101 SDValue N0, N1,
A, FoldableOp;
5104 auto tryPeelOuterNotWrappingLogic = [&](SDNode *
Op) {
5107 SDValue InnerOp = getFoldableLogicOp(
Op->getOperand(0));
5114 if ((FoldableOp = getFoldableLogicOp(N1))) {
5118 if ((FoldableOp = getFoldableLogicOp(N0))) {
5126 bool PeeledOuterNot =
false;
5128 if (SDValue InnerOp = tryPeelOuterNotWrappingLogic(
N)) {
5129 PeeledOuterNot =
true;
5135 if ((FoldableOp = getFoldableLogicOp(N1)))
5137 else if ((FoldableOp = getFoldableLogicOp(N0)))
5145 SDNode *ParentA =
N;
5146 SDNode *ParentB = FoldableOp.
getNode();
5147 SDNode *ParentC = FoldableOp.
getNode();
5151 uint8_t TernlogMagicA = 0xf0;
5152 uint8_t TernlogMagicB = 0xcc;
5153 uint8_t TernlogMagicC = 0xaa;
5158 auto PeekThroughNot = [](SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
5162 Parent =
Op.getNode();
5163 Op =
Op.getOperand(0);
5167 PeekThroughNot(
A, ParentA, TernlogMagicA);
5168 PeekThroughNot(
B, ParentB, TernlogMagicB);
5169 PeekThroughNot(
C, ParentC, TernlogMagicC);
5174 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
5175 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
5176 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
5177 case X86ISD::ANDNP:
Imm = ~(TernlogMagicB) & TernlogMagicC;
break;
5180 switch (
N->getOpcode()) {
5184 Imm &= ~TernlogMagicA;
5186 Imm = ~(
Imm) & TernlogMagicA;
5196 return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC,
A,
B,
C,
Imm);
5206bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
5209 MVT VT =
And->getSimpleValueType(0);
5210 if (VT != MVT::i32 && VT != MVT::i64)
5222 APInt MaskVal = And1C->getAPIntValue();
5224 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
5228 if (VT == MVT::i64 && MaskLZ >= 32) {
5230 MaskVal = MaskVal.
trunc(32);
5233 SDValue And0 =
And->getOperand(0);
5235 APInt NegMaskVal = MaskVal | HighZeros;
5244 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
5245 NegMaskVal = NegMaskVal.
zext(64);
5246 HighZeros = HighZeros.
zext(64);
5252 KnownBits Known0 = CurDAG->computeKnownBits(And0);
5261 if (VT == MVT::i32 && !isDef32(And0.
getNode()))
5268 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
5270 SDValue NewAnd = CurDAG->getNode(
ISD::AND, SDLoc(
And), VT, And0, NewMask);
5277 bool FoldedBCast,
bool Masked) {
5278#define VPTESTM_CASE(VT, SUFFIX) \
5281 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
5282 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
5285#define VPTESTM_BROADCAST_CASES(SUFFIX) \
5286default: llvm_unreachable("Unexpected VT!"); \
5287VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
5288VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
5289VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
5290VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
5291VPTESTM_CASE(v16i32, DZ##SUFFIX) \
5292VPTESTM_CASE(v8i64, QZ##SUFFIX)
5294#define VPTESTM_FULL_CASES(SUFFIX) \
5295VPTESTM_BROADCAST_CASES(SUFFIX) \
5296VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
5297VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
5298VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
5299VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
5300VPTESTM_CASE(v64i8, BZ##SUFFIX) \
5301VPTESTM_CASE(v32i16, WZ##SUFFIX)
5319#undef VPTESTM_FULL_CASES
5320#undef VPTESTM_BROADCAST_CASES
5330 if (
Reg.isVirtual())
5335 if (GetPhysReg(N1) == LoReg && GetPhysReg(N0) != LoReg)
5341bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root, SDValue Setcc,
5343 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
5363 SDValue N0 = SetccOp0;
5374 SDValue N0Temp = N0;
5388 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P, SDValue &
L,
5389 SDValue &
Base, SDValue &Scale, SDValue &
Index,
5390 SDValue &Disp, SDValue &Segment) {
5393 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
5398 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
5404 L =
L.getOperand(0);
5407 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
5411 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5414 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5420 bool FoldedLoad =
false;
5421 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5423 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5427 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5434 bool FoldedBCast = FoldedLoad &&
Src1.getOpcode() == X86ISD::VBROADCAST_LOAD;
5436 bool IsMasked = InMask.
getNode() !=
nullptr;
5445 unsigned SubReg = CmpVT.
is128BitVector() ? X86::sub_xmm : X86::sub_ymm;
5449 SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5451 Src0 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src0);
5454 Src1 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src1);
5459 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5460 InMask = SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5461 dl, MaskVT, InMask, RC), 0);
5469 MachineSDNode *CNode;
5471 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5474 SDValue
Ops[] = { InMask,
Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5475 Src1.getOperand(0) };
5476 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5478 SDValue
Ops[] = {
Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5479 Src1.getOperand(0) };
5480 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5484 ReplaceUses(
Src1.getValue(1), SDValue(CNode, 1));
5486 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5489 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5491 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5497 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5498 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5499 dl, ResVT, SDValue(CNode, 0), RC);
5502 ReplaceUses(SDValue(Root, 0), SDValue(CNode, 0));
5503 CurDAG->RemoveDeadNode(Root);
5509bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5512 MVT NVT =
N->getSimpleValueType(0);
5515 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5549 SDValue
Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5550 SDValue Ternlog = CurDAG->getNode(X86ISD::VPTERNLOG, dl, NVT,
A,
B,
C,
Imm);
5557void X86DAGToDAGISel::Select(SDNode *Node) {
5558 MVT NVT =
Node->getSimpleValueType(0);
5559 unsigned Opcode =
Node->getOpcode();
5562 if (
Node->isMachineOpcode()) {
5564 Node->setNodeId(-1);
5571 unsigned IntNo =
Node->getConstantOperandVal(1);
5574 case Intrinsic::x86_encodekey128:
5575 case Intrinsic::x86_encodekey256: {
5576 if (!Subtarget->hasKL())
5582 case Intrinsic::x86_encodekey128:
5583 Opcode = X86::ENCODEKEY128;
5585 case Intrinsic::x86_encodekey256:
5586 Opcode = X86::ENCODEKEY256;
5590 SDValue Chain =
Node->getOperand(0);
5591 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5593 if (Opcode == X86::ENCODEKEY256)
5594 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5597 MachineSDNode *Res = CurDAG->getMachineNode(
5598 Opcode, dl,
Node->getVTList(),
5599 {Node->getOperand(2), Chain, Chain.getValue(1)});
5600 ReplaceNode(Node, Res);
5603 case Intrinsic::x86_tileloaddrs64_internal:
5604 case Intrinsic::x86_tileloaddrst164_internal:
5605 if (!Subtarget->hasAMXMOVRS())
5608 case Intrinsic::x86_tileloadd64_internal:
5609 case Intrinsic::x86_tileloaddt164_internal: {
5610 if (!Subtarget->hasAMXTILE())
5613 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5614 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5619 case Intrinsic::x86_tileloaddrs64_internal:
5620 Opc = X86::PTILELOADDRSV;
5622 case Intrinsic::x86_tileloaddrst164_internal:
5623 Opc = X86::PTILELOADDRST1V;
5625 case Intrinsic::x86_tileloadd64_internal:
5626 Opc = X86::PTILELOADDV;
5628 case Intrinsic::x86_tileloaddt164_internal:
5629 Opc = X86::PTILELOADDT1V;
5633 SDValue
Base =
Node->getOperand(4);
5634 SDValue Scale = getI8Imm(1, dl);
5636 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5637 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5638 SDValue Chain =
Node->getOperand(0);
5639 MachineSDNode *CNode;
5640 SDValue
Ops[] = {
Node->getOperand(2),
5641 Node->getOperand(3),
5648 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5649 ReplaceNode(Node, CNode);
5656 unsigned IntNo =
Node->getConstantOperandVal(1);
5659 case Intrinsic::x86_sse3_monitor:
5660 case Intrinsic::x86_monitorx:
5661 case Intrinsic::x86_clzero: {
5662 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5667 case Intrinsic::x86_sse3_monitor:
5668 if (!Subtarget->hasSSE3())
5670 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5672 case Intrinsic::x86_monitorx:
5673 if (!Subtarget->hasMWAITX())
5675 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5677 case Intrinsic::x86_clzero:
5678 if (!Subtarget->hasCLZERO())
5680 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5685 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5686 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5687 Node->getOperand(2), SDValue());
5688 SDValue InGlue = Chain.
getValue(1);
5690 if (IntNo == Intrinsic::x86_sse3_monitor ||
5691 IntNo == Intrinsic::x86_monitorx) {
5693 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5696 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5701 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5703 ReplaceNode(Node, CNode);
5709 case Intrinsic::x86_tilestored64_internal: {
5711 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5712 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5713 unsigned Opc = X86::PTILESTOREDV;
5715 SDValue
Base =
Node->getOperand(4);
5716 SDValue Scale = getI8Imm(1, dl);
5718 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5719 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5720 SDValue Chain =
Node->getOperand(0);
5721 MachineSDNode *CNode;
5722 SDValue
Ops[] = {
Node->getOperand(2),
5723 Node->getOperand(3),
5729 Node->getOperand(6),
5731 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5732 ReplaceNode(Node, CNode);
5735 case Intrinsic::x86_tileloaddrs64:
5736 case Intrinsic::x86_tileloaddrst164:
5737 if (!Subtarget->hasAMXMOVRS())
5740 case Intrinsic::x86_tileloadd64:
5741 case Intrinsic::x86_tileloaddt164:
5742 case Intrinsic::x86_tilestored64: {
5743 if (!Subtarget->hasAMXTILE())
5746 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5747 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5751 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5752 case Intrinsic::x86_tileloaddrs64:
5753 Opc = X86::PTILELOADDRS;
5755 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5756 case Intrinsic::x86_tileloaddrst164:
5757 Opc = X86::PTILELOADDRST1;
5759 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5762 unsigned TIndex =
Node->getConstantOperandVal(2);
5763 SDValue
TReg = getI8Imm(TIndex, dl);
5764 SDValue
Base =
Node->getOperand(3);
5765 SDValue Scale = getI8Imm(1, dl);
5767 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5768 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5769 SDValue Chain =
Node->getOperand(0);
5770 MachineSDNode *CNode;
5771 if (
Opc == X86::PTILESTORED) {
5773 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5776 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5778 ReplaceNode(Node, CNode);
5785 case X86ISD::NT_BRIND: {
5786 if (Subtarget->isTarget64BitILP32()) {
5791 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5792 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5795 unsigned Opc = Opcode == X86ISD::NT_BRIND ? X86::JMP64r_NT : X86::JMP64r;
5796 SDNode *Res = CurDAG->getMachineNode(
Opc, dl, MVT::Other, ZextTarget,
5797 Node->getOperand(0));
5798 ReplaceNode(Node, Res);
5804 ReplaceNode(Node, getGlobalBaseReg());
5811 ReplaceUses(SDValue(Node, 0),
Node->getOperand(0));
5812 CurDAG->RemoveDeadNode(Node);
5818 if (matchBitExtract(Node))
5823 if (tryShiftAmountMod(Node))
5827 case X86ISD::VPTERNLOG: {
5828 uint8_t
Imm =
Node->getConstantOperandVal(3);
5829 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5836 if (tryVPTERNLOG(Node))
5843 SDValue N0 =
Node->getOperand(0);
5844 SDValue N1 =
Node->getOperand(1);
5846 tryVPTESTM(Node, N0, N1))
5849 tryVPTESTM(Node, N1, N0))
5853 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5854 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
5855 CurDAG->RemoveDeadNode(Node);
5858 if (matchBitExtract(Node))
5860 if (Subtarget->getCLOpts().and_imm_shrink && shrinkAndImmediate(Node))
5867 if (Opcode ==
ISD::XOR && Subtarget->hasBMI2() && matchBitExtract(Node))
5871 if (tryShrinkShlLogicImm(Node))
5873 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5875 if (tryVPTERNLOG(Node))
5880 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5890 if (!CurDAG->shouldOptForSize())
5894 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5897 SDValue N0 =
Node->getOperand(0);
5898 SDValue N1 =
Node->getOperand(1);
5904 int64_t Val = Cst->getSExtValue();
5912 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5916 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5920 unsigned ROpc, MOpc;
6029 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6030 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6031 SDValue
Ops[] = { N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N0.
getOperand(0) };
6032 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
6033 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6035 ReplaceUses(N0.
getValue(1), SDValue(CNode, 2));
6038 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6039 CurDAG->RemoveDeadNode(Node);
6044 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
6053 case X86ISD::UMUL: {
6054 SDValue N0 =
Node->getOperand(0);
6055 SDValue N1 =
Node->getOperand(1);
6057 unsigned LoReg, ROpc, MOpc;
6062 ROpc = Opcode == X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
6063 MOpc = Opcode == X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
6082 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6083 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6086 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6094 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
6096 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
6097 N0, SDValue()).getValue(1);
6099 MachineSDNode *CNode;
6105 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
6107 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
6109 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.
getOperand(0),
6111 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6114 ReplaceUses(N1.
getValue(1), SDValue(CNode, NVT == MVT::i8 ? 2 : 3));
6122 VTs = CurDAG->getVTList(NVT, MVT::i32);
6124 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
6126 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
6129 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6130 ReplaceUses(SDValue(Node, 1), SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
6131 CurDAG->RemoveDeadNode(Node);
6137 SDValue N0 =
Node->getOperand(0);
6138 SDValue N1 =
Node->getOperand(1);
6141 unsigned LoReg, HiReg;
6143 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
6144 bool UseMULXHi = UseMULX && SDValue(Node, 0).use_empty();
6148 Opc = UseMULXHi ? X86::MULX32Hrr
6150 : IsSigned ?
X86::IMUL32r
6152 MOpc = UseMULXHi ? X86::MULX32Hrm
6154 : IsSigned ?
X86::IMUL32m
6156 LoReg = UseMULX ? X86::EDX : X86::EAX;
6160 Opc = UseMULXHi ? X86::MULX64Hrr
6162 : IsSigned ?
X86::IMUL64r
6164 MOpc = UseMULXHi ? X86::MULX64Hrm
6166 : IsSigned ?
X86::IMUL64m
6168 LoReg = UseMULX ? X86::RDX : X86::RAX;
6173 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6174 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6177 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6185 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
6187 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
6188 N0, SDValue()).getValue(1);
6189 SDValue ResHi, ResLo;
6192 MachineSDNode *CNode =
nullptr;
6193 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.
getOperand(0),
6196 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
6197 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6198 ResHi = SDValue(CNode, 0);
6199 Chain = SDValue(CNode, 1);
6200 }
else if (UseMULX) {
6201 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
6202 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6203 ResHi = SDValue(CNode, 0);
6204 ResLo = SDValue(CNode, 1);
6205 Chain = SDValue(CNode, 2);
6207 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6208 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6209 Chain = SDValue(CNode, 0);
6210 InGlue = SDValue(CNode, 1);
6214 ReplaceUses(N1.
getValue(1), Chain);
6218 SDValue
Ops[] = { N1, InGlue };
6220 SDVTList VTs = CurDAG->getVTList(NVT);
6221 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
6222 ResHi = SDValue(CNode, 0);
6223 }
else if (UseMULX) {
6224 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
6225 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
6226 ResHi = SDValue(CNode, 0);
6227 ResLo = SDValue(CNode, 1);
6229 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
6230 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
6231 InGlue = SDValue(CNode, 0);
6236 if (!SDValue(Node, 0).use_empty()) {
6238 assert(LoReg &&
"Register for low half is not defined!");
6239 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
6243 ReplaceUses(SDValue(Node, 0), ResLo);
6248 if (!SDValue(Node, 1).use_empty()) {
6250 assert(HiReg &&
"Register for high half is not defined!");
6251 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
6255 ReplaceUses(SDValue(Node, 1), ResHi);
6260 CurDAG->RemoveDeadNode(Node);
6266 SDValue N0 =
Node->getOperand(0);
6267 SDValue N1 =
Node->getOperand(1);
6269 unsigned ROpc, MOpc;
6274 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
6275 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
6276 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
6277 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
6282 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
6283 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
6284 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
6285 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
6289 unsigned LoReg, HiReg, ClrReg;
6290 unsigned SExtOpcode;
6294 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
6298 LoReg = X86::AX; HiReg = X86::DX;
6300 SExtOpcode = X86::CWD;
6303 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
6304 SExtOpcode = X86::CDQ;
6307 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
6308 SExtOpcode = X86::CQO;
6312 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6313 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6314 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
6317 if (NVT == MVT::i8) {
6320 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
6321 MachineSDNode *Move;
6322 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6323 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N0.
getOperand(0) };
6324 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rm8
6326 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
6327 Chain = SDValue(Move, 1);
6328 ReplaceUses(N0.
getValue(1), Chain);
6332 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rr8
6334 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
6335 Chain = CurDAG->getEntryNode();
6337 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX, SDValue(Move, 0),
6342 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
6343 LoReg, N0, SDValue()).getValue(1);
6347 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
6350 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
6352 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
6356 SDValue(CurDAG->getMachineNode(
6357 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
6358 CurDAG->getTargetConstant(X86::sub_16bit, dl,
6366 CurDAG->getMachineNode(
6367 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, ClrNode,
6368 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
6375 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
6376 ClrNode, InGlue).getValue(1);
6381 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.
getOperand(0),
6383 MachineSDNode *CNode =
6384 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
6385 InGlue = SDValue(CNode, 1);
6387 ReplaceUses(N1.
getValue(1), SDValue(CNode, 0));
6392 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
6402 if (HiReg == X86::AH && !SDValue(Node, 1).use_empty()) {
6403 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
6404 unsigned AHExtOpcode =
6405 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6407 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6408 MVT::Glue, AHCopy, InGlue);
6409 SDValue
Result(RNode, 0);
6410 InGlue = SDValue(RNode, 1);
6413 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6415 ReplaceUses(SDValue(Node, 1), Result);
6420 if (!SDValue(Node, 0).use_empty()) {
6421 SDValue
Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6422 LoReg, NVT, InGlue);
6423 InGlue =
Result.getValue(2);
6424 ReplaceUses(SDValue(Node, 0), Result);
6429 if (!SDValue(Node, 1).use_empty()) {
6430 SDValue
Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6431 HiReg, NVT, InGlue);
6432 InGlue =
Result.getValue(2);
6433 ReplaceUses(SDValue(Node, 1), Result);
6437 CurDAG->RemoveDeadNode(Node);
6442 case X86ISD::STRICT_FCMP:
6443 case X86ISD::STRICT_FCMPS: {
6444 bool IsStrictCmp =
Node->getOpcode() == X86ISD::STRICT_FCMP ||
6445 Node->getOpcode() == X86ISD::STRICT_FCMPS;
6446 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6447 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6453 if (Subtarget->canUseCMOV())
6456 bool IsSignaling =
Node->getOpcode() == X86ISD::STRICT_FCMPS;
6462 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6465 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6468 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6473 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6476 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6477 Chain = SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6480 Glue = SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6485 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6489 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6493 assert(Subtarget->canUseLAHFSAHF() &&
6494 "Target doesn't support SAHF or FCOMI?");
6495 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract, SDValue());
6497 SDValue SAHF = SDValue(
6498 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6501 ReplaceUses(SDValue(Node, 1), Chain);
6503 ReplaceUses(SDValue(Node, 0), SAHF);
6504 CurDAG->RemoveDeadNode(Node);
6509 SDValue N0 =
Node->getOperand(0);
6510 SDValue N1 =
Node->getOperand(1);
6524 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6525 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6527 SDValue BEXTR = SDValue(NewNode, 0);
6528 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6529 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
6530 CurDAG->RemoveDeadNode(Node);
6557 onlyUsesZeroFlag(SDValue(Node, 0))) {
6562 unsigned TestOpcode;
6570 if (LeadingZeros == 0 && SavesBytes) {
6575 ShiftAmt = TrailingZeros;
6577 TestOpcode = X86::TEST64rr;
6578 }
else if (TrailingZeros == 0 && SavesBytes) {
6584 if (LeadingZeros == 1) {
6588 MachineSDNode *
Add = CurDAG->getMachineNode(
6591 MachineSDNode *
Test = CurDAG->getMachineNode(
6592 X86::TEST64rr, dl, MVT::i32, SDValue(
Add, 0), SDValue(
Add, 0));
6593 ReplaceNode(Node,
Test);
6597 ShiftAmt = LeadingZeros;
6599 TestOpcode = X86::TEST64rr;
6600 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6603 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6604 if (PopCount == 8) {
6606 ShiftAmt = TrailingZeros;
6607 SubRegIdx = X86::sub_8bit;
6609 TestOpcode = X86::TEST8rr;
6610 }
else if (PopCount == 16) {
6612 ShiftAmt = TrailingZeros;
6613 SubRegIdx = X86::sub_16bit;
6614 SubRegVT = MVT::i16;
6615 TestOpcode = X86::TEST16rr;
6616 }
else if (PopCount == 32) {
6618 ShiftAmt = TrailingZeros;
6619 SubRegIdx = X86::sub_32bit;
6620 SubRegVT = MVT::i32;
6621 TestOpcode = X86::TEST32rr;
6625 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6626 SDValue Shift = SDValue(
6627 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6630 if (SubRegIdx != 0) {
6632 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6634 MachineSDNode *
Test =
6635 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6636 ReplaceNode(Node,
Test);
6643 unsigned ROpc, MOpc;
6651 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6652 hasNoSignFlagUses(SDValue(Node, 0)))) {
6655 SubRegOp = X86::sub_8bit;
6656 ROpc = X86::TEST8ri;
6657 MOpc = X86::TEST8mi;
6658 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6659 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6660 hasNoSignFlagUses(SDValue(Node, 0)))) {
6666 SubRegOp = X86::sub_16bit;
6667 ROpc = X86::TEST16ri;
6668 MOpc = X86::TEST16mi;
6670 ((!(Mask & 0x80000000) &&
6673 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6674 CmpVT == MVT::i32 ||
6675 hasNoSignFlagUses(SDValue(Node, 0)))) {
6682 SubRegOp = X86::sub_32bit;
6683 ROpc = X86::TEST32ri;
6684 MOpc = X86::TEST32mi;
6690 SDValue
Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6694 MachineSDNode *NewNode;
6695 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6696 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6698 if (!LoadN->isSimple()) {
6699 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6700 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6701 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6702 (MOpc == X86::TEST32mi && NumVolBits != 32))
6706 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
6707 Reg.getOperand(0) };
6708 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6710 ReplaceUses(
Reg.getValue(1), SDValue(NewNode, 1));
6712 CurDAG->setNodeMemRefs(NewNode,
6717 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6719 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg,
Imm);
6722 ReplaceNode(Node, NewNode);
6728 if (!Subtarget->hasSSE42())
6731 bool NeedIndex = !SDValue(Node, 0).use_empty();
6732 bool NeedMask = !SDValue(Node, 1).use_empty();
6734 bool MayFoldLoad = !NeedIndex || !
NeedMask;
6736 MachineSDNode *CNode;
6739 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6741 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6742 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6743 ReplaceUses(SDValue(Node, 1), SDValue(CNode, 0));
6745 if (NeedIndex || !NeedMask) {
6747 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6749 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6750 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6751 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6755 ReplaceUses(SDValue(Node, 2), SDValue(CNode, 1));
6756 CurDAG->RemoveDeadNode(Node);
6760 if (!Subtarget->hasSSE42())
6764 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6765 Node->getOperand(1),
6766 SDValue()).getValue(1);
6767 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6768 Node->getOperand(3), InGlue).getValue(1);
6770 bool NeedIndex = !SDValue(Node, 0).use_empty();
6771 bool NeedMask = !SDValue(Node, 1).use_empty();
6773 bool MayFoldLoad = !NeedIndex || !
NeedMask;
6775 MachineSDNode *CNode;
6778 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6780 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6782 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6783 ReplaceUses(SDValue(Node, 1), SDValue(CNode, 0));
6785 if (NeedIndex || !NeedMask) {
6787 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6789 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6790 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6791 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6794 ReplaceUses(SDValue(Node, 2), SDValue(CNode, 1));
6795 CurDAG->RemoveDeadNode(Node);
6800 if (NVT.
isVector() && tryVPTESTM(Node, SDValue(Node, 0), SDValue()))
6807 if (foldLoadStoreIntoMemOperand(Node))
6811 case X86ISD::SETCC_CARRY: {
6812 MVT VT =
Node->getSimpleValueType(0);
6814 if (Subtarget->hasSBBDepBreaking()) {
6819 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6820 Node->getOperand(1), SDValue());
6824 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6825 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6827 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6832 Result = getSBBZero(Node);
6836 if (VT == MVT::i8 || VT == MVT::i16) {
6837 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6838 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6841 ReplaceUses(SDValue(Node, 0), Result);
6842 CurDAG->RemoveDeadNode(Node);
6848 SDValue
Result = getSBBZero(Node);
6851 ReplaceUses(SDValue(Node, 1),
Result.getValue(1));
6854 if (!SDValue(Node, 0).use_empty()) {
6856 MVT VT =
Node->getSimpleValueType(0);
6857 if (VT == MVT::i8 || VT == MVT::i16) {
6858 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6859 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6861 ReplaceUses(SDValue(Node, 0), Result);
6864 CurDAG->RemoveDeadNode(Node);
6871 SDValue IndexOp = Mgt->getIndex();
6872 SDValue
Mask = Mgt->getMask();
6874 MVT ValueVT =
Node->getSimpleValueType(0);
6875 MVT MaskVT =
Mask.getSimpleValueType();
6892 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6893 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6894 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6895 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6896 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6897 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6898 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6899 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6900 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6901 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6902 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6903 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6904 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6905 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6906 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6907 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6908 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6909 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6910 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6911 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6912 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6913 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6914 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6915 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6917 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6918 "Unexpected mask VT!");
6919 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6920 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6921 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6922 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6923 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6924 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6925 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6926 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6927 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6928 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6929 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6930 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6931 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6932 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6933 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6934 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6940 SDValue
Base, Scale,
Index, Disp, Segment;
6941 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6942 Base, Scale, Index, Disp, Segment))
6945 SDValue PassThru = Mgt->getPassThru();
6946 SDValue Chain = Mgt->getChain();
6948 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6950 MachineSDNode *NewNode;
6953 Index, Disp, Segment, Chain};
6954 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6957 Disp, Segment,
Mask, Chain};
6958 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6960 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6961 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
6962 ReplaceUses(SDValue(Node, 1), SDValue(NewNode, 2));
6963 CurDAG->RemoveDeadNode(Node);
6968 SDValue
Value = Sc->getValue();
6969 SDValue IndexOp = Sc->getIndex();
6971 MVT ValueVT =
Value.getSimpleValueType();
6986 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6987 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6988 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6989 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6990 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6991 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6992 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6993 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6994 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6995 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6996 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6997 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6998 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6999 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
7000 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
7001 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
7002 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
7003 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
7004 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
7005 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
7006 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
7007 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
7008 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
7009 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
7013 SDValue
Base, Scale,
Index, Disp, Segment;
7014 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
7015 Base, Scale, Index, Disp, Segment))
7018 SDValue
Mask = Sc->getMask();
7019 SDValue Chain = Sc->getChain();
7021 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
7024 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
7025 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
7026 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 1));
7027 CurDAG->RemoveDeadNode(Node);
7031 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
7032 auto CallId = MFI->getPreallocatedIdForCallSite(
7034 SDValue Chain =
Node->getOperand(0);
7035 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
7036 MachineSDNode *
New = CurDAG->getMachineNode(
7037 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
7038 ReplaceUses(SDValue(Node, 0), SDValue(New, 0));
7039 CurDAG->RemoveDeadNode(Node);
7043 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
7046 SDValue Chain =
Node->getOperand(0);
7047 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
7048 SDValue ArgIndex =
Node->getOperand(2);
7050 Ops[0] = CallIdValue;
7053 MachineSDNode *
New = CurDAG->getMachineNode(
7054 TargetOpcode::PREALLOCATED_ARG, dl,
7055 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
7058 ReplaceUses(SDValue(Node, 0), SDValue(New, 0));
7059 ReplaceUses(SDValue(Node, 1), SDValue(New, 1));
7060 CurDAG->RemoveDeadNode(Node);
7067 if (!Subtarget->hasWIDEKL())
7071 switch (
Node->getOpcode()) {
7075 Opcode = X86::AESENCWIDE128KL;
7078 Opcode = X86::AESDECWIDE128KL;
7081 Opcode = X86::AESENCWIDE256KL;
7084 Opcode = X86::AESDECWIDE256KL;
7088 SDValue Chain =
Node->getOperand(0);
7089 SDValue Addr =
Node->getOperand(1);
7091 SDValue
Base, Scale,
Index, Disp, Segment;
7092 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
7095 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
7097 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
7099 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
7101 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
7103 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
7105 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
7107 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
7109 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
7112 MachineSDNode *Res = CurDAG->getMachineNode(
7113 Opcode, dl,
Node->getVTList(),
7114 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
7116 ReplaceNode(Node, Res);
7120 SDValue Chain =
Node->getOperand(0);
7123 if (
Node->getNumValues() == 3)
7124 Glue =
Node->getOperand(2);
7126 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
7127 ReplaceNode(Node,
Copy.getNode());
7135bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
7137 std::vector<SDValue> &OutOps) {
7138 SDValue Op0, Op1, Op2, Op3, Op4;
7139 switch (ConstraintID) {
7142 case InlineAsm::ConstraintCode::o:
7143 case InlineAsm::ConstraintCode::v:
7144 case InlineAsm::ConstraintCode::m:
7145 case InlineAsm::ConstraintCode::X:
7146 case InlineAsm::ConstraintCode::p:
7147 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
7152 OutOps.push_back(Op0);
7153 OutOps.push_back(Op1);
7154 OutOps.push_back(Op2);
7155 OutOps.push_back(Op3);
7156 OutOps.push_back(Op4);
7162 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
7168 return new X86DAGToDAGISelLegacy(TM, OptLevel);
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
#define CASE(ATTRNAME, AANAME,...)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isSigned(unsigned Opcode)
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
const MCPhysReg ArgGPRs[]
static bool isUndef(const MachineInstr &MI)
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static bool isFusableLoadOpStorePattern(StoreSDNode *StoreNode, SDValue StoredVal, SelectionDAG *CurDAG, LoadSDNode *&LoadNode, SDValue &InputChain)
static void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N)
static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII)
Check if the instruction uses RIP relative addressing.
#define FROM_TO(FROM, TO)
#define GET_EGPR_IF_ENABLED(OPC)
static bool isLegalMaskCompare(SDNode *N, const X86Subtarget *Subtarget)
static bool foldMaskAndShiftToScale(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static bool foldMaskAndShiftToExtract(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static bool addrMayUseNonFixedFrameIndex(SDValue Addr, const MachineFrameInfo &MFI, unsigned Depth=0)
Return true if Addr may be matched with a non-fixed frame index as base.
static bool needBWI(MVT VT)
static unsigned getVPTESTMOpc(MVT TestVT, bool IsTestN, bool FoldedLoad, bool FoldedBCast, bool Masked)
#define GET_NDM_IF_ENABLED(OPC)
static bool foldMaskedShiftToBEXTR(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM, const X86Subtarget &Subtarget)
static bool mayUseCarryFlag(X86::CondCode CC)
static bool isEndbrImm(uint64_t Imm, unsigned BitWidth)
static void moveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load, SDValue Call, SDValue OrigChain)
Replace the original chain operand of the call with load's chain operand and move load below the call...
#define GET_ND_IF_ENABLED(OPC)
#define VPTESTM_BROADCAST_CASES(SUFFIX)
static SDValue getLowSubvectorMaskCompare(SDValue V, const X86Subtarget *Subtarget)
static bool foldMaskedShiftToScaledMask(SelectionDAG &DAG, SDValue N, X86ISelAddressMode &AM)
#define VPTESTM_FULL_CASES(SUFFIX)
static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq)
Return true if call address is a load and it can be moved below CALLSEQ_START and the chains leading ...
static bool isDispSafeForFrameIndexOrRegBase(int64_t Val)
static void orderRegForMul(SDValue &N0, SDValue &N1, const unsigned LoReg, const MachineRegisterInfo &MRI)
#define GET_ND_IF_ENABLED(OPC)
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countl_zero() const
The APInt version of std::countl_zero.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
bool isOne() const
Determine if this is a value of 1.
unsigned countr_one() const
Count the number of trailing one bits.
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI std::optional< ConstantRange > getAbsoluteSymbolRange() const
If this is an absolute symbol reference, returns the range of the symbol, otherwise returns std::null...
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
unsigned getID() const
getID() - Return the register class ID number.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
bool isVectorOf(MVT EltVT) const
Return true if this is a vector with matching element type.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool is512BitVector() const
Return true if this is a 512-bit vector type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MVT getHalfNumVectorElementsVT() const
Return a VT for a vector type with the same element type but half the number of elements.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MCRegister getLiveInPhysReg(Register VReg) const
getLiveInPhysReg - If VReg is a live-in virtual register, return the corresponding live-in physical r...
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
bool isNonTemporal() const
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
int getNodeId() const
Return the unique node id.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
SDNodeFlags getFlags() const
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
iterator_range< user_iterator > users()
op_iterator op_end() const
op_iterator op_begin() const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISelPass(std::unique_ptr< SelectionDAGISel > Selector)
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
static int getUninvalidatedNodeId(SDNode *N)
virtual bool runOnMachineFunction(MachineFunction &mf)
static void InvalidateNodeId(SDNode *N)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
void RepositionNode(allnodes_iterator Position, SDNode *N)
Move node N in the AllNodes list to be immediately before the given iterator Position.
ilist< SDNode >::iterator allnodes_iterator
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool hasOneUse() const
Return true if there is exactly one use of this value.
X86ISelDAGToDAGPass(X86TargetMachine &TM)
size_t getPreallocatedIdForCallSite(const Value *CS)
bool isScalarFPTypeInSSEReg(EVT VT) const
Return true if the specified scalar FP type is computed in an SSE register, not on the X87 floating p...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ PREALLOCATED_SETUP
PREALLOCATED_SETUP - This has 2 operands: an input chain and a SRCVALUE with the preallocated call Va...
@ PREALLOCATED_ARG
PREALLOCATED_ARG - This has 3 operands: an input chain, a SRCVALUE with the preallocated call Value,...
@ BRIND
BRIND - Indirect branch.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ LOCAL_RECOVER
LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ X86
Windows x64, Windows Itanium (IA-64)
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
int getMemoryOperandNo(uint64_t TSFlags)
@ GlobalBaseReg
On Darwin, this node represents the result of the popl at function entry, used for PIC code.
@ POP_FROM_X87_REG
The same as ISD::CopyFromReg except that this node makes it explicit that it may lower to an x87 FPU ...
int getCondSrcNoFromDesc(const MCInstrDesc &MCID)
Return the source operand # for condition code by MCID.
bool mayFoldLoad(SDValue Op, const X86Subtarget &Subtarget, bool AssumeSingleUse=false, bool IgnoreAlignment=false)
Check if Op is a load operation that could be folded into some other x86 instruction as a memory oper...
bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M, bool hasSymbolicDisplacement)
Returns true of the given offset can be fit into displacement field of the instruction.
bool isConstantSplat(SDValue Op, APInt &SplatVal, bool AllowPartialUndefs)
If Op is a constant whose elements are all the same constant or undefined, return true and return the...
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
bool isa_and_nonnull(const Y &Val)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
unsigned M1(unsigned Val)
auto dyn_cast_or_null(const Y &Val)
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
FunctionPass * createX86ISelDag(X86TargetMachine &TM, CodeGenOptLevel OptLevel)
This pass converts a legalized DAG into a X86-specific DAG, ready for instruction scheduling.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
bool isVector() const
Return true if this is a vector value type.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
bool isConstant() const
Returns true if we know the value of all bits.
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
bool hasNoUnsignedWrap() const