22#include "llvm/Config/llvm-config.h"
27#include "llvm/IR/IntrinsicsX86.h"
38#define DEBUG_TYPE "x86-isel"
39#define PASS_NAME "X86 DAG->DAG Instruction Selection"
41STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
44 cl::desc(
"Enable setting constant bits to reduce size of mask immediates"),
48 "x86-promote-anyext-load",
cl::init(
true),
60 struct X86ISelAddressMode {
68 int Base_FrameIndex = 0;
74 const GlobalValue *GV =
nullptr;
77 const char *ES =
nullptr;
82 bool NegateIndex =
false;
84 X86ISelAddressMode() =
default;
86 bool hasSymbolicDisplacement()
const {
87 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr ||
88 MCSym !=
nullptr || JT != -1 || BlockAddr !=
nullptr;
91 bool hasBaseOrIndexReg()
const {
92 return BaseType == FrameIndexBase ||
93 IndexReg.getNode() !=
nullptr || Base_Reg.getNode() !=
nullptr;
98 if (BaseType != RegBase)
return false;
99 if (RegisterSDNode *RegNode =
101 return RegNode->getReg() == X86::RIP;
110#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
111 void dump(SelectionDAG *DAG =
nullptr) {
112 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
113 dbgs() <<
"Base_Reg ";
114 if (Base_Reg.getNode())
115 Base_Reg.getNode()->dump(DAG);
118 if (BaseType == FrameIndexBase)
119 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
120 dbgs() <<
" Scale " << Scale <<
'\n'
124 if (IndexReg.getNode())
125 IndexReg.getNode()->dump(DAG);
128 dbgs() <<
" Disp " << Disp <<
'\n'
150 dbgs() <<
" JT" << JT <<
" Align" << Alignment.value() <<
'\n';
164 const X86Subtarget *Subtarget;
170 bool IndirectTlsSegRefs;
173 X86DAGToDAGISel() =
delete;
175 explicit X86DAGToDAGISel(X86TargetMachine &tm,
CodeGenOptLevel OptLevel)
176 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr),
177 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
179 bool runOnMachineFunction(MachineFunction &MF)
override {
183 "indirect-tls-seg-refs");
190 void emitFunctionEntryCode()
override;
192 bool IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const override;
194 void PreprocessISelDAG()
override;
195 void PostprocessISelDAG()
override;
198#include "X86GenDAGISel.inc"
201 void Select(SDNode *
N)
override;
203 bool foldOffsetIntoAddress(uint64_t
Offset, X86ISelAddressMode &AM);
204 bool matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
205 bool AllowSegmentRegForX32 =
false);
206 bool matchWrapper(
SDValue N, X86ISelAddressMode &AM);
207 bool matchAddress(
SDValue N, X86ISelAddressMode &AM);
208 bool matchVectorAddress(
SDValue N, X86ISelAddressMode &AM);
209 bool matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
212 bool matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
214 bool matchVectorAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
216 bool matchAddressBase(
SDValue N, X86ISelAddressMode &AM);
219 bool HasNDDM =
true);
222 bool selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
SDValue IndexOp,
236 bool tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
246 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
249 bool tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
254 bool isProfitableToFormMaskedOp(SDNode *
N)
const;
257 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
259 std::vector<SDValue> &OutOps)
override;
261 void emitSpecialCodeForMain();
263 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
267 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
268 Base = CurDAG->getTargetFrameIndex(
269 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
270 else if (AM.Base_Reg.
getNode())
273 Base = CurDAG->getRegister(0, VT);
275 Scale = getI8Imm(AM.Scale,
DL);
277#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
278#define GET_NDM_IF_ENABLED(OPC) \
279 (Subtarget->hasNDD() && Subtarget->hasNDDM() ? OPC##_ND : OPC)
281 if (AM.NegateIndex) {
307 Index = CurDAG->getRegister(0, VT);
312 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(),
316 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
317 AM.Disp, AM.SymbolFlags);
319 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
320 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
321 }
else if (AM.MCSym) {
322 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
323 assert(AM.SymbolFlags == 0 &&
"oo");
324 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
325 }
else if (AM.JT != -1) {
326 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
327 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
328 }
else if (AM.BlockAddr)
329 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
332 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
335 Segment = AM.Segment;
337 Segment = CurDAG->getRegister(0, MVT::i16);
342 bool isAMXSDNode(SDNode *
N)
const {
346 for (
unsigned Idx = 0,
E =
N->getNumValues(); Idx !=
E; ++Idx) {
347 if (
N->getValueType(Idx) == MVT::x86amx)
350 for (
unsigned Idx = 0,
E =
N->getNumOperands(); Idx !=
E; ++Idx) {
352 if (
Op.getValueType() == MVT::x86amx)
364 bool shouldAvoidImmediateInstFormsForSize(SDNode *
N)
const {
365 uint32_t UseCount = 0;
370 if (!CurDAG->shouldOptForSize())
374 for (
const SDNode *User :
N->users()) {
380 if (
User->isMachineOpcode()) {
387 User->getOperand(1).getNode() ==
N) {
398 if (
User->getNumOperands() != 2)
411 if (
User->getOpcode() == X86ISD::ADD ||
413 User->getOpcode() == X86ISD::SUB ||
419 OtherOp =
User->getOperand(1);
422 RegisterSDNode *RegNode;
426 if ((RegNode->
getReg() == X86::ESP) ||
427 (RegNode->
getReg() == X86::RSP))
436 return (UseCount > 1);
440 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &
DL) {
441 return CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
445 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &
DL) {
446 return CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
450 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &
DL) {
451 return CurDAG->getTargetConstant(Imm,
DL, MVT::i64);
454 SDValue getExtractVEXTRACTImmediate(SDNode *
N,
unsigned VecWidth,
456 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
457 uint64_t
Index =
N->getConstantOperandVal(1);
458 MVT VecVT =
N->getOperand(0).getSimpleValueType();
462 SDValue getInsertVINSERTImmediate(SDNode *
N,
unsigned VecWidth,
464 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
465 uint64_t
Index =
N->getConstantOperandVal(2);
466 MVT VecVT =
N->getSimpleValueType(0);
470 SDValue getPermuteVINSERTCommutedImmediate(SDNode *
N,
unsigned VecWidth,
472 assert(VecWidth == 128 &&
"Unexpected vector width");
473 uint64_t
Index =
N->getConstantOperandVal(2);
474 MVT VecVT =
N->getSimpleValueType(0);
476 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
479 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
484 MVT VT =
N->getSimpleValueType(0);
487 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
489 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
490 if (VT == MVT::i64) {
492 CurDAG->getMachineNode(
493 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, Zero,
494 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
499 unsigned Opcode =
N->getOpcode();
500 assert((Opcode == X86ISD::SBB || Opcode == X86ISD::SETCC_CARRY) &&
501 "Unexpected opcode for SBB materialization");
502 unsigned FlagOpIndex = Opcode == X86ISD::SBB ? 2 : 1;
504 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
505 N->getOperand(FlagOpIndex),
SDValue());
509 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
510 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
511 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
513 CurDAG->getMachineNode(
Opc, dl, VTs,
514 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
520 bool isUnneededShiftMask(SDNode *
N,
unsigned Width)
const {
522 const APInt &Val =
N->getConstantOperandAPInt(1);
527 APInt
Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
528 return Mask.countr_one() >= Width;
534 SDNode *getGlobalBaseReg();
538 const X86TargetMachine &getTargetMachine()
const {
539 return static_cast<const X86TargetMachine &
>(TM);
544 const X86InstrInfo *getInstrInfo()
const {
545 return Subtarget->getInstrInfo();
554 bool ComplexPatternFuncMutatesDAG()
const override {
558 bool isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const;
561 bool useNonTemporalLoad(LoadSDNode *
N)
const {
562 if (!
N->isNonTemporal())
565 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
567 if (
N->getAlign().value() < StoreSize)
576 return Subtarget->hasSSE41();
578 return Subtarget->hasAVX2();
580 return Subtarget->hasAVX512();
584 bool foldLoadStoreIntoMemOperand(SDNode *Node);
585 MachineSDNode *matchBEXTRFromAndImm(SDNode *Node);
586 bool matchBitExtract(SDNode *Node);
587 bool shrinkAndImmediate(SDNode *
N);
588 bool isMaskZeroExtended(SDNode *
N)
const;
589 bool tryShiftAmountMod(SDNode *
N);
590 bool tryShrinkShlLogicImm(SDNode *
N);
591 bool tryVPTERNLOG(SDNode *
N);
592 bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentB,
596 bool tryMatchBitSelect(SDNode *
N);
598 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
599 const SDLoc &dl, MVT VT, SDNode *Node);
600 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
601 const SDLoc &dl, MVT VT, SDNode *Node,
604 bool tryOptimizeRem8Extend(SDNode *
N);
606 bool onlyUsesZeroFlag(
SDValue Flags)
const;
607 bool hasNoSignFlagUses(
SDValue Flags)
const;
608 bool hasNoCarryFlagUses(
SDValue Flags)
const;
609 bool checkTCRetEnoughRegs(SDNode *
N)
const;
615 explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm,
617 : SelectionDAGISelLegacy(
618 ID, std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
622char X86DAGToDAGISelLegacy::ID = 0;
629 unsigned Opcode =
N->getOpcode();
630 if (Opcode == X86ISD::CMPM || Opcode == X86ISD::CMPMM ||
631 Opcode == X86ISD::STRICT_CMPM || Opcode ==
ISD::SETCC ||
632 Opcode == X86ISD::CMPMM_SAE || Opcode == X86ISD::VFPCLASS) {
636 EVT OpVT =
N->getOperand(0).getValueType();
639 if (Opcode == X86ISD::STRICT_CMPM)
640 OpVT =
N->getOperand(1).getValueType();
642 return Subtarget->hasVLX();
647 if (Opcode == X86ISD::VFPCLASSS || Opcode == X86ISD::FSETCCM ||
648 Opcode == X86ISD::FSETCCM_SAE)
656bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
668X86DAGToDAGISel::IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const {
669 if (OptLevel == CodeGenOptLevel::None)
684 switch (
U->getOpcode()) {
711 if (
Imm->getAPIntValue().isSignedIntN(8))
720 Imm->getAPIntValue().getBitWidth() == 64 &&
721 Imm->getAPIntValue().isIntN(32))
728 (
Imm->getAPIntValue() == UINT8_MAX ||
729 Imm->getAPIntValue() == UINT16_MAX ||
730 Imm->getAPIntValue() == UINT32_MAX))
736 (-
Imm->getAPIntValue()).isSignedIntN(8))
739 if ((
U->getOpcode() == X86ISD::ADD ||
U->getOpcode() == X86ISD::SUB) &&
740 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
741 hasNoCarryFlagUses(
SDValue(U, 1)))
755 if (Op1.
getOpcode() == X86ISD::Wrapper) {
766 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
770 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
779 if (
C &&
C->getSExtValue() == -2)
785 if (
C &&
C->getSExtValue() == -2)
820bool X86DAGToDAGISel::isProfitableToFormMaskedOp(SDNode *
N)
const {
822 (
N->getOpcode() ==
ISD::VSELECT ||
N->getOpcode() == X86ISD::SELECTS) &&
823 "Unexpected opcode!");
828 return N->getOperand(1).hasOneUse();
837 if (Chain.
getNode() == Load.getNode())
838 Ops.push_back(Load.getOperand(0));
841 "Unexpected chain operand");
844 Ops.push_back(Load.getOperand(0));
850 Ops.push_back(NewChain);
855 Load.getOperand(1), Load.getOperand(2));
873 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
885 if (!Callee.getValue(1).hasOneUse())
916 Callee.getValue(1).hasOneUse())
933 if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
936 uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
937 0x65, 0x66, 0x67, 0xf0, 0xf2};
940 uint8_t Byte = (Imm >> i) & 0xFF;
952 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
955void X86DAGToDAGISel::PreprocessISelDAG() {
956 bool MadeChange =
false;
958 E = CurDAG->allnodes_end();
I !=
E; ) {
977 MVT VT =
N->getSimpleValueType(0);
979 int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
984 "cf-protection-branch");
987 SDValue Complement = CurDAG->getConstant(~Imm, dl, VT,
false,
true);
988 Complement = CurDAG->getNOT(dl, Complement, VT);
990 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Complement);
1000 if (
N->getOpcode() == X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
1002 N->getOperand(0),
N->getOperand(1));
1004 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1028 auto mayPreventLoadFold = [&]() {
1030 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1031 !
N->getOperand(1).hasOneUse();
1034 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1042 MVT VT =
N->getSimpleValueType(0);
1050 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1052 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1059 switch (
N->getOpcode()) {
1060 case X86ISD::VBROADCAST: {
1061 MVT VT =
N->getSimpleValueType(0);
1063 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1067 CurDAG->getNode(X86ISD::VBROADCAST, dl, NarrowVT,
N->getOperand(0));
1070 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1073 CurDAG->getIntPtrConstant(Index, dl));
1076 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1084 case X86ISD::VBROADCAST_LOAD: {
1085 MVT VT =
N->getSimpleValueType(0);
1087 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1091 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1092 SDValue Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1093 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1094 X86ISD::VBROADCAST_LOAD, dl, VTs,
Ops, MemNode->getMemoryVT(),
1095 MemNode->getMemOperand());
1098 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1101 CurDAG->getIntPtrConstant(Index, dl));
1105 CurDAG->ReplaceAllUsesWith(
N, To);
1117 MVT VT =
N->getSimpleValueType(0);
1123 SDNode *MaxLd =
nullptr;
1124 SDValue Ptr = Ld->getBasePtr();
1125 SDValue Chain = Ld->getChain();
1126 for (SDNode *User : Ptr->
users()) {
1128 MVT UserVT =
User->getSimpleValueType(0);
1130 UserLd->getBasePtr() == Ptr && UserLd->getChain() == Chain &&
1131 !
User->hasAnyUseOfValue(1) &&
1145 CurDAG->getIntPtrConstant(0, dl));
1146 SDValue Res = CurDAG->getBitcast(VT, Extract);
1150 CurDAG->ReplaceAllUsesWith(
N, To);
1159 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1160 if (EleVT == MVT::i1)
1163 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1164 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1165 "We can't replace VSELECT with BLENDV in vXi16!");
1167 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1169 R = CurDAG->getNode(X86ISD::VPTERNLOG, SDLoc(
N),
N->getValueType(0),
1170 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1171 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1173 R = CurDAG->getNode(X86ISD::BLENDV, SDLoc(
N),
N->getValueType(0),
1174 N->getOperand(0),
N->getOperand(1),
1178 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1191 if (!
N->getSimpleValueType(0).isVector())
1195 switch (
N->getOpcode()) {
1205 if (
N->isStrictFPOpcode())
1207 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1208 {
N->getOperand(0),
N->getOperand(1)});
1211 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1214 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1224 if (!
N->getValueType(0).isVector())
1228 switch (
N->getOpcode()) {
1230 case ISD::SHL: NewOpc = X86ISD::VSHLV;
break;
1231 case ISD::SRA: NewOpc = X86ISD::VSRAV;
break;
1232 case ISD::SRL: NewOpc = X86ISD::VSRLV;
break;
1234 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1235 N->getOperand(0),
N->getOperand(1));
1237 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1246 if (!
N->getValueType(0).isVector())
1250 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1252 "Unexpected opcode for mask vector!");
1260 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1263 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1283 switch (
N->getOpcode()) {
1299 bool IsStrict =
N->isStrictFPOpcode();
1302 Res = CurDAG->getNode(X86ISD::STRICT_VRNDSCALE, dl,
1303 {
N->getValueType(0), MVT::Other},
1304 {
N->getOperand(0),
N->getOperand(1),
1305 CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
1307 Res = CurDAG->getNode(X86ISD::VRNDSCALE, dl,
N->getValueType(0),
1309 CurDAG->getTargetConstant(Imm, dl, MVT::i32));
1311 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1319 case X86ISD::FXOR: {
1322 MVT VT =
N->getSimpleValueType(0);
1323 if (VT.
isVector() || VT == MVT::f128)
1326 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1327 : VT == MVT::f32 ? MVT::v4f32
1337 if (Subtarget->hasSSE2()) {
1338 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1342 switch (
N->getOpcode()) {
1344 case X86ISD::FANDN:
Opc = X86ISD::ANDNP;
break;
1349 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1352 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1355 CurDAG->getIntPtrConstant(0, dl));
1357 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1364 if (OptLevel != CodeGenOptLevel::None &&
1367 !Subtarget->useIndirectThunkCalls() &&
1368 ((
N->getOpcode() == X86ISD::CALL && !Subtarget->slowTwoMemOps() &&
1369 !Subtarget->slowIndirectCall()) ||
1370 (
N->getOpcode() == X86ISD::TC_RETURN &&
1371 (Subtarget->is64Bit() ||
1372 !getTargetMachine().isPositionIndependent())))) {
1392 bool HasCallSeq =
N->getOpcode() == X86ISD::CALL;
1397 if (
N->getOpcode() == X86ISD::TC_RETURN && !checkTCRetEnoughRegs(
N))
1413 switch (
N->getOpcode()) {
1418 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1419 MVT DstVT =
N->getSimpleValueType(0);
1427 const X86TargetLowering *X86Lowering =
1428 static_cast<const X86TargetLowering *
>(TLI);
1431 if (SrcIsSSE && DstIsSSE)
1434 if (!SrcIsSSE && !DstIsSSE) {
1439 if (
N->getConstantOperandVal(1))
1447 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1449 MachinePointerInfo MPI =
1456 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1458 MemTmp, MPI, MemVT);
1465 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1474 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1475 MVT DstVT =
N->getSimpleValueType(0);
1483 const X86TargetLowering *X86Lowering =
1484 static_cast<const X86TargetLowering *
>(TLI);
1487 if (SrcIsSSE && DstIsSSE)
1490 if (!SrcIsSSE && !DstIsSSE) {
1495 if (
N->getConstantOperandVal(2))
1503 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1505 MachinePointerInfo MPI =
1514 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1515 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1516 Store = CurDAG->getMemIntrinsicNode(X86ISD::FST, dl, VTs,
Ops, MemVT,
1519 if (
N->getFlags().hasNoFPExcept()) {
1521 Flags.setNoFPExcept(
true);
1522 Store->setFlags(Flags);
1525 assert(SrcVT == MemVT &&
"Unexpected VT!");
1526 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1531 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1533 Result = CurDAG->getMemIntrinsicNode(
1534 X86ISD::FLD, dl, VTs,
Ops, MemVT, MPI,
1536 if (
N->getFlags().hasNoFPExcept()) {
1538 Flags.setNoFPExcept(
true);
1542 assert(DstVT == MemVT &&
"Unexpected VT!");
1543 Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
1551 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1565 CurDAG->RemoveDeadNodes();
1569bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1570 unsigned Opc =
N->getMachineOpcode();
1571 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1572 Opc != X86::MOVSX64rr8)
1584 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1585 : X86::MOVSX32rr8_NOREX;
1590 if (
Opc == X86::MOVSX64rr8) {
1593 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1595 ReplaceUses(
N, Extend);
1604void X86DAGToDAGISel::PostprocessISelDAG() {
1606 if (TM.getOptLevel() == CodeGenOptLevel::None)
1611 bool MadeChange =
false;
1612 while (Position != CurDAG->allnodes_begin()) {
1613 SDNode *
N = &*--Position;
1615 if (
N->use_empty() || !
N->isMachineOpcode())
1618 if (tryOptimizeRem8Extend(
N)) {
1623 unsigned Opc =
N->getMachineOpcode();
1634 case X86::CTEST16rr:
1635 case X86::CTEST32rr:
1636 case X86::CTEST64rr: {
1642#define CASE_ND(OP) \
1645 switch (
And.getMachineOpcode()) {
1652 if (
And->hasAnyUseOfValue(1))
1655 Ops[0] =
And.getOperand(0);
1656 Ops[1] =
And.getOperand(1);
1657 MachineSDNode *
Test =
1658 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1659 ReplaceUses(
N,
Test);
1667 if (
And->hasAnyUseOfValue(1))
1670 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1671#define FROM_TO(A, B) \
1672 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1674 switch (
And.getMachineOpcode()) {
1684 And.getOperand(3),
And.getOperand(4),
1685 And.getOperand(5),
And.getOperand(0)};
1688 Ops.push_back(
N->getOperand(2));
1689 Ops.push_back(
N->getOperand(3));
1692 Ops.push_back(
And.getOperand(6));
1695 Ops.push_back(
N->getOperand(4));
1697 MachineSDNode *
Test = CurDAG->getMachineNode(
1698 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1699 CurDAG->setNodeMemRefs(
1712 case X86::KORTESTBkk:
1713 case X86::KORTESTWkk:
1714 case X86::KORTESTDkk:
1715 case X86::KORTESTQkk: {
1717 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1732#define FROM_TO(A, B) \
1744 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1747 MachineSDNode *KTest = CurDAG->getMachineNode(
1749 ReplaceUses(
N, KTest);
1754 case TargetOpcode::SUBREG_TO_REG: {
1755 unsigned SubRegIdx =
N->getConstantOperandVal(1);
1756 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1773 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1774 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1775 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1776 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1777 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1778 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1779 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1780 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1785 if (!
In.isMachineOpcode() ||
1786 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1791 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1799 CurDAG->UpdateNodeOperands(
N, In,
N->getOperand(1));
1806 CurDAG->RemoveDeadNodes();
1811void X86DAGToDAGISel::emitSpecialCodeForMain() {
1812 if (Subtarget->isTargetCygMing()) {
1813 TargetLowering::ArgListTy
Args;
1814 auto &
DL = CurDAG->getDataLayout();
1816 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1817 CLI.setChain(CurDAG->getRoot())
1818 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1819 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1821 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1823 CurDAG->setRoot(
Result.second);
1827void X86DAGToDAGISel::emitFunctionEntryCode() {
1830 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1831 emitSpecialCodeForMain();
1844bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t
Offset,
1845 X86ISelAddressMode &AM) {
1850 int64_t Val = AM.Disp +
Offset;
1853 if (Val != 0 && (AM.ES || AM.MCSym))
1857 if (Subtarget->is64Bit()) {
1860 AM.hasSymbolicDisplacement()))
1864 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1883 if (Subtarget->isTarget64BitILP32() &&
1885 !AM.hasBaseOrIndexReg())
1887 }
else if (Subtarget->is16Bit()) {
1890 if (Val < -(int64_t)UINT16_MAX || Val > (int64_t)UINT16_MAX)
1900bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1901 bool AllowSegmentRegForX32) {
1914 !IndirectTlsSegRefs &&
1915 (Subtarget->isTargetGlibc() || Subtarget->isTargetMusl() ||
1916 Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())) {
1917 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1919 switch (
N->getPointerInfo().getAddrSpace()) {
1921 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1924 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1937bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1940 if (AM.hasSymbolicDisplacement())
1943 bool IsRIPRelTLS =
false;
1944 bool IsRIPRel =
N.getOpcode() == X86ISD::WrapperRIP;
1961 if (IsRIPRel && AM.hasBaseOrIndexReg())
1965 X86ISelAddressMode Backup = AM;
1970 AM.GV =
G->getGlobal();
1971 AM.SymbolFlags =
G->getTargetFlags();
1974 AM.CP = CP->getConstVal();
1975 AM.Alignment = CP->getAlign();
1976 AM.SymbolFlags = CP->getTargetFlags();
1977 Offset = CP->getOffset();
1979 AM.ES = S->getSymbol();
1980 AM.SymbolFlags = S->getTargetFlags();
1982 AM.MCSym = S->getMCSymbol();
1984 AM.JT = J->getIndex();
1985 AM.SymbolFlags = J->getTargetFlags();
1987 AM.BlockAddr = BA->getBlockAddress();
1988 AM.SymbolFlags = BA->getTargetFlags();
1989 Offset = BA->getOffset();
1994 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1995 TM.isLargeGlobalValue(AM.GV)) {
2000 if (foldOffsetIntoAddress(
Offset, AM)) {
2006 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
2014bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
2015 if (matchAddressRecursively(
N, AM, 0))
2022 if (Subtarget->isTarget64BitILP32() &&
2023 AM.BaseType == X86ISelAddressMode::RegBase &&
2024 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
2025 SDValue Save_Base_Reg = AM.Base_Reg;
2028 if (matchLoadInAddress(LoadN, AM,
true))
2029 AM.Base_Reg = Save_Base_Reg;
2035 if (AM.Scale == 2 &&
2036 AM.BaseType == X86ISelAddressMode::RegBase &&
2037 AM.Base_Reg.
getNode() ==
nullptr) {
2038 AM.Base_Reg = AM.IndexReg;
2045 (!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2046 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2047 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2059 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2065bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
2069 HandleSDNode Handle(
N);
2071 X86ISelAddressMode Backup = AM;
2072 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
2073 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
2078 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
2080 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2087 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2090 N = Handle.getValue();
2096 N = Handle.getValue();
2106 if (
N->getNodeId() == -1 ||
2126 X86ISelAddressMode &AM) {
2133 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2134 Mask != (0xffu << ScaleLog))
2137 MVT XVT =
X.getSimpleValueType();
2138 MVT VT =
N.getSimpleValueType();
2163 AM.Scale = (1 << ScaleLog);
2171 X86ISelAddressMode &AM) {
2182 bool FoundAnyExtend =
false;
2186 FoundAnyExtend =
true;
2204 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2207 MVT VT =
N.getSimpleValueType();
2209 if (FoundAnyExtend) {
2230 AM.Scale = 1 << ShiftAmt;
2231 AM.IndexReg = NewAnd;
2265 X86ISelAddressMode &AM) {
2271 unsigned MaskIdx, MaskLen;
2274 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2280 unsigned AMShiftAmt = MaskIdx;
2284 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2288 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2289 if (MaskLZ < ScaleDown)
2291 MaskLZ -= ScaleDown;
2299 bool ReplacingAnyExtend =
false;
2301 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2302 X.getOperand(0).getSimpleValueType().getSizeInBits();
2305 X =
X.getOperand(0);
2306 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2307 ReplacingAnyExtend =
true;
2309 APInt MaskedHighBits =
2316 MVT VT =
N.getSimpleValueType();
2317 if (ReplacingAnyExtend) {
2318 assert(
X.getValueType() != VT);
2325 MVT XVT =
X.getSimpleValueType();
2346 AM.Scale = 1 << AMShiftAmt;
2347 AM.IndexReg = NewExt;
2357 X86ISelAddressMode &AM,
2365 if (!Subtarget.hasTBM() &&
2366 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2370 unsigned MaskIdx, MaskLen;
2378 unsigned AMShiftAmt = MaskIdx;
2382 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2384 MVT XVT =
X.getSimpleValueType();
2385 MVT VT =
N.getSimpleValueType();
2410 AM.Scale = 1 << AMShiftAmt;
2411 AM.IndexReg = NewExt;
2418 X86ISelAddressMode &AM,
2420 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2421 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2422 "Illegal index scale");
2428 EVT VT =
N.getValueType();
2429 unsigned Opc =
N.getOpcode();
2432 if (CurDAG->isBaseWithConstantOffset(
N)) {
2434 uint64_t
Offset = (uint64_t)AddVal->getSExtValue() * AM.Scale;
2435 if (!foldOffsetIntoAddress(
Offset, AM))
2436 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2440 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2441 if (AM.Scale <= 4) {
2443 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2448 if (
Opc == X86ISD::VSHLI) {
2449 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2450 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2451 if ((AM.Scale * ScaleAmt) <= 8) {
2452 AM.Scale *= ScaleAmt;
2453 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2461 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2463 if (CurDAG->isBaseWithConstantOffset(Src)) {
2464 SDValue AddSrc = Src.getOperand(0);
2466 int64_t
Offset = AddVal->getSExtValue();
2467 if (!foldOffsetIntoAddress((uint64_t)
Offset * AM.Scale, AM)) {
2475 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2476 CurDAG->RemoveDeadNode(
N.getNode());
2488 unsigned SrcOpc = Src.getOpcode();
2489 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2490 CurDAG->isADDLike(Src,
true)) &&
2492 if (CurDAG->isBaseWithConstantOffset(Src)) {
2493 SDValue AddSrc = Src.getOperand(0);
2494 uint64_t
Offset = Src.getConstantOperandVal(1);
2495 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2505 uint64_t ScaleAmt = 1ULL << ShAmt;
2506 if ((AM.Scale * ScaleAmt) <= 8 &&
2508 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2509 AM.Scale *= ScaleAmt;
2510 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2521 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2525 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2526 CurDAG->RemoveDeadNode(
N.getNode());
2527 return Res ? Res : ExtSrc;
2537bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2540 dbgs() <<
"MatchAddress: ";
2545 return matchAddressBase(
N, AM);
2550 if (AM.isRIPRelative()) {
2554 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2558 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2563 switch (
N.getOpcode()) {
2566 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2569 AM.MCSym = ESNode->getMCSymbol();
2576 if (!foldOffsetIntoAddress(Val, AM))
2581 case X86ISD::Wrapper:
2582 case X86ISD::WrapperRIP:
2583 if (!matchWrapper(
N, AM))
2593 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2594 AM.Base_Reg.
getNode() ==
nullptr &&
2596 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2603 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2607 unsigned Val = CN->getZExtValue();
2612 if (Val == 1 || Val == 2 || Val == 3) {
2614 AM.Scale = 1 << Val;
2615 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2623 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2627 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2628 "Unexpected value size!");
2640 uint64_t
Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2652 if (
N.getResNo() != 0)
break;
2655 case X86ISD::MUL_IMM:
2657 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2658 AM.Base_Reg.
getNode() ==
nullptr &&
2659 AM.IndexReg.
getNode() ==
nullptr) {
2661 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2662 CN->getZExtValue() == 9) {
2663 AM.Scale = unsigned(CN->getZExtValue())-1;
2675 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2676 if (foldOffsetIntoAddress(Disp, AM))
2677 Reg =
N.getOperand(0);
2679 Reg =
N.getOperand(0);
2682 AM.IndexReg = AM.Base_Reg =
Reg;
2698 HandleSDNode Handle(
N);
2701 X86ISelAddressMode Backup = AM;
2702 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2703 N = Handle.getValue();
2707 N = Handle.getValue();
2709 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2724 RHS.getOperand(0).getValueType() == MVT::i32))
2728 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2730 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2734 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2735 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2748 AM.NegateIndex =
true;
2756 if (!CurDAG->isADDLike(
N))
2760 if (!matchAdd(
N, AM,
Depth))
2769 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2773 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2774 "Unexpected value size!");
2779 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2783 uint64_t
Mask =
N.getConstantOperandVal(1);
2808 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2816 if (
SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2818 AM.IndexReg =
Index;
2824 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2826 Mask = MaskC->getAPIntValue();
2827 Src = Src.getOperand(0);
2830 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2832 SDValue ShlSrc = Src.getOperand(0);
2833 SDValue ShlAmt = Src.getOperand(1);
2837 unsigned ShAmtV = ShAmtC->getZExtValue();
2845 if (!Src->getFlags().hasNoUnsignedWrap() &&
2846 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2854 MVT VT =
N.getSimpleValueType();
2858 if (!
Mask.isAllOnes()) {
2859 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2861 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2868 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2869 CurDAG->RemoveDeadNode(
N.getNode());
2872 AM.Scale = 1 << ShAmtV;
2876 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2880 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2883 Src.getOperand(0), AM))
2888 Src.getOperand(0), AM))
2893 Src.getOperand(0), AM, *Subtarget))
2901 return matchAddressBase(
N, AM);
2906bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2908 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
2921 AM.BaseType = X86ISelAddressMode::RegBase;
2926bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2927 X86ISelAddressMode &AM,
2930 dbgs() <<
"MatchVectorAddress: ";
2935 return matchAddressBase(
N, AM);
2938 switch (
N.getOpcode()) {
2941 if (!foldOffsetIntoAddress(Val, AM))
2945 case X86ISD::Wrapper:
2946 if (!matchWrapper(
N, AM))
2952 HandleSDNode Handle(
N);
2954 X86ISelAddressMode Backup = AM;
2955 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2956 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2962 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2964 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2969 N = Handle.getValue();
2974 return matchAddressBase(
N, AM);
2980bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2981 return matchVectorAddressRecursively(
N, AM, 0);
2984bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
2989 X86ISelAddressMode AM;
2995 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2997 AM.IndexReg = IndexOp;
3001 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3003 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3005 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3008 MVT VT =
BasePtr.getSimpleValueType();
3011 if (matchVectorAddress(BasePtr, AM))
3014 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3027 SDValue &Segment,
bool HasNDDM) {
3028 X86ISelAddressMode AM;
3035 Parent->
getOpcode() != X86ISD::TLSCALL &&
3036 Parent->
getOpcode() != X86ISD::ENQCMD &&
3037 Parent->
getOpcode() != X86ISD::ENQCMDS &&
3038 Parent->
getOpcode() != X86ISD::EH_SJLJ_SETJMP &&
3039 Parent->
getOpcode() != X86ISD::EH_SJLJ_LONGJMP) {
3040 unsigned AddrSpace =
3043 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3045 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3047 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3052 MVT VT =
N.getSimpleValueType();
3054 if (matchAddress(
N, AM))
3057 if (!HasNDDM && !AM.isRIPRelative())
3060 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3067 return selectAddr(Parent,
N,
Base, Scale, Index, Disp, Segment,
3068 Subtarget->hasNDDM());
3080 if (
N->getOpcode() != X86ISD::Wrapper)
3083 N =
N.getOperand(0);
3100 return CR->getUnsignedMax().ult(1ull << 32);
3102 return !TM.isLargeGlobalValue(GV);
3111 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3117 SubReg = X86::sub_8bit;
3119 SubReg = X86::sub_16bit;
3121 SubReg = X86::sub_32bit;
3124 if (RN &&
RN->getReg() == 0)
3125 Base = CurDAG->getRegister(0, MVT::i64);
3132 Base = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef,
Base);
3135 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3137 if (RN &&
RN->getReg() == 0)
3138 Index = CurDAG->getRegister(0, MVT::i64);
3141 "Expect to be extending 8/16/32-bit registers for use in LEA");
3144 Index = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef, Index);
3152bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3156 X86ISelAddressMode AM;
3160 MVT VT =
N.getSimpleValueType();
3165 SDValue T = CurDAG->getRegister(0, MVT::i32);
3167 if (matchAddress(
N, AM))
3172 unsigned Complexity = 0;
3173 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3175 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3191 if (AM.hasSymbolicDisplacement()) {
3193 if (Subtarget->is64Bit())
3203 auto isMathWithFlags = [](
SDValue V) {
3204 switch (
V.getOpcode()) {
3218 return !
SDValue(
V.getNode(), 1).use_empty();
3225 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3233 if (Complexity <= 2)
3236 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3247 X86ISelAddressMode AM;
3249 AM.GV = GA->getGlobal();
3250 AM.Disp += GA->getOffset();
3251 AM.SymbolFlags = GA->getTargetFlags();
3254 AM.ES = SA->getSymbol();
3255 AM.SymbolFlags = SA->getTargetFlags();
3258 if (Subtarget->is32Bit()) {
3260 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3263 MVT VT =
N.getSimpleValueType();
3264 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3272 EVT VT =
N.getValueType();
3273 bool WasTruncated =
false;
3275 WasTruncated =
true;
3276 N =
N.getOperand(0);
3279 if (
N.getOpcode() != X86ISD::Wrapper)
3285 unsigned Opc =
N.getOperand(0)->getOpcode();
3287 Op =
N.getOperand(0);
3290 return !WasTruncated;
3295 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3296 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3300 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3301 GA->getOffset(), GA->getTargetFlags());
3305bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
3309 assert(Root &&
P &&
"Unknown root/parent nodes");
3311 !IsProfitableToFold(
N,
P, Root) ||
3312 !IsLegalToFold(
N,
P, Root, OptLevel))
3315 return selectAddr(
N.getNode(),
3316 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3319bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
3323 assert(Root &&
P &&
"Unknown root/parent nodes");
3324 if (
N->getOpcode() != X86ISD::VBROADCAST_LOAD ||
3325 !IsProfitableToFold(
N,
P, Root) ||
3326 !IsLegalToFold(
N,
P, Root, OptLevel))
3329 return selectAddr(
N.getNode(),
3330 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3336SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3339 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3342bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3344 N =
N->getOperand(0).getNode();
3345 if (
N->getOpcode() != X86ISD::Wrapper)
3352 auto *GV = GA->getGlobal();
3355 return CR->getSignedMin().sge(-1ull << Width) &&
3356 CR->getSignedMax().slt(1ull << Width);
3362 !TM.isLargeGlobalValue(GV);
3366 assert(
N->isMachineOpcode() &&
"Unexpected node");
3367 unsigned Opc =
N->getMachineOpcode();
3368 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3373 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3378bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3380 for (SDUse &Use :
Flags->uses()) {
3382 if (
Use.getResNo() !=
Flags.getResNo())
3390 for (SDUse &FlagUse :
User->uses()) {
3392 if (FlagUse.getResNo() != 1)
3395 if (!FlagUse.getUser()->isMachineOpcode())
3415bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3417 for (SDUse &Use :
Flags->uses()) {
3419 if (
Use.getResNo() !=
Flags.getResNo())
3427 for (SDUse &FlagUse :
User->uses()) {
3429 if (FlagUse.getResNo() != 1)
3432 if (!FlagUse.getUser()->isMachineOpcode())
3472 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3474 for (SDUse &Use :
Flags->uses()) {
3476 if (
Use.getResNo() !=
Flags.getResNo())
3480 unsigned UserOpc =
User->getOpcode();
3487 for (SDUse &FlagUse :
User->uses()) {
3489 if (FlagUse.getResNo() != 1)
3492 if (!FlagUse.getUser()->isMachineOpcode())
3512 case X86ISD::SETCC: CCOpNo = 0;
break;
3513 case X86ISD::SETCC_CARRY: CCOpNo = 0;
break;
3514 case X86ISD::CMOV: CCOpNo = 2;
break;
3515 case X86ISD::BRCOND: CCOpNo = 2;
break;
3525bool X86DAGToDAGISel::checkTCRetEnoughRegs(SDNode *
N)
const {
3528 const X86RegisterInfo *RI = Subtarget->getRegisterInfo();
3532 if (Subtarget->is64Bit()) {
3533 const TargetRegisterClass *TCGPRs =
3535 ? &X86::GR64_TCW64RegClass
3536 : &X86::GR64_TCRegClass;
3542 const TargetRegisterClass *TCGPRs =
3544 ? &X86::GR32RegClass
3545 : &X86::GR32_TCRegClass;
3552 unsigned LoadGPRs = 2;
3554 assert(
N->getOpcode() == X86ISD::TC_RETURN);
3557 if (Subtarget->is32Bit()) {
3563 }
else if (
BasePtr.getOpcode() == X86ISD::Wrapper &&
3565 assert(!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
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.
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.
unsigned getNumRegs() const
Return the number of registers in this class.
unsigned getID() const
Return the register class ID number.
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
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)
FunctionAddr VTableAddr Value
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.
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.
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.
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