21#include "llvm/Config/llvm-config.h"
26#include "llvm/IR/IntrinsicsX86.h"
37#define DEBUG_TYPE "x86-isel"
38#define PASS_NAME "X86 DAG->DAG Instruction Selection"
40STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
43 cl::desc(
"Enable setting constant bits to reduce size of mask immediates"),
47 "x86-promote-anyext-load",
cl::init(
true),
59 struct X86ISelAddressMode {
67 int Base_FrameIndex = 0;
73 const GlobalValue *GV =
nullptr;
76 const char *ES =
nullptr;
81 bool NegateIndex =
false;
83 X86ISelAddressMode() =
default;
85 bool hasSymbolicDisplacement()
const {
86 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr ||
87 MCSym !=
nullptr || JT != -1 || BlockAddr !=
nullptr;
90 bool hasBaseOrIndexReg()
const {
91 return BaseType == FrameIndexBase ||
92 IndexReg.getNode() !=
nullptr || Base_Reg.getNode() !=
nullptr;
97 if (BaseType != RegBase)
return false;
98 if (RegisterSDNode *RegNode =
100 return RegNode->getReg() == X86::RIP;
109#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
110 void dump(SelectionDAG *DAG =
nullptr) {
111 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
112 dbgs() <<
"Base_Reg ";
113 if (Base_Reg.getNode())
114 Base_Reg.getNode()->dump(DAG);
117 if (BaseType == FrameIndexBase)
118 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
119 dbgs() <<
" Scale " << Scale <<
'\n'
123 if (IndexReg.getNode())
124 IndexReg.getNode()->dump(DAG);
127 dbgs() <<
" Disp " << Disp <<
'\n'
149 dbgs() <<
" JT" << JT <<
" Align" << Alignment.value() <<
'\n';
163 const X86Subtarget *Subtarget;
169 bool IndirectTlsSegRefs;
172 X86DAGToDAGISel() =
delete;
174 explicit X86DAGToDAGISel(X86TargetMachine &tm,
CodeGenOptLevel OptLevel)
175 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr),
176 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
178 bool runOnMachineFunction(MachineFunction &MF)
override {
182 "indirect-tls-seg-refs");
189 void emitFunctionEntryCode()
override;
191 bool IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const override;
193 void PreprocessISelDAG()
override;
194 void PostprocessISelDAG()
override;
197#include "X86GenDAGISel.inc"
200 void Select(SDNode *
N)
override;
202 bool foldOffsetIntoAddress(uint64_t
Offset, X86ISelAddressMode &AM);
203 bool matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
204 bool AllowSegmentRegForX32 =
false);
205 bool matchWrapper(
SDValue N, X86ISelAddressMode &AM);
206 bool matchAddress(
SDValue N, X86ISelAddressMode &AM);
207 bool matchVectorAddress(
SDValue N, X86ISelAddressMode &AM);
208 bool matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
211 bool matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
213 bool matchVectorAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
215 bool matchAddressBase(
SDValue N, X86ISelAddressMode &AM);
218 bool HasNDDM =
true);
221 bool selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
SDValue IndexOp,
235 bool tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
245 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
248 bool tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
253 bool isProfitableToFormMaskedOp(SDNode *
N)
const;
256 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
258 std::vector<SDValue> &OutOps)
override;
260 void emitSpecialCodeForMain();
262 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
266 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
267 Base = CurDAG->getTargetFrameIndex(
268 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
269 else if (AM.Base_Reg.
getNode())
272 Base = CurDAG->getRegister(0, VT);
274 Scale = getI8Imm(AM.Scale,
DL);
276#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
277#define GET_NDM_IF_ENABLED(OPC) \
278 (Subtarget->hasNDD() && Subtarget->hasNDDM() ? OPC##_ND : OPC)
280 if (AM.NegateIndex) {
306 Index = CurDAG->getRegister(0, VT);
311 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(),
315 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
316 AM.Disp, AM.SymbolFlags);
318 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
319 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
320 }
else if (AM.MCSym) {
321 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
322 assert(AM.SymbolFlags == 0 &&
"oo");
323 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
324 }
else if (AM.JT != -1) {
325 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
326 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
327 }
else if (AM.BlockAddr)
328 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
331 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
334 Segment = AM.Segment;
336 Segment = CurDAG->getRegister(0, MVT::i16);
341 bool isAMXSDNode(SDNode *
N)
const {
345 for (
unsigned Idx = 0,
E =
N->getNumValues(); Idx !=
E; ++Idx) {
346 if (
N->getValueType(Idx) == MVT::x86amx)
349 for (
unsigned Idx = 0,
E =
N->getNumOperands(); Idx !=
E; ++Idx) {
351 if (
Op.getValueType() == MVT::x86amx)
363 bool shouldAvoidImmediateInstFormsForSize(SDNode *
N)
const {
364 uint32_t UseCount = 0;
369 if (!CurDAG->shouldOptForSize())
373 for (
const SDNode *User :
N->users()) {
379 if (
User->isMachineOpcode()) {
386 User->getOperand(1).getNode() ==
N) {
397 if (
User->getNumOperands() != 2)
410 if (
User->getOpcode() == X86ISD::ADD ||
412 User->getOpcode() == X86ISD::SUB ||
418 OtherOp =
User->getOperand(1);
421 RegisterSDNode *RegNode;
425 if ((RegNode->
getReg() == X86::ESP) ||
426 (RegNode->
getReg() == X86::RSP))
435 return (UseCount > 1);
439 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &
DL) {
440 return CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
444 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &
DL) {
445 return CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
449 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &
DL) {
450 return CurDAG->getTargetConstant(Imm,
DL, MVT::i64);
453 SDValue getExtractVEXTRACTImmediate(SDNode *
N,
unsigned VecWidth,
455 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
456 uint64_t
Index =
N->getConstantOperandVal(1);
457 MVT VecVT =
N->getOperand(0).getSimpleValueType();
461 SDValue getInsertVINSERTImmediate(SDNode *
N,
unsigned VecWidth,
463 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
464 uint64_t
Index =
N->getConstantOperandVal(2);
465 MVT VecVT =
N->getSimpleValueType(0);
469 SDValue getPermuteVINSERTCommutedImmediate(SDNode *
N,
unsigned VecWidth,
471 assert(VecWidth == 128 &&
"Unexpected vector width");
472 uint64_t
Index =
N->getConstantOperandVal(2);
473 MVT VecVT =
N->getSimpleValueType(0);
475 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
478 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
483 MVT VT =
N->getSimpleValueType(0);
486 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
488 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
489 if (VT == MVT::i64) {
491 CurDAG->getMachineNode(
492 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, Zero,
493 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
498 unsigned Opcode =
N->getOpcode();
499 assert((Opcode == X86ISD::SBB || Opcode == X86ISD::SETCC_CARRY) &&
500 "Unexpected opcode for SBB materialization");
501 unsigned FlagOpIndex = Opcode == X86ISD::SBB ? 2 : 1;
503 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
504 N->getOperand(FlagOpIndex),
SDValue());
508 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
509 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
510 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
512 CurDAG->getMachineNode(
Opc, dl, VTs,
513 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
519 bool isUnneededShiftMask(SDNode *
N,
unsigned Width)
const {
521 const APInt &Val =
N->getConstantOperandAPInt(1);
526 APInt
Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
527 return Mask.countr_one() >= Width;
533 SDNode *getGlobalBaseReg();
537 const X86TargetMachine &getTargetMachine()
const {
538 return static_cast<const X86TargetMachine &
>(TM);
543 const X86InstrInfo *getInstrInfo()
const {
544 return Subtarget->getInstrInfo();
553 bool ComplexPatternFuncMutatesDAG()
const override {
557 bool isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const;
560 bool useNonTemporalLoad(LoadSDNode *
N)
const {
561 if (!
N->isNonTemporal())
564 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
566 if (
N->getAlign().value() < StoreSize)
575 return Subtarget->hasSSE41();
577 return Subtarget->hasAVX2();
579 return Subtarget->hasAVX512();
583 bool foldLoadStoreIntoMemOperand(SDNode *Node);
584 MachineSDNode *matchBEXTRFromAndImm(SDNode *Node);
585 bool matchBitExtract(SDNode *Node);
586 bool shrinkAndImmediate(SDNode *
N);
587 bool isMaskZeroExtended(SDNode *
N)
const;
588 bool tryShiftAmountMod(SDNode *
N);
589 bool tryShrinkShlLogicImm(SDNode *
N);
590 bool tryVPTERNLOG(SDNode *
N);
591 bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentB,
595 bool tryMatchBitSelect(SDNode *
N);
597 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
598 const SDLoc &dl, MVT VT, SDNode *Node);
599 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
600 const SDLoc &dl, MVT VT, SDNode *Node,
603 bool tryOptimizeRem8Extend(SDNode *
N);
605 bool onlyUsesZeroFlag(
SDValue Flags)
const;
606 bool hasNoSignFlagUses(
SDValue Flags)
const;
607 bool hasNoCarryFlagUses(
SDValue Flags)
const;
608 bool checkTCRetEnoughRegs(SDNode *
N)
const;
614 explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm,
616 : SelectionDAGISelLegacy(
617 ID, std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
621char X86DAGToDAGISelLegacy::ID = 0;
628 unsigned Opcode =
N->getOpcode();
629 if (Opcode == X86ISD::CMPM || Opcode == X86ISD::CMPMM ||
630 Opcode == X86ISD::STRICT_CMPM || Opcode ==
ISD::SETCC ||
631 Opcode == X86ISD::CMPMM_SAE || Opcode == X86ISD::VFPCLASS) {
635 EVT OpVT =
N->getOperand(0).getValueType();
638 if (Opcode == X86ISD::STRICT_CMPM)
639 OpVT =
N->getOperand(1).getValueType();
641 return Subtarget->hasVLX();
646 if (Opcode == X86ISD::VFPCLASSS || Opcode == X86ISD::FSETCCM ||
647 Opcode == X86ISD::FSETCCM_SAE)
655bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
667X86DAGToDAGISel::IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const {
668 if (OptLevel == CodeGenOptLevel::None)
683 switch (
U->getOpcode()) {
710 if (
Imm->getAPIntValue().isSignedIntN(8))
719 Imm->getAPIntValue().getBitWidth() == 64 &&
720 Imm->getAPIntValue().isIntN(32))
727 (
Imm->getAPIntValue() == UINT8_MAX ||
728 Imm->getAPIntValue() == UINT16_MAX ||
729 Imm->getAPIntValue() == UINT32_MAX))
735 (-
Imm->getAPIntValue()).isSignedIntN(8))
738 if ((
U->getOpcode() == X86ISD::ADD ||
U->getOpcode() == X86ISD::SUB) &&
739 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
740 hasNoCarryFlagUses(
SDValue(U, 1)))
754 if (Op1.
getOpcode() == X86ISD::Wrapper) {
765 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
769 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
778 if (
C &&
C->getSExtValue() == -2)
784 if (
C &&
C->getSExtValue() == -2)
819bool X86DAGToDAGISel::isProfitableToFormMaskedOp(SDNode *
N)
const {
821 (
N->getOpcode() ==
ISD::VSELECT ||
N->getOpcode() == X86ISD::SELECTS) &&
822 "Unexpected opcode!");
827 return N->getOperand(1).hasOneUse();
837 Ops.push_back(
Load.getOperand(0));
840 "Unexpected chain operand");
843 Ops.push_back(
Load.getOperand(0));
849 Ops.push_back(NewChain);
854 Load.getOperand(1),
Load.getOperand(2));
872 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
884 if (!Callee.getValue(1).hasOneUse())
915 Callee.getValue(1).hasOneUse())
932 if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
935 uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
936 0x65, 0x66, 0x67, 0xf0, 0xf2};
939 uint8_t Byte = (Imm >> i) & 0xFF;
951 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
954void X86DAGToDAGISel::PreprocessISelDAG() {
955 bool MadeChange =
false;
957 E = CurDAG->allnodes_end();
I !=
E; ) {
976 MVT VT =
N->getSimpleValueType(0);
978 int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
983 "cf-protection-branch");
986 SDValue Complement = CurDAG->getConstant(~Imm, dl, VT,
false,
true);
987 Complement = CurDAG->getNOT(dl, Complement, VT);
989 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Complement);
999 if (
N->getOpcode() == X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
1001 N->getOperand(0),
N->getOperand(1));
1003 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1027 auto mayPreventLoadFold = [&]() {
1029 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1030 !
N->getOperand(1).hasOneUse();
1033 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1041 MVT VT =
N->getSimpleValueType(0);
1049 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1051 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1058 switch (
N->getOpcode()) {
1059 case X86ISD::VBROADCAST: {
1060 MVT VT =
N->getSimpleValueType(0);
1062 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1066 CurDAG->getNode(X86ISD::VBROADCAST, dl, NarrowVT,
N->getOperand(0));
1069 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1072 CurDAG->getIntPtrConstant(Index, dl));
1075 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1083 case X86ISD::VBROADCAST_LOAD: {
1084 MVT VT =
N->getSimpleValueType(0);
1086 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1090 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1091 SDValue Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1092 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1093 X86ISD::VBROADCAST_LOAD, dl, VTs,
Ops, MemNode->getMemoryVT(),
1094 MemNode->getMemOperand());
1097 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1100 CurDAG->getIntPtrConstant(Index, dl));
1104 CurDAG->ReplaceAllUsesWith(
N, To);
1116 MVT VT =
N->getSimpleValueType(0);
1122 SDNode *MaxLd =
nullptr;
1123 SDValue Ptr = Ld->getBasePtr();
1124 SDValue Chain = Ld->getChain();
1125 for (SDNode *User : Ptr->
users()) {
1127 MVT UserVT =
User->getSimpleValueType(0);
1129 UserLd->getBasePtr() == Ptr && UserLd->getChain() == Chain &&
1130 !
User->hasAnyUseOfValue(1) &&
1144 CurDAG->getIntPtrConstant(0, dl));
1145 SDValue Res = CurDAG->getBitcast(VT, Extract);
1149 CurDAG->ReplaceAllUsesWith(
N, To);
1158 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1159 if (EleVT == MVT::i1)
1162 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1163 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1164 "We can't replace VSELECT with BLENDV in vXi16!");
1166 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1168 R = CurDAG->getNode(X86ISD::VPTERNLOG, SDLoc(
N),
N->getValueType(0),
1169 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1170 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1172 R = CurDAG->getNode(X86ISD::BLENDV, SDLoc(
N),
N->getValueType(0),
1173 N->getOperand(0),
N->getOperand(1),
1177 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1190 if (!
N->getSimpleValueType(0).isVector())
1194 switch (
N->getOpcode()) {
1204 if (
N->isStrictFPOpcode())
1206 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1207 {
N->getOperand(0),
N->getOperand(1)});
1210 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1213 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1223 if (!
N->getValueType(0).isVector())
1227 switch (
N->getOpcode()) {
1229 case ISD::SHL: NewOpc = X86ISD::VSHLV;
break;
1230 case ISD::SRA: NewOpc = X86ISD::VSRAV;
break;
1231 case ISD::SRL: NewOpc = X86ISD::VSRLV;
break;
1233 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1234 N->getOperand(0),
N->getOperand(1));
1236 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1245 if (!
N->getValueType(0).isVector())
1249 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1251 "Unexpected opcode for mask vector!");
1259 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1262 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1282 switch (
N->getOpcode()) {
1298 bool IsStrict =
N->isStrictFPOpcode();
1301 Res = CurDAG->getNode(X86ISD::STRICT_VRNDSCALE, dl,
1302 {
N->getValueType(0), MVT::Other},
1303 {
N->getOperand(0),
N->getOperand(1),
1304 CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
1306 Res = CurDAG->getNode(X86ISD::VRNDSCALE, dl,
N->getValueType(0),
1308 CurDAG->getTargetConstant(Imm, dl, MVT::i32));
1310 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1318 case X86ISD::FXOR: {
1321 MVT VT =
N->getSimpleValueType(0);
1322 if (VT.
isVector() || VT == MVT::f128)
1325 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1326 : VT == MVT::f32 ? MVT::v4f32
1336 if (Subtarget->hasSSE2()) {
1337 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1341 switch (
N->getOpcode()) {
1343 case X86ISD::FANDN:
Opc = X86ISD::ANDNP;
break;
1348 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1351 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1354 CurDAG->getIntPtrConstant(0, dl));
1356 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1363 if (OptLevel != CodeGenOptLevel::None &&
1366 !Subtarget->useIndirectThunkCalls() &&
1367 ((
N->getOpcode() == X86ISD::CALL && !Subtarget->slowTwoMemOps() &&
1368 !Subtarget->slowIndirectCall()) ||
1369 (
N->getOpcode() == X86ISD::TC_RETURN &&
1370 (Subtarget->is64Bit() ||
1371 !getTargetMachine().isPositionIndependent())))) {
1391 bool HasCallSeq =
N->getOpcode() == X86ISD::CALL;
1396 if (
N->getOpcode() == X86ISD::TC_RETURN && !checkTCRetEnoughRegs(
N))
1412 switch (
N->getOpcode()) {
1417 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1418 MVT DstVT =
N->getSimpleValueType(0);
1426 const X86TargetLowering *X86Lowering =
1427 static_cast<const X86TargetLowering *
>(TLI);
1430 if (SrcIsSSE && DstIsSSE)
1433 if (!SrcIsSSE && !DstIsSSE) {
1438 if (
N->getConstantOperandVal(1))
1446 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1448 MachinePointerInfo MPI =
1455 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1457 MemTmp, MPI, MemVT);
1464 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1473 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1474 MVT DstVT =
N->getSimpleValueType(0);
1482 const X86TargetLowering *X86Lowering =
1483 static_cast<const X86TargetLowering *
>(TLI);
1486 if (SrcIsSSE && DstIsSSE)
1489 if (!SrcIsSSE && !DstIsSSE) {
1494 if (
N->getConstantOperandVal(2))
1502 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1504 MachinePointerInfo MPI =
1513 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1514 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1515 Store = CurDAG->getMemIntrinsicNode(X86ISD::FST, dl, VTs,
Ops, MemVT,
1518 if (
N->getFlags().hasNoFPExcept()) {
1520 Flags.setNoFPExcept(
true);
1521 Store->setFlags(Flags);
1524 assert(SrcVT == MemVT &&
"Unexpected VT!");
1525 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1530 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1532 Result = CurDAG->getMemIntrinsicNode(
1533 X86ISD::FLD, dl, VTs,
Ops, MemVT, MPI,
1535 if (
N->getFlags().hasNoFPExcept()) {
1537 Flags.setNoFPExcept(
true);
1541 assert(DstVT == MemVT &&
"Unexpected VT!");
1542 Result = CurDAG->getLoad(DstVT, dl,
Store, MemTmp, MPI);
1550 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1564 CurDAG->RemoveDeadNodes();
1568bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1569 unsigned Opc =
N->getMachineOpcode();
1570 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1571 Opc != X86::MOVSX64rr8)
1583 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1584 : X86::MOVSX32rr8_NOREX;
1589 if (
Opc == X86::MOVSX64rr8) {
1592 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1594 ReplaceUses(
N, Extend);
1603void X86DAGToDAGISel::PostprocessISelDAG() {
1605 if (TM.getOptLevel() == CodeGenOptLevel::None)
1610 bool MadeChange =
false;
1611 while (Position != CurDAG->allnodes_begin()) {
1612 SDNode *
N = &*--Position;
1614 if (
N->use_empty() || !
N->isMachineOpcode())
1617 if (tryOptimizeRem8Extend(
N)) {
1622 unsigned Opc =
N->getMachineOpcode();
1633 case X86::CTEST16rr:
1634 case X86::CTEST32rr:
1635 case X86::CTEST64rr: {
1641#define CASE_ND(OP) \
1644 switch (
And.getMachineOpcode()) {
1651 if (
And->hasAnyUseOfValue(1))
1654 Ops[0] =
And.getOperand(0);
1655 Ops[1] =
And.getOperand(1);
1656 MachineSDNode *
Test =
1657 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1658 ReplaceUses(
N,
Test);
1666 if (
And->hasAnyUseOfValue(1))
1669 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1670#define FROM_TO(A, B) \
1671 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1673 switch (
And.getMachineOpcode()) {
1683 And.getOperand(3),
And.getOperand(4),
1684 And.getOperand(5),
And.getOperand(0)};
1687 Ops.push_back(
N->getOperand(2));
1688 Ops.push_back(
N->getOperand(3));
1691 Ops.push_back(
And.getOperand(6));
1694 Ops.push_back(
N->getOperand(4));
1696 MachineSDNode *
Test = CurDAG->getMachineNode(
1697 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1698 CurDAG->setNodeMemRefs(
1711 case X86::KORTESTBkk:
1712 case X86::KORTESTWkk:
1713 case X86::KORTESTDkk:
1714 case X86::KORTESTQkk: {
1716 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1731#define FROM_TO(A, B) \
1743 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1746 MachineSDNode *KTest = CurDAG->getMachineNode(
1748 ReplaceUses(
N, KTest);
1753 case TargetOpcode::SUBREG_TO_REG: {
1754 unsigned SubRegIdx =
N->getConstantOperandVal(1);
1755 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1772 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1773 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1774 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1775 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1776 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1777 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1778 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1779 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1784 if (!
In.isMachineOpcode() ||
1785 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1790 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1798 CurDAG->UpdateNodeOperands(
N, In,
N->getOperand(1));
1805 CurDAG->RemoveDeadNodes();
1810void X86DAGToDAGISel::emitSpecialCodeForMain() {
1811 if (Subtarget->isTargetCygMing()) {
1812 TargetLowering::ArgListTy
Args;
1813 auto &
DL = CurDAG->getDataLayout();
1815 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1816 CLI.setChain(CurDAG->getRoot())
1817 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1818 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1820 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1822 CurDAG->setRoot(
Result.second);
1826void X86DAGToDAGISel::emitFunctionEntryCode() {
1829 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1830 emitSpecialCodeForMain();
1843bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t
Offset,
1844 X86ISelAddressMode &AM) {
1849 int64_t Val = AM.Disp +
Offset;
1852 if (Val != 0 && (AM.ES || AM.MCSym))
1856 if (Subtarget->is64Bit()) {
1859 AM.hasSymbolicDisplacement()))
1863 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1882 if (Subtarget->isTarget64BitILP32() &&
1884 !AM.hasBaseOrIndexReg())
1886 }
else if (Subtarget->is16Bit()) {
1889 if (Val < -(int64_t)UINT16_MAX || Val > (int64_t)UINT16_MAX)
1899bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1900 bool AllowSegmentRegForX32) {
1913 !IndirectTlsSegRefs &&
1914 (Subtarget->isTargetGlibc() || Subtarget->isTargetMusl() ||
1915 Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())) {
1916 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1918 switch (
N->getPointerInfo().getAddrSpace()) {
1920 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1923 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1936bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1939 if (AM.hasSymbolicDisplacement())
1942 bool IsRIPRelTLS =
false;
1943 bool IsRIPRel =
N.getOpcode() == X86ISD::WrapperRIP;
1960 if (IsRIPRel && AM.hasBaseOrIndexReg())
1964 X86ISelAddressMode Backup = AM;
1969 AM.GV =
G->getGlobal();
1970 AM.SymbolFlags =
G->getTargetFlags();
1973 AM.CP = CP->getConstVal();
1974 AM.Alignment = CP->getAlign();
1975 AM.SymbolFlags = CP->getTargetFlags();
1976 Offset = CP->getOffset();
1978 AM.ES = S->getSymbol();
1979 AM.SymbolFlags = S->getTargetFlags();
1981 AM.MCSym = S->getMCSymbol();
1983 AM.JT = J->getIndex();
1984 AM.SymbolFlags = J->getTargetFlags();
1986 AM.BlockAddr = BA->getBlockAddress();
1987 AM.SymbolFlags = BA->getTargetFlags();
1988 Offset = BA->getOffset();
1993 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1994 TM.isLargeGlobalValue(AM.GV)) {
1999 if (foldOffsetIntoAddress(
Offset, AM)) {
2005 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
2013bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
2014 if (matchAddressRecursively(
N, AM, 0))
2021 if (Subtarget->isTarget64BitILP32() &&
2022 AM.BaseType == X86ISelAddressMode::RegBase &&
2023 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
2024 SDValue Save_Base_Reg = AM.Base_Reg;
2027 if (matchLoadInAddress(LoadN, AM,
true))
2028 AM.Base_Reg = Save_Base_Reg;
2034 if (AM.Scale == 2 &&
2035 AM.BaseType == X86ISelAddressMode::RegBase &&
2036 AM.Base_Reg.
getNode() ==
nullptr) {
2037 AM.Base_Reg = AM.IndexReg;
2044 (!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2045 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2046 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2058 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2064bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
2068 HandleSDNode Handle(
N);
2070 X86ISelAddressMode Backup = AM;
2071 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
2072 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
2077 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
2079 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2086 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2089 N = Handle.getValue();
2095 N = Handle.getValue();
2105 if (
N->getNodeId() == -1 ||
2125 X86ISelAddressMode &AM) {
2132 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2133 Mask != (0xffu << ScaleLog))
2136 MVT XVT =
X.getSimpleValueType();
2137 MVT VT =
N.getSimpleValueType();
2162 AM.Scale = (1 << ScaleLog);
2170 X86ISelAddressMode &AM) {
2181 bool FoundAnyExtend =
false;
2185 FoundAnyExtend =
true;
2203 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2206 MVT VT =
N.getSimpleValueType();
2208 if (FoundAnyExtend) {
2229 AM.Scale = 1 << ShiftAmt;
2230 AM.IndexReg = NewAnd;
2264 X86ISelAddressMode &AM) {
2270 unsigned MaskIdx, MaskLen;
2273 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2279 unsigned AMShiftAmt = MaskIdx;
2283 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2287 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2288 if (MaskLZ < ScaleDown)
2290 MaskLZ -= ScaleDown;
2298 bool ReplacingAnyExtend =
false;
2300 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2301 X.getOperand(0).getSimpleValueType().getSizeInBits();
2304 X =
X.getOperand(0);
2305 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2306 ReplacingAnyExtend =
true;
2308 APInt MaskedHighBits =
2315 MVT VT =
N.getSimpleValueType();
2316 if (ReplacingAnyExtend) {
2317 assert(
X.getValueType() != VT);
2324 MVT XVT =
X.getSimpleValueType();
2345 AM.Scale = 1 << AMShiftAmt;
2346 AM.IndexReg = NewExt;
2356 X86ISelAddressMode &AM,
2364 if (!Subtarget.hasTBM() &&
2365 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2369 unsigned MaskIdx, MaskLen;
2377 unsigned AMShiftAmt = MaskIdx;
2381 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2383 MVT XVT =
X.getSimpleValueType();
2384 MVT VT =
N.getSimpleValueType();
2409 AM.Scale = 1 << AMShiftAmt;
2410 AM.IndexReg = NewExt;
2417 X86ISelAddressMode &AM,
2419 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2420 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2421 "Illegal index scale");
2427 EVT VT =
N.getValueType();
2428 unsigned Opc =
N.getOpcode();
2431 if (CurDAG->isBaseWithConstantOffset(
N)) {
2433 uint64_t
Offset = (uint64_t)AddVal->getSExtValue() * AM.Scale;
2434 if (!foldOffsetIntoAddress(
Offset, AM))
2435 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2439 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2440 if (AM.Scale <= 4) {
2442 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2447 if (
Opc == X86ISD::VSHLI) {
2448 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2449 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2450 if ((AM.Scale * ScaleAmt) <= 8) {
2451 AM.Scale *= ScaleAmt;
2452 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2460 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2462 if (CurDAG->isBaseWithConstantOffset(Src)) {
2463 SDValue AddSrc = Src.getOperand(0);
2465 int64_t
Offset = AddVal->getSExtValue();
2466 if (!foldOffsetIntoAddress((uint64_t)
Offset * AM.Scale, AM)) {
2474 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2475 CurDAG->RemoveDeadNode(
N.getNode());
2487 unsigned SrcOpc = Src.getOpcode();
2488 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2489 CurDAG->isADDLike(Src,
true)) &&
2491 if (CurDAG->isBaseWithConstantOffset(Src)) {
2492 SDValue AddSrc = Src.getOperand(0);
2493 uint64_t
Offset = Src.getConstantOperandVal(1);
2494 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2504 uint64_t ScaleAmt = 1ULL << ShAmt;
2505 if ((AM.Scale * ScaleAmt) <= 8 &&
2507 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2508 AM.Scale *= ScaleAmt;
2509 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2520 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2524 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2525 CurDAG->RemoveDeadNode(
N.getNode());
2526 return Res ? Res : ExtSrc;
2536bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2539 dbgs() <<
"MatchAddress: ";
2544 return matchAddressBase(
N, AM);
2549 if (AM.isRIPRelative()) {
2553 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2557 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2562 switch (
N.getOpcode()) {
2565 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2568 AM.MCSym = ESNode->getMCSymbol();
2575 if (!foldOffsetIntoAddress(Val, AM))
2580 case X86ISD::Wrapper:
2581 case X86ISD::WrapperRIP:
2582 if (!matchWrapper(
N, AM))
2592 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2593 AM.Base_Reg.
getNode() ==
nullptr &&
2595 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2602 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2606 unsigned Val = CN->getZExtValue();
2611 if (Val == 1 || Val == 2 || Val == 3) {
2613 AM.Scale = 1 << Val;
2614 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2622 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2626 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2627 "Unexpected value size!");
2639 uint64_t
Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2651 if (
N.getResNo() != 0)
break;
2654 case X86ISD::MUL_IMM:
2656 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2657 AM.Base_Reg.
getNode() ==
nullptr &&
2658 AM.IndexReg.
getNode() ==
nullptr) {
2660 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2661 CN->getZExtValue() == 9) {
2662 AM.Scale = unsigned(CN->getZExtValue())-1;
2674 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2675 if (foldOffsetIntoAddress(Disp, AM))
2676 Reg =
N.getOperand(0);
2678 Reg =
N.getOperand(0);
2681 AM.IndexReg = AM.Base_Reg =
Reg;
2697 HandleSDNode Handle(
N);
2700 X86ISelAddressMode Backup = AM;
2701 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2702 N = Handle.getValue();
2706 N = Handle.getValue();
2708 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2723 RHS.getOperand(0).getValueType() == MVT::i32))
2727 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2729 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2733 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2734 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2747 AM.NegateIndex =
true;
2755 if (!CurDAG->isADDLike(
N))
2759 if (!matchAdd(
N, AM,
Depth))
2768 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2772 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2773 "Unexpected value size!");
2778 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2782 uint64_t
Mask =
N.getConstantOperandVal(1);
2807 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2815 if (
SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2817 AM.IndexReg =
Index;
2823 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2825 Mask = MaskC->getAPIntValue();
2826 Src = Src.getOperand(0);
2829 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2831 SDValue ShlSrc = Src.getOperand(0);
2832 SDValue ShlAmt = Src.getOperand(1);
2836 unsigned ShAmtV = ShAmtC->getZExtValue();
2844 if (!Src->getFlags().hasNoUnsignedWrap() &&
2845 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2853 MVT VT =
N.getSimpleValueType();
2857 if (!
Mask.isAllOnes()) {
2858 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2860 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2867 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2868 CurDAG->RemoveDeadNode(
N.getNode());
2871 AM.Scale = 1 << ShAmtV;
2875 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2879 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2882 Src.getOperand(0), AM))
2887 Src.getOperand(0), AM))
2892 Src.getOperand(0), AM, *Subtarget))
2900 return matchAddressBase(
N, AM);
2905bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2907 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
2920 AM.BaseType = X86ISelAddressMode::RegBase;
2925bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2926 X86ISelAddressMode &AM,
2929 dbgs() <<
"MatchVectorAddress: ";
2934 return matchAddressBase(
N, AM);
2937 switch (
N.getOpcode()) {
2940 if (!foldOffsetIntoAddress(Val, AM))
2944 case X86ISD::Wrapper:
2945 if (!matchWrapper(
N, AM))
2951 HandleSDNode Handle(
N);
2953 X86ISelAddressMode Backup = AM;
2954 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2955 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2961 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2963 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2968 N = Handle.getValue();
2973 return matchAddressBase(
N, AM);
2979bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2980 return matchVectorAddressRecursively(
N, AM, 0);
2983bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
2988 X86ISelAddressMode AM;
2994 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2996 AM.IndexReg = IndexOp;
3000 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3002 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3004 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3007 MVT VT =
BasePtr.getSimpleValueType();
3010 if (matchVectorAddress(BasePtr, AM))
3013 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3026 SDValue &Segment,
bool HasNDDM) {
3027 X86ISelAddressMode AM;
3034 Parent->
getOpcode() != X86ISD::TLSCALL &&
3035 Parent->
getOpcode() != X86ISD::ENQCMD &&
3036 Parent->
getOpcode() != X86ISD::ENQCMDS &&
3037 Parent->
getOpcode() != X86ISD::EH_SJLJ_SETJMP &&
3038 Parent->
getOpcode() != X86ISD::EH_SJLJ_LONGJMP) {
3039 unsigned AddrSpace =
3042 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3044 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3046 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3051 MVT VT =
N.getSimpleValueType();
3053 if (matchAddress(
N, AM))
3056 if (!HasNDDM && !AM.isRIPRelative())
3059 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3066 return selectAddr(Parent,
N,
Base, Scale, Index, Disp, Segment,
3067 Subtarget->hasNDDM());
3079 if (
N->getOpcode() != X86ISD::Wrapper)
3082 N =
N.getOperand(0);
3099 return CR->getUnsignedMax().ult(1ull << 32);
3101 return !TM.isLargeGlobalValue(GV);
3110 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3116 SubReg = X86::sub_8bit;
3118 SubReg = X86::sub_16bit;
3120 SubReg = X86::sub_32bit;
3123 if (RN &&
RN->getReg() == 0)
3124 Base = CurDAG->getRegister(0, MVT::i64);
3131 Base = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef,
Base);
3134 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3136 if (RN &&
RN->getReg() == 0)
3137 Index = CurDAG->getRegister(0, MVT::i64);
3140 "Expect to be extending 8/16/32-bit registers for use in LEA");
3143 Index = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef, Index);
3151bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3155 X86ISelAddressMode AM;
3159 MVT VT =
N.getSimpleValueType();
3164 SDValue T = CurDAG->getRegister(0, MVT::i32);
3166 if (matchAddress(
N, AM))
3171 unsigned Complexity = 0;
3172 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3174 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3190 if (AM.hasSymbolicDisplacement()) {
3192 if (Subtarget->is64Bit())
3202 auto isMathWithFlags = [](
SDValue V) {
3203 switch (
V.getOpcode()) {
3217 return !
SDValue(
V.getNode(), 1).use_empty();
3224 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3232 if (Complexity <= 2)
3235 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3246 X86ISelAddressMode AM;
3248 AM.GV = GA->getGlobal();
3249 AM.Disp += GA->getOffset();
3250 AM.SymbolFlags = GA->getTargetFlags();
3253 AM.ES = SA->getSymbol();
3254 AM.SymbolFlags = SA->getTargetFlags();
3257 if (Subtarget->is32Bit()) {
3259 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3262 MVT VT =
N.getSimpleValueType();
3263 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3271 EVT VT =
N.getValueType();
3272 bool WasTruncated =
false;
3274 WasTruncated =
true;
3275 N =
N.getOperand(0);
3278 if (
N.getOpcode() != X86ISD::Wrapper)
3284 unsigned Opc =
N.getOperand(0)->getOpcode();
3286 Op =
N.getOperand(0);
3289 return !WasTruncated;
3294 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3295 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3299 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3300 GA->getOffset(), GA->getTargetFlags());
3304bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
3308 assert(Root &&
P &&
"Unknown root/parent nodes");
3310 !IsProfitableToFold(
N,
P, Root) ||
3311 !IsLegalToFold(
N,
P, Root, OptLevel))
3314 return selectAddr(
N.getNode(),
3315 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3318bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
3322 assert(Root &&
P &&
"Unknown root/parent nodes");
3323 if (
N->getOpcode() != X86ISD::VBROADCAST_LOAD ||
3324 !IsProfitableToFold(
N,
P, Root) ||
3325 !IsLegalToFold(
N,
P, Root, OptLevel))
3328 return selectAddr(
N.getNode(),
3329 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3335SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3338 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3341bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3343 N =
N->getOperand(0).getNode();
3344 if (
N->getOpcode() != X86ISD::Wrapper)
3351 auto *GV = GA->getGlobal();
3354 return CR->getSignedMin().sge(-1ull << Width) &&
3355 CR->getSignedMax().slt(1ull << Width);
3361 !TM.isLargeGlobalValue(GV);
3365 assert(
N->isMachineOpcode() &&
"Unexpected node");
3366 unsigned Opc =
N->getMachineOpcode();
3367 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3372 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3377bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3379 for (SDUse &Use :
Flags->uses()) {
3381 if (
Use.getResNo() !=
Flags.getResNo())
3389 for (SDUse &FlagUse :
User->uses()) {
3391 if (FlagUse.getResNo() != 1)
3394 if (!FlagUse.getUser()->isMachineOpcode())
3414bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3416 for (SDUse &Use :
Flags->uses()) {
3418 if (
Use.getResNo() !=
Flags.getResNo())
3426 for (SDUse &FlagUse :
User->uses()) {
3428 if (FlagUse.getResNo() != 1)
3431 if (!FlagUse.getUser()->isMachineOpcode())
3471 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3473 for (SDUse &Use :
Flags->uses()) {
3475 if (
Use.getResNo() !=
Flags.getResNo())
3479 unsigned UserOpc =
User->getOpcode();
3486 for (SDUse &FlagUse :
User->uses()) {
3488 if (FlagUse.getResNo() != 1)
3491 if (!FlagUse.getUser()->isMachineOpcode())
3511 case X86ISD::SETCC: CCOpNo = 0;
break;
3512 case X86ISD::SETCC_CARRY: CCOpNo = 0;
break;
3513 case X86ISD::CMOV: CCOpNo = 2;
break;
3514 case X86ISD::BRCOND: CCOpNo = 2;
break;
3524bool X86DAGToDAGISel::checkTCRetEnoughRegs(SDNode *
N)
const {
3527 const X86RegisterInfo *RI = Subtarget->getRegisterInfo();
3531 if (Subtarget->is64Bit()) {
3534 ? &X86::GR64_TCW64RegClass
3535 : &X86::GR64_TCRegClass;
3543 ? &X86::GR32RegClass
3544 : &X86::GR32_TCRegClass;
3551 unsigned LoadGPRs = 2;
3553 assert(
N->getOpcode() == X86ISD::TC_RETURN);
3556 if (Subtarget->is32Bit()) {
3562 }
else if (
BasePtr.getOpcode() == X86ISD::Wrapper &&
3564 if (getTargetMachine().isPositionIndependent())
3572 for (
unsigned I = 3,
E =
N->getNumOperands();
I !=
E; ++
I) {
3574 if (!RI->isGeneralPurposeRegister(*MF,
RN->getReg()))
3576 if (++
ArgGPRs + LoadGPRs > AvailGPRs)
3592 if (StoredVal.
getResNo() != 0)
return false;
3609 if (!
Load.hasOneUse())
3617 bool FoundLoad =
false;
3621 const unsigned int Max = 1024;
3663 if (Chain ==
Load.getValue(1)) {
3669 if (
Op ==
Load.getValue(1)) {
3685 if (
Op.getNode() != LoadNode)
3717bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3719 SDValue StoredVal = StoreNode->getOperand(1);
3725 EVT MemVT = StoreNode->getMemoryVT();
3726 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3730 bool IsCommutable =
false;
3731 bool IsNegate =
false;
3745 IsCommutable =
true;
3749 unsigned LoadOpNo = IsNegate ? 1 : 0;
3750 LoadSDNode *LoadNode =
nullptr;
3753 LoadNode, InputChain)) {
3760 LoadNode, InputChain))
3765 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3769 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3790 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3793 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3800 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
3804 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3806 ((
Opc == X86ISD::ADD) == IsOne)
3807 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
3808 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
3810 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3821 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
3824 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
3827 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
3830 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
3833 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
3836 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
3839 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
3841 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
3847 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
3850 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
3853 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
3856 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
3859 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
3862 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
3865 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
3868 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
3875 unsigned NewOpc = SelectRegOpcode(
Opc);
3881 int64_t OperandV = OperandC->getSExtValue();
3886 if ((
Opc == X86ISD::ADD ||
Opc == X86ISD::SUB) &&
3888 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
3890 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3891 OperandV = -OperandV;
3892 Opc =
Opc == X86ISD::ADD ? X86ISD::SUB : X86ISD::ADD;
3895 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
3896 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
3897 NewOpc = SelectImmOpcode(
Opc);
3901 if (
Opc == X86ISD::ADC ||
Opc == X86ISD::SBB) {
3903 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
3907 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
3908 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3912 Segment, Operand, InputChain};
3913 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3922 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
3924 CurDAG->setNodeMemRefs(Result, MemOps);
3930 CurDAG->RemoveDeadNode(Node);
3941bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
3945 "Should be either an and-mask, or right-shift after clearing high bits.");
3948 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
3951 MVT NVT =
Node->getSimpleValueType(0);
3954 if (NVT != MVT::i32 && NVT != MVT::i64)
3962 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
3963 auto checkUses = [AllowExtraUsesByDefault](
3965 std::optional<bool> AllowExtraUses) {
3966 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
3967 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
3969 auto checkOneUse = [checkUses](
SDValue Op,
3970 std::optional<bool> AllowExtraUses =
3972 return checkUses(
Op, 1, AllowExtraUses);
3974 auto checkTwoUse = [checkUses](
SDValue Op,
3975 std::optional<bool> AllowExtraUses =
3977 return checkUses(
Op, 2, AllowExtraUses);
3980 auto peekThroughOneUseTruncation = [checkOneUse](
SDValue V) {
3982 assert(
V.getSimpleValueType() == MVT::i32 &&
3983 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
3984 "Expected i64 -> i32 truncation");
3985 V =
V.getOperand(0);
3991 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
3994 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
4000 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4005 NBits =
M0->getOperand(1);
4006 NegateNBits =
false;
4010 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](
SDValue V) {
4011 V = peekThroughOneUseTruncation(V);
4012 return CurDAG->MaskedValueIsAllOnes(
4018 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
4021 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
4024 if (!isAllOnes(
Mask->getOperand(1)))
4027 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4031 if (!isAllOnes(
M0->getOperand(0)))
4033 NBits =
M0->getOperand(1);
4034 NegateNBits =
false;
4040 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](
SDValue ShiftAmt,
4041 unsigned Bitwidth) {
4046 NBits = NBits.getOperand(0);
4052 if (!V0 || V0->getZExtValue() != Bitwidth)
4054 NBits = NBits.getOperand(1);
4055 NegateNBits =
false;
4061 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
4064 Mask = peekThroughOneUseTruncation(Mask);
4065 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
4067 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
4074 if (!checkOneUse(
M1))
4076 canonicalizeShiftAmt(
M1, Bitwidth);
4081 return !NegateNBits;
4089 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
4090 AllowExtraUsesByDefault, &NegateNBits,
4091 &
X](SDNode *
Node) ->
bool {
4103 canonicalizeShiftAmt(N1, Bitwidth);
4107 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
4108 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4114 auto matchLowBitMask = [matchPatternA, matchPatternB,
4116 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4120 X =
Node->getOperand(0);
4123 if (matchLowBitMask(Mask)) {
4127 if (!matchLowBitMask(Mask))
4130 }
else if (matchLowBitMask(
SDValue(Node, 0))) {
4131 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4132 }
else if (!matchPatternD(Node))
4137 if (NegateNBits && !Subtarget->hasBMI2())
4142 if (NBits.getSimpleValueType() != MVT::i8) {
4149 ConstantSDNode *
Imm =
nullptr;
4150 if (NBits->getOpcode() ==
ISD::AND)
4152 NBits = NBits->getOperand(0);
4157 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4160 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4162 NBits =
SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4163 MVT::i32, ImplDef, NBits, SRIdxVal),
4169 CurDAG->getNode(
ISD::AND,
DL, MVT::i32, NBits,
4170 CurDAG->getConstant(
Imm->getZExtValue(),
DL, MVT::i32));
4180 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4184 if (Subtarget->hasBMI2()) {
4186 if (NVT != MVT::i32) {
4192 SDValue Extract = CurDAG->getNode(X86ISD::BZHI,
DL, NVT,
X, NBits);
4193 ReplaceNode(Node, Extract.
getNode());
4194 SelectCode(Extract.
getNode());
4203 SDValue RealX = peekThroughOneUseTruncation(
X);
4209 MVT XVT =
X.getSimpleValueType();
4219 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4227 SDValue ShiftAmt =
X.getOperand(1);
4228 X =
X.getOperand(0);
4231 "Expected shift amount to be i8");
4235 SDValue OrigShiftAmt = ShiftAmt;
4240 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4245 if (XVT != MVT::i32) {
4251 SDValue Extract = CurDAG->getNode(X86ISD::BEXTR,
DL, XVT,
X, Control);
4259 ReplaceNode(Node, Extract.
getNode());
4260 SelectCode(Extract.
getNode());
4266MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4267 MVT NVT =
Node->getSimpleValueType(0);
4280 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4281 if (!PreferBEXTR && !Subtarget->hasBMI2())
4293 if (NVT != MVT::i32 && NVT != MVT::i64)
4299 if (!MaskCst || !ShiftCst)
4303 uint64_t
Mask = MaskCst->getZExtValue();
4307 uint64_t Shift = ShiftCst->getZExtValue();
4312 if (Shift == 8 && MaskSize == 8)
4323 if (!PreferBEXTR && MaskSize <= 32)
4327 unsigned ROpc, MOpc;
4329#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4331 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4335 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4340 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4341 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4347 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4348 if (Subtarget->hasTBM()) {
4349 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4350 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4352 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4358 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4359 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4363 MachineSDNode *NewNode;
4365 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4366 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4368 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4369 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4370 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4374 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4376 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4381 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4385 CurDAG->getMachineNode(NewOpc, dl, NVT,
SDValue(NewNode, 0), ShAmt);
4392MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4393 bool MayFoldLoad,
const SDLoc &dl,
4394 MVT VT, SDNode *Node) {
4399 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4402 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4403 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4406 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4407 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4416 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4417 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4424MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4425 bool MayFoldLoad,
const SDLoc &dl,
4426 MVT VT, SDNode *Node,
4432 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4435 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4436 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4439 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4440 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4450 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4451 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4456bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4457 EVT VT =
N->getValueType(0);
4464 unsigned Size = VT == MVT::i64 ? 64 : 32;
4467 SDValue ShiftAmt = OrigShiftAmt;
4486 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4490 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4491 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4495 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4504 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4505 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4511 Add0C->getZExtValue() != 0) {
4514 if (Add0C->getZExtValue() %
Size == 0)
4517 Add0C->getZExtValue() % 32 == 0) {
4525 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4529 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4551 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4558 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4559 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4563 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4565 if (UpdatedNode !=
N) {
4568 ReplaceNode(
N, UpdatedNode);
4575 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4583bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4584 MVT NVT =
N->getSimpleValueType(0);
4585 unsigned Opcode =
N->getOpcode();
4597 int64_t Val = Cst->getSExtValue();
4602 bool FoundAnyExtend =
false;
4606 FoundAnyExtend =
true;
4614 if (NVT != MVT::i32 && NVT != MVT::i64)
4621 uint64_t ShAmt = ShlCst->getZExtValue();
4625 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4626 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4631 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4635 ShiftedVal = (uint64_t)Val >> ShAmt;
4639 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4642 ShiftedVal = Val >> ShAmt;
4648 ShiftedVal = (uint64_t)Val >> ShAmt;
4656 if (!CanShrinkImmediate(ShiftedVal))
4666 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4672 NeededMask &= ~Cst->getAPIntValue();
4674 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4679 if (FoundAnyExtend) {
4685 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4687 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4696bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4697 SDNode *ParentB, SDNode *ParentC,
4700 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4701 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4703 auto tryFoldLoadOrBCast =
4706 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4712 L =
L.getOperand(0);
4715 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
4720 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4724 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4727 bool FoldedLoad =
false;
4728 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4729 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4731 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4736 uint8_t OldImm =
Imm;
4737 Imm = OldImm & 0xa5;
4738 if (OldImm & 0x02)
Imm |= 0x10;
4739 if (OldImm & 0x10)
Imm |= 0x02;
4740 if (OldImm & 0x08)
Imm |= 0x40;
4741 if (OldImm & 0x40)
Imm |= 0x08;
4742 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4747 uint8_t OldImm =
Imm;
4748 Imm = OldImm & 0x99;
4749 if (OldImm & 0x02)
Imm |= 0x04;
4750 if (OldImm & 0x04)
Imm |= 0x02;
4751 if (OldImm & 0x20)
Imm |= 0x40;
4752 if (OldImm & 0x40)
Imm |= 0x20;
4757 SDValue TImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
4761 MachineSDNode *MNode;
4763 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4766 if (
C.getOpcode() == X86ISD::VBROADCAST_LOAD) {
4768 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4769 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4771 bool UseD = EltSize == 32;
4773 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4775 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4777 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4783 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4785 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4787 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4793 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
4796 ReplaceUses(
C.getValue(1),
SDValue(MNode, 1));
4803 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
4805 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
4807 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
4811 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
4815 CurDAG->RemoveDeadNode(Root);
4821bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
4822 MVT NVT =
N->getSimpleValueType(0);
4825 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
4833 auto getFoldableLogicOp = [](
SDValue Op) {
4836 Op =
Op.getOperand(0);
4838 if (!
Op.hasOneUse())
4841 unsigned Opc =
Op.getOpcode();
4843 Opc == X86ISD::ANDNP)
4852 auto tryPeelOuterNotWrappingLogic = [&](SDNode *
Op) {
4855 SDValue InnerOp = getFoldableLogicOp(
Op->getOperand(0));
4862 if ((FoldableOp = getFoldableLogicOp(N1))) {
4866 if ((FoldableOp = getFoldableLogicOp(N0))) {
4874 bool PeeledOuterNot =
false;
4876 if (
SDValue InnerOp = tryPeelOuterNotWrappingLogic(
N)) {
4877 PeeledOuterNot =
true;
4883 if ((FoldableOp = getFoldableLogicOp(N1)))
4885 else if ((FoldableOp = getFoldableLogicOp(N0)))
4893 SDNode *ParentA =
N;
4894 SDNode *ParentB = FoldableOp.
getNode();
4895 SDNode *ParentC = FoldableOp.
getNode();
4899 uint8_t TernlogMagicA = 0xf0;
4900 uint8_t TernlogMagicB = 0xcc;
4901 uint8_t TernlogMagicC = 0xaa;
4906 auto PeekThroughNot = [](
SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
4910 Parent =
Op.getNode();
4911 Op =
Op.getOperand(0);
4915 PeekThroughNot(
A, ParentA, TernlogMagicA);
4916 PeekThroughNot(
B, ParentB, TernlogMagicB);
4917 PeekThroughNot(
C, ParentC, TernlogMagicC);
4922 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
4923 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
4924 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
4925 case X86ISD::ANDNP:
Imm = ~(TernlogMagicB) & TernlogMagicC;
break;
4928 switch (
N->getOpcode()) {
4932 Imm &= ~TernlogMagicA;
4934 Imm = ~(
Imm) & TernlogMagicA;
4944 return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC,
A,
B,
C, Imm);
4954bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
4957 MVT VT =
And->getSimpleValueType(0);
4958 if (VT != MVT::i32 && VT != MVT::i64)
4970 APInt MaskVal = And1C->getAPIntValue();
4972 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
4976 if (VT == MVT::i64 && MaskLZ >= 32) {
4978 MaskVal = MaskVal.
trunc(32);
4983 APInt NegMaskVal = MaskVal | HighZeros;
4992 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
4993 NegMaskVal = NegMaskVal.
zext(64);
4994 HighZeros = HighZeros.
zext(64);
5000 KnownBits Known0 = CurDAG->computeKnownBits(And0);
5012 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
5021 bool FoldedBCast,
bool Masked) {
5022#define VPTESTM_CASE(VT, SUFFIX) \
5025 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
5026 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
5029#define VPTESTM_BROADCAST_CASES(SUFFIX) \
5030default: llvm_unreachable("Unexpected VT!"); \
5031VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
5032VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
5033VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
5034VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
5035VPTESTM_CASE(v16i32, DZ##SUFFIX) \
5036VPTESTM_CASE(v8i64, QZ##SUFFIX)
5038#define VPTESTM_FULL_CASES(SUFFIX) \
5039VPTESTM_BROADCAST_CASES(SUFFIX) \
5040VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
5041VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
5042VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
5043VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
5044VPTESTM_CASE(v64i8, BZ##SUFFIX) \
5045VPTESTM_CASE(v32i16, WZ##SUFFIX)
5063#undef VPTESTM_FULL_CASES
5064#undef VPTESTM_BROADCAST_CASES
5074 if (
Reg.isVirtual())
5079 if (GetPhysReg(N1) == LoReg && GetPhysReg(N0) != LoReg)
5085bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root,
SDValue Setcc,
5087 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
5132 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P,
SDValue &
L,
5137 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
5142 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
5148 L =
L.getOperand(0);
5151 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
5155 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5158 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5162 bool CanFoldLoads = Src0 != Src1;
5164 bool FoldedLoad =
false;
5165 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5167 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5171 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5178 bool FoldedBCast = FoldedLoad && Src1.
getOpcode() == X86ISD::VBROADCAST_LOAD;
5180 bool IsMasked = InMask.
getNode() !=
nullptr;
5189 unsigned SubReg = CmpVT.
is128BitVector() ? X86::sub_xmm : X86::sub_ymm;
5193 SDValue ImplDef =
SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5195 Src0 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src0);
5198 Src1 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src1);
5203 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5204 InMask =
SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5205 dl, MaskVT, InMask, RC), 0);
5213 MachineSDNode *CNode;
5215 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5218 SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5220 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5222 SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5224 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5230 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5233 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5235 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5241 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5242 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5243 dl, ResVT,
SDValue(CNode, 0), RC);
5247 CurDAG->RemoveDeadNode(Root);
5253bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5256 MVT NVT =
N->getSimpleValueType(0);
5259 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5293 SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5294 SDValue Ternlog = CurDAG->getNode(X86ISD::VPTERNLOG, dl, NVT,
A,
B,
C, Imm);
5301void X86DAGToDAGISel::Select(SDNode *Node) {
5302 MVT NVT =
Node->getSimpleValueType(0);
5303 unsigned Opcode =
Node->getOpcode();
5306 if (
Node->isMachineOpcode()) {
5308 Node->setNodeId(-1);
5315 unsigned IntNo =
Node->getConstantOperandVal(1);
5318 case Intrinsic::x86_encodekey128:
5319 case Intrinsic::x86_encodekey256: {
5320 if (!Subtarget->hasKL())
5326 case Intrinsic::x86_encodekey128:
5327 Opcode = X86::ENCODEKEY128;
5329 case Intrinsic::x86_encodekey256:
5330 Opcode = X86::ENCODEKEY256;
5335 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5337 if (Opcode == X86::ENCODEKEY256)
5338 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5341 MachineSDNode *Res = CurDAG->getMachineNode(
5342 Opcode, dl,
Node->getVTList(),
5343 {Node->getOperand(2), Chain, Chain.getValue(1)});
5344 ReplaceNode(Node, Res);
5347 case Intrinsic::x86_tileloaddrs64_internal:
5348 case Intrinsic::x86_tileloaddrst164_internal:
5349 if (!Subtarget->hasAMXMOVRS())
5352 case Intrinsic::x86_tileloadd64_internal:
5353 case Intrinsic::x86_tileloaddt164_internal: {
5354 if (!Subtarget->hasAMXTILE())
5357 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5358 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5363 case Intrinsic::x86_tileloaddrs64_internal:
5364 Opc = X86::PTILELOADDRSV;
5366 case Intrinsic::x86_tileloaddrst164_internal:
5367 Opc = X86::PTILELOADDRST1V;
5369 case Intrinsic::x86_tileloadd64_internal:
5370 Opc = X86::PTILELOADDV;
5372 case Intrinsic::x86_tileloaddt164_internal:
5373 Opc = X86::PTILELOADDT1V;
5378 SDValue Scale = getI8Imm(1, dl);
5380 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5381 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5383 MachineSDNode *CNode;
5385 Node->getOperand(3),
5392 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5393 ReplaceNode(Node, CNode);
5400 unsigned IntNo =
Node->getConstantOperandVal(1);
5403 case Intrinsic::x86_sse3_monitor:
5404 case Intrinsic::x86_monitorx:
5405 case Intrinsic::x86_clzero: {
5406 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5411 case Intrinsic::x86_sse3_monitor:
5412 if (!Subtarget->hasSSE3())
5414 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5416 case Intrinsic::x86_monitorx:
5417 if (!Subtarget->hasMWAITX())
5419 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5421 case Intrinsic::x86_clzero:
5422 if (!Subtarget->hasCLZERO())
5424 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5429 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5430 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5434 if (IntNo == Intrinsic::x86_sse3_monitor ||
5435 IntNo == Intrinsic::x86_monitorx) {
5437 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5440 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5445 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5447 ReplaceNode(Node, CNode);
5453 case Intrinsic::x86_tilestored64_internal: {
5455 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5456 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5457 unsigned Opc = X86::PTILESTOREDV;
5460 SDValue Scale = getI8Imm(1, dl);
5462 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5463 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5465 MachineSDNode *CNode;
5467 Node->getOperand(3),
5473 Node->getOperand(6),
5475 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5476 ReplaceNode(Node, CNode);
5479 case Intrinsic::x86_tileloaddrs64:
5480 case Intrinsic::x86_tileloaddrst164:
5481 if (!Subtarget->hasAMXMOVRS())
5484 case Intrinsic::x86_tileloadd64:
5485 case Intrinsic::x86_tileloaddt164:
5486 case Intrinsic::x86_tilestored64: {
5487 if (!Subtarget->hasAMXTILE())
5490 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5491 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5495 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5496 case Intrinsic::x86_tileloaddrs64:
5497 Opc = X86::PTILELOADDRS;
5499 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5500 case Intrinsic::x86_tileloaddrst164:
5501 Opc = X86::PTILELOADDRST1;
5503 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5506 unsigned TIndex =
Node->getConstantOperandVal(2);
5509 SDValue Scale = getI8Imm(1, dl);
5511 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5512 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5514 MachineSDNode *CNode;
5515 if (
Opc == X86::PTILESTORED) {
5517 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5520 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5522 ReplaceNode(Node, CNode);
5529 case X86ISD::NT_BRIND: {
5530 if (Subtarget->isTarget64BitILP32()) {
5535 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5536 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5537 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5538 Node->getOperand(0), ZextTarget);
5539 ReplaceNode(Node, Brind.
getNode());
5540 SelectCode(ZextTarget.
getNode());
5547 ReplaceNode(Node, getGlobalBaseReg());
5554 ReplaceUses(
SDValue(Node, 0),
Node->getOperand(0));
5555 CurDAG->RemoveDeadNode(Node);
5561 if (matchBitExtract(Node))
5566 if (tryShiftAmountMod(Node))
5570 case X86ISD::VPTERNLOG: {
5571 uint8_t
Imm =
Node->getConstantOperandVal(3);
5572 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5573 Node->getOperand(1),
Node->getOperand(2), Imm))
5579 if (tryVPTERNLOG(Node))
5589 tryVPTESTM(Node, N0, N1))
5592 tryVPTESTM(Node, N1, N0))
5596 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5598 CurDAG->RemoveDeadNode(Node);
5601 if (matchBitExtract(Node))
5609 if (tryShrinkShlLogicImm(Node))
5611 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5613 if (tryVPTERNLOG(Node))
5618 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5628 if (!CurDAG->shouldOptForSize())
5632 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5642 int64_t Val = Cst->getSExtValue();
5650 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5654 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5658 unsigned ROpc, MOpc;
5767 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5768 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5770 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5771 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5777 CurDAG->RemoveDeadNode(Node);
5782 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
5791 case X86ISD::UMUL: {
5795 unsigned LoReg, ROpc, MOpc;
5800 ROpc = Opcode == X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
5801 MOpc = Opcode == X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
5820 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5821 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5824 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5832 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
5834 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5837 MachineSDNode *CNode;
5843 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5845 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
5849 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5860 VTs = CurDAG->getVTList(NVT, MVT::i32);
5862 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
5864 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
5868 ReplaceUses(
SDValue(Node, 1),
SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
5869 CurDAG->RemoveDeadNode(Node);
5879 unsigned LoReg, HiReg;
5881 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
5882 bool UseMULXHi = UseMULX &&
SDValue(Node, 0).use_empty();
5886 Opc = UseMULXHi ? X86::MULX32Hrr
5888 : IsSigned ?
X86::IMUL32r
5890 MOpc = UseMULXHi ? X86::MULX32Hrm
5892 : IsSigned ?
X86::IMUL32m
5894 LoReg = UseMULX ? X86::EDX : X86::EAX;
5898 Opc = UseMULXHi ? X86::MULX64Hrr
5900 : IsSigned ?
X86::IMUL64r
5902 MOpc = UseMULXHi ? X86::MULX64Hrm
5904 : IsSigned ?
X86::IMUL64m
5906 LoReg = UseMULX ? X86::RDX : X86::RAX;
5911 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5912 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5915 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5923 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
5925 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5930 MachineSDNode *CNode =
nullptr;
5934 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5935 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5938 }
else if (UseMULX) {
5939 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
5940 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5945 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5946 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5952 ReplaceUses(N1.
getValue(1), Chain);
5958 SDVTList VTs = CurDAG->getVTList(NVT);
5959 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5961 }
else if (UseMULX) {
5962 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
5963 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5967 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
5968 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5974 if (!
SDValue(Node, 0).use_empty()) {
5976 assert(LoReg &&
"Register for low half is not defined!");
5977 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
5981 ReplaceUses(
SDValue(Node, 0), ResLo);
5986 if (!
SDValue(Node, 1).use_empty()) {
5988 assert(HiReg &&
"Register for high half is not defined!");
5989 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
5993 ReplaceUses(
SDValue(Node, 1), ResHi);
5998 CurDAG->RemoveDeadNode(Node);
6007 unsigned ROpc, MOpc;
6012 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
6013 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
6014 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
6015 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
6020 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
6021 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
6022 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
6023 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
6027 unsigned LoReg, HiReg, ClrReg;
6028 unsigned SExtOpcode;
6032 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
6036 LoReg = X86::AX; HiReg = X86::DX;
6038 SExtOpcode = X86::CWD;
6041 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
6042 SExtOpcode = X86::CDQ;
6045 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
6046 SExtOpcode = X86::CQO;
6050 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6051 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6052 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
6055 if (NVT == MVT::i8) {
6058 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
6059 MachineSDNode *Move;
6060 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6062 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rm8
6064 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
6066 ReplaceUses(N0.
getValue(1), Chain);
6070 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rr8
6072 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
6073 Chain = CurDAG->getEntryNode();
6075 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX,
SDValue(Move, 0),
6080 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
6081 LoReg, N0,
SDValue()).getValue(1);
6085 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
6088 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
6090 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
6094 SDValue(CurDAG->getMachineNode(
6095 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
6096 CurDAG->getTargetConstant(X86::sub_16bit, dl,
6104 CurDAG->getMachineNode(
6105 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, ClrNode,
6106 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
6113 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
6114 ClrNode, InGlue).getValue(1);
6121 MachineSDNode *CNode =
6122 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
6130 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
6140 if (HiReg == X86::AH && !
SDValue(Node, 1).use_empty()) {
6141 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
6142 unsigned AHExtOpcode =
6143 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6145 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6146 MVT::Glue, AHCopy, InGlue);
6151 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6153 ReplaceUses(
SDValue(Node, 1), Result);
6158 if (!
SDValue(Node, 0).use_empty()) {
6159 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6160 LoReg, NVT, InGlue);
6161 InGlue =
Result.getValue(2);
6162 ReplaceUses(
SDValue(Node, 0), Result);
6167 if (!
SDValue(Node, 1).use_empty()) {
6168 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6169 HiReg, NVT, InGlue);
6170 InGlue =
Result.getValue(2);
6171 ReplaceUses(
SDValue(Node, 1), Result);
6175 CurDAG->RemoveDeadNode(Node);
6180 case X86ISD::STRICT_FCMP:
6181 case X86ISD::STRICT_FCMPS: {
6182 bool IsStrictCmp =
Node->getOpcode() == X86ISD::STRICT_FCMP ||
6183 Node->getOpcode() == X86ISD::STRICT_FCMPS;
6184 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6185 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6191 if (Subtarget->canUseCMOV())
6194 bool IsSignaling =
Node->getOpcode() == X86ISD::STRICT_FCMPS;
6200 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6203 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6206 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6211 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6214 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6215 Chain =
SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6218 Glue =
SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6223 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6227 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6231 assert(Subtarget->canUseLAHFSAHF() &&
6232 "Target doesn't support SAHF or FCOMI?");
6233 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract,
SDValue());
6236 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6239 ReplaceUses(
SDValue(Node, 1), Chain);
6241 ReplaceUses(
SDValue(Node, 0), SAHF);
6242 CurDAG->RemoveDeadNode(Node);
6262 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6263 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6266 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6268 CurDAG->RemoveDeadNode(Node);
6288 uint64_t
Mask = MaskC->getZExtValue();
6295 onlyUsesZeroFlag(
SDValue(Node, 0))) {
6300 unsigned TestOpcode;
6308 if (LeadingZeros == 0 && SavesBytes) {
6313 ShiftAmt = TrailingZeros;
6315 TestOpcode = X86::TEST64rr;
6316 }
else if (TrailingZeros == 0 && SavesBytes) {
6321 ShiftAmt = LeadingZeros;
6323 TestOpcode = X86::TEST64rr;
6324 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6327 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6328 if (PopCount == 8) {
6330 ShiftAmt = TrailingZeros;
6331 SubRegIdx = X86::sub_8bit;
6333 TestOpcode = X86::TEST8rr;
6334 }
else if (PopCount == 16) {
6336 ShiftAmt = TrailingZeros;
6337 SubRegIdx = X86::sub_16bit;
6338 SubRegVT = MVT::i16;
6339 TestOpcode = X86::TEST16rr;
6340 }
else if (PopCount == 32) {
6342 ShiftAmt = TrailingZeros;
6343 SubRegIdx = X86::sub_32bit;
6344 SubRegVT = MVT::i32;
6345 TestOpcode = X86::TEST32rr;
6349 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6351 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6354 if (SubRegIdx != 0) {
6356 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6358 MachineSDNode *
Test =
6359 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6360 ReplaceNode(Node,
Test);
6367 unsigned ROpc, MOpc;
6375 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6376 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6379 SubRegOp = X86::sub_8bit;
6380 ROpc = X86::TEST8ri;
6381 MOpc = X86::TEST8mi;
6382 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6383 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6384 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6390 SubRegOp = X86::sub_16bit;
6391 ROpc = X86::TEST16ri;
6392 MOpc = X86::TEST16mi;
6394 ((!(Mask & 0x80000000) &&
6397 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6398 CmpVT == MVT::i32 ||
6399 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6406 SubRegOp = X86::sub_32bit;
6407 ROpc = X86::TEST32ri;
6408 MOpc = X86::TEST32mi;
6414 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6418 MachineSDNode *NewNode;
6419 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6420 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6422 if (!LoadN->isSimple()) {
6423 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6424 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6425 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6426 (MOpc == X86::TEST32mi && NumVolBits != 32))
6431 Reg.getOperand(0) };
6432 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6434 ReplaceUses(
Reg.getValue(1),
SDValue(NewNode, 1));
6436 CurDAG->setNodeMemRefs(NewNode,
6441 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6443 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg, Imm);
6446 ReplaceNode(Node, NewNode);
6452 if (!Subtarget->hasSSE42())
6455 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6456 bool NeedMask = !
SDValue(Node, 1).use_empty();
6458 bool MayFoldLoad = !NeedIndex || !NeedMask;
6460 MachineSDNode *CNode;
6463 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6465 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6466 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6469 if (NeedIndex || !NeedMask) {
6471 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6473 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6474 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6480 CurDAG->RemoveDeadNode(Node);
6484 if (!Subtarget->hasSSE42())
6488 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6489 Node->getOperand(1),
6491 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6492 Node->getOperand(3), InGlue).getValue(1);
6494 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6495 bool NeedMask = !
SDValue(Node, 1).use_empty();
6497 bool MayFoldLoad = !NeedIndex || !NeedMask;
6499 MachineSDNode *CNode;
6502 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6504 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6506 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6509 if (NeedIndex || !NeedMask) {
6511 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6513 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6514 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6519 CurDAG->RemoveDeadNode(Node);
6531 if (foldLoadStoreIntoMemOperand(Node))
6535 case X86ISD::SETCC_CARRY: {
6536 MVT VT =
Node->getSimpleValueType(0);
6538 if (Subtarget->hasSBBDepBreaking()) {
6543 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6548 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6549 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6551 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6556 Result = getSBBZero(Node);
6560 if (VT == MVT::i8 || VT == MVT::i16) {
6561 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6562 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6565 ReplaceUses(
SDValue(Node, 0), Result);
6566 CurDAG->RemoveDeadNode(Node);
6578 if (!
SDValue(Node, 0).use_empty()) {
6580 MVT VT =
Node->getSimpleValueType(0);
6581 if (VT == MVT::i8 || VT == MVT::i16) {
6582 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6583 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6585 ReplaceUses(
SDValue(Node, 0), Result);
6588 CurDAG->RemoveDeadNode(Node);
6595 SDValue IndexOp = Mgt->getIndex();
6598 MVT ValueVT =
Node->getSimpleValueType(0);
6599 MVT MaskVT =
Mask.getSimpleValueType();
6616 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6617 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6618 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6619 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6620 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6621 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6622 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6623 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6624 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6625 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6626 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6627 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6628 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6629 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6630 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6631 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6632 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6633 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6634 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6635 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6636 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6637 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6638 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6639 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6641 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6642 "Unexpected mask VT!");
6643 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6644 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6645 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6646 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6647 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6648 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6649 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6650 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6651 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6652 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6653 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6654 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6655 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6656 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6657 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6658 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6665 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6666 Base, Scale, Index, Disp, Segment))
6669 SDValue PassThru = Mgt->getPassThru();
6670 SDValue Chain = Mgt->getChain();
6672 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6674 MachineSDNode *NewNode;
6677 Index, Disp, Segment, Chain};
6678 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6681 Disp, Segment,
Mask, Chain};
6682 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6684 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6687 CurDAG->RemoveDeadNode(Node);
6693 SDValue IndexOp = Sc->getIndex();
6695 MVT ValueVT =
Value.getSimpleValueType();
6710 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6711 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6712 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6713 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6714 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6715 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6716 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6717 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6718 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6719 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6720 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6721 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6722 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6723 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6724 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6725 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6726 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6727 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6728 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6729 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6730 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6731 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6732 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6733 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6738 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6739 Base, Scale, Index, Disp, Segment))
6743 SDValue Chain = Sc->getChain();
6745 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6748 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6749 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6751 CurDAG->RemoveDeadNode(Node);
6755 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6756 auto CallId = MFI->getPreallocatedIdForCallSite(
6759 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6760 MachineSDNode *
New = CurDAG->getMachineNode(
6761 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6763 CurDAG->RemoveDeadNode(Node);
6767 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6771 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6774 Ops[0] = CallIdValue;
6777 MachineSDNode *
New = CurDAG->getMachineNode(
6778 TargetOpcode::PREALLOCATED_ARG, dl,
6779 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
6784 CurDAG->RemoveDeadNode(Node);
6791 if (!Subtarget->hasWIDEKL())
6795 switch (
Node->getOpcode()) {
6799 Opcode = X86::AESENCWIDE128KL;
6802 Opcode = X86::AESDECWIDE128KL;
6805 Opcode = X86::AESENCWIDE256KL;
6808 Opcode = X86::AESDECWIDE256KL;
6816 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
6819 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
6821 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
6823 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
6825 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
6827 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
6829 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
6831 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
6833 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
6836 MachineSDNode *Res = CurDAG->getMachineNode(
6837 Opcode, dl,
Node->getVTList(),
6838 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
6840 ReplaceNode(Node, Res);
6847 if (
Node->getNumValues() == 3)
6848 Glue =
Node->getOperand(2);
6850 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
6851 ReplaceNode(Node,
Copy.getNode());
6859bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
6861 std::vector<SDValue> &OutOps) {
6862 SDValue Op0, Op1, Op2, Op3, Op4;
6863 switch (ConstraintID) {
6866 case InlineAsm::ConstraintCode::o:
6867 case InlineAsm::ConstraintCode::v:
6868 case InlineAsm::ConstraintCode::m:
6869 case InlineAsm::ConstraintCode::X:
6870 case InlineAsm::ConstraintCode::p:
6871 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
6876 OutOps.push_back(Op0);
6877 OutOps.push_back(Op1);
6878 OutOps.push_back(Op2);
6879 OutOps.push_back(Op3);
6880 OutOps.push_back(Op4);
6886 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
6892 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< 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)
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
const MCPhysReg ArgGPRs[]
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 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 cl::opt< bool > EnablePromoteAnyextLoad("x86-promote-anyext-load", cl::init(true), cl::desc("Enable promoting aligned anyext load to wider load"), cl::Hidden)
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 cl::opt< bool > AndImmShrink("x86-and-imm-shrink", cl::init(true), cl::desc("Enable setting constant bits to reduce size of mask immediates"), cl::Hidden)
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 bool isEndbrImm64(uint64_t Imm)
static void orderRegForMul(SDValue &N0, SDValue &N1, const unsigned LoReg, const MachineRegisterInfo &MRI)
cl::opt< bool > IndirectBranchTracking("x86-indirect-branch-tracking", cl::init(false), cl::Hidden, cl::desc("Enable X86 indirect branch tracking pass."))
#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.
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
@ C
The default llvm calling convention, compatible with C.
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.
@ 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.
@ 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.
@ 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.
@ 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...
initializer< Ty > init(const Ty &Val)
@ 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)
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