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 (
N->getOpcode() == X86ISD::TC_RETURN &&
1370 (Subtarget->is64Bit() ||
1371 !getTargetMachine().isPositionIndependent())))) {
1391 bool HasCallSeq =
N->getOpcode() == X86ISD::CALL;
1396 if (
N->getOpcode() == X86ISD::TC_RETURN && !checkTCRetEnoughRegs(
N))
1412 switch (
N->getOpcode()) {
1417 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1418 MVT DstVT =
N->getSimpleValueType(0);
1426 const X86TargetLowering *X86Lowering =
1427 static_cast<const X86TargetLowering *
>(TLI);
1430 if (SrcIsSSE && DstIsSSE)
1433 if (!SrcIsSSE && !DstIsSSE) {
1438 if (
N->getConstantOperandVal(1))
1446 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1448 MachinePointerInfo MPI =
1455 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1457 MemTmp, MPI, MemVT);
1464 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1473 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1474 MVT DstVT =
N->getSimpleValueType(0);
1482 const X86TargetLowering *X86Lowering =
1483 static_cast<const X86TargetLowering *
>(TLI);
1486 if (SrcIsSSE && DstIsSSE)
1489 if (!SrcIsSSE && !DstIsSSE) {
1494 if (
N->getConstantOperandVal(2))
1502 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1504 MachinePointerInfo MPI =
1513 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1514 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1515 Store = CurDAG->getMemIntrinsicNode(X86ISD::FST, dl, VTs,
Ops, MemVT,
1518 if (
N->getFlags().hasNoFPExcept()) {
1520 Flags.setNoFPExcept(
true);
1521 Store->setFlags(Flags);
1524 assert(SrcVT == MemVT &&
"Unexpected VT!");
1525 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1530 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1532 Result = CurDAG->getMemIntrinsicNode(
1533 X86ISD::FLD, dl, VTs,
Ops, MemVT, MPI,
1535 if (
N->getFlags().hasNoFPExcept()) {
1537 Flags.setNoFPExcept(
true);
1541 assert(DstVT == MemVT &&
"Unexpected VT!");
1542 Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
1550 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1564 CurDAG->RemoveDeadNodes();
1568bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1569 unsigned Opc =
N->getMachineOpcode();
1570 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1571 Opc != X86::MOVSX64rr8)
1583 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1584 : X86::MOVSX32rr8_NOREX;
1589 if (
Opc == X86::MOVSX64rr8) {
1592 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1594 ReplaceUses(
N, Extend);
1603void X86DAGToDAGISel::PostprocessISelDAG() {
1605 if (TM.getOptLevel() == CodeGenOptLevel::None)
1610 bool MadeChange =
false;
1611 while (Position != CurDAG->allnodes_begin()) {
1612 SDNode *
N = &*--Position;
1614 if (
N->use_empty() || !
N->isMachineOpcode())
1617 if (tryOptimizeRem8Extend(
N)) {
1622 unsigned Opc =
N->getMachineOpcode();
1633 case X86::CTEST16rr:
1634 case X86::CTEST32rr:
1635 case X86::CTEST64rr: {
1641#define CASE_ND(OP) \
1644 switch (
And.getMachineOpcode()) {
1651 if (
And->hasAnyUseOfValue(1))
1654 Ops[0] =
And.getOperand(0);
1655 Ops[1] =
And.getOperand(1);
1656 MachineSDNode *
Test =
1657 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1658 ReplaceUses(
N,
Test);
1666 if (
And->hasAnyUseOfValue(1))
1669 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1670#define FROM_TO(A, B) \
1671 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1673 switch (
And.getMachineOpcode()) {
1683 And.getOperand(3),
And.getOperand(4),
1684 And.getOperand(5),
And.getOperand(0)};
1687 Ops.push_back(
N->getOperand(2));
1688 Ops.push_back(
N->getOperand(3));
1691 Ops.push_back(
And.getOperand(6));
1694 Ops.push_back(
N->getOperand(4));
1696 MachineSDNode *
Test = CurDAG->getMachineNode(
1697 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1698 CurDAG->setNodeMemRefs(
1711 case X86::KORTESTBkk:
1712 case X86::KORTESTWkk:
1713 case X86::KORTESTDkk:
1714 case X86::KORTESTQkk: {
1716 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1731#define FROM_TO(A, B) \
1743 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1746 MachineSDNode *KTest = CurDAG->getMachineNode(
1748 ReplaceUses(
N, KTest);
1753 case TargetOpcode::SUBREG_TO_REG: {
1754 unsigned SubRegIdx =
N->getConstantOperandVal(1);
1755 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1772 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1773 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1774 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1775 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1776 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1777 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1778 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1779 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1784 if (!
In.isMachineOpcode() ||
1785 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1790 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1798 CurDAG->UpdateNodeOperands(
N, In,
N->getOperand(1));
1805 CurDAG->RemoveDeadNodes();
1810void X86DAGToDAGISel::emitSpecialCodeForMain() {
1811 if (Subtarget->isTargetCygMing()) {
1812 TargetLowering::ArgListTy
Args;
1813 auto &
DL = CurDAG->getDataLayout();
1815 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1816 CLI.setChain(CurDAG->getRoot())
1817 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1818 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1820 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1822 CurDAG->setRoot(
Result.second);
1826void X86DAGToDAGISel::emitFunctionEntryCode() {
1829 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1830 emitSpecialCodeForMain();
1843bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t
Offset,
1844 X86ISelAddressMode &AM) {
1849 int64_t Val = AM.Disp +
Offset;
1852 if (Val != 0 && (AM.ES || AM.MCSym))
1856 if (Subtarget->is64Bit()) {
1859 AM.hasSymbolicDisplacement()))
1863 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1882 if (Subtarget->isTarget64BitILP32() &&
1884 !AM.hasBaseOrIndexReg())
1886 }
else if (Subtarget->is16Bit()) {
1889 if (Val < -(int64_t)UINT16_MAX || Val > (int64_t)UINT16_MAX)
1899bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1900 bool AllowSegmentRegForX32) {
1913 !IndirectTlsSegRefs &&
1914 (Subtarget->isTargetGlibc() || Subtarget->isTargetMusl() ||
1915 Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())) {
1916 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1918 switch (
N->getPointerInfo().getAddrSpace()) {
1920 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1923 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1936bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1939 if (AM.hasSymbolicDisplacement())
1942 bool IsRIPRelTLS =
false;
1943 bool IsRIPRel =
N.getOpcode() == X86ISD::WrapperRIP;
1960 if (IsRIPRel && AM.hasBaseOrIndexReg())
1964 X86ISelAddressMode Backup = AM;
1969 AM.GV =
G->getGlobal();
1970 AM.SymbolFlags =
G->getTargetFlags();
1973 AM.CP = CP->getConstVal();
1974 AM.Alignment = CP->getAlign();
1975 AM.SymbolFlags = CP->getTargetFlags();
1976 Offset = CP->getOffset();
1978 AM.ES = S->getSymbol();
1979 AM.SymbolFlags = S->getTargetFlags();
1981 AM.MCSym = S->getMCSymbol();
1983 AM.JT = J->getIndex();
1984 AM.SymbolFlags = J->getTargetFlags();
1986 AM.BlockAddr = BA->getBlockAddress();
1987 AM.SymbolFlags = BA->getTargetFlags();
1988 Offset = BA->getOffset();
1993 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1994 TM.isLargeGlobalValue(AM.GV)) {
1999 if (foldOffsetIntoAddress(
Offset, AM)) {
2005 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
2013bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
2014 if (matchAddressRecursively(
N, AM, 0))
2021 if (Subtarget->isTarget64BitILP32() &&
2022 AM.BaseType == X86ISelAddressMode::RegBase &&
2023 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
2024 SDValue Save_Base_Reg = AM.Base_Reg;
2027 if (matchLoadInAddress(LoadN, AM,
true))
2028 AM.Base_Reg = Save_Base_Reg;
2034 if (AM.Scale == 2 &&
2035 AM.BaseType == X86ISelAddressMode::RegBase &&
2036 AM.Base_Reg.
getNode() ==
nullptr) {
2037 AM.Base_Reg = AM.IndexReg;
2044 (!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2045 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2046 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2058 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2064bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
2068 HandleSDNode Handle(
N);
2070 X86ISelAddressMode Backup = AM;
2071 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
2072 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
2077 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
2079 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2086 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2089 N = Handle.getValue();
2095 N = Handle.getValue();
2105 if (
N->getNodeId() == -1 ||
2125 X86ISelAddressMode &AM) {
2132 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2133 Mask != (0xffu << ScaleLog))
2136 MVT XVT =
X.getSimpleValueType();
2137 MVT VT =
N.getSimpleValueType();
2162 AM.Scale = (1 << ScaleLog);
2170 X86ISelAddressMode &AM) {
2181 bool FoundAnyExtend =
false;
2185 FoundAnyExtend =
true;
2203 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2206 MVT VT =
N.getSimpleValueType();
2208 if (FoundAnyExtend) {
2229 AM.Scale = 1 << ShiftAmt;
2230 AM.IndexReg = NewAnd;
2264 X86ISelAddressMode &AM) {
2270 unsigned MaskIdx, MaskLen;
2273 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2279 unsigned AMShiftAmt = MaskIdx;
2283 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2287 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2288 if (MaskLZ < ScaleDown)
2290 MaskLZ -= ScaleDown;
2298 bool ReplacingAnyExtend =
false;
2300 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2301 X.getOperand(0).getSimpleValueType().getSizeInBits();
2304 X =
X.getOperand(0);
2305 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2306 ReplacingAnyExtend =
true;
2308 APInt MaskedHighBits =
2315 MVT VT =
N.getSimpleValueType();
2316 if (ReplacingAnyExtend) {
2317 assert(
X.getValueType() != VT);
2324 MVT XVT =
X.getSimpleValueType();
2345 AM.Scale = 1 << AMShiftAmt;
2346 AM.IndexReg = NewExt;
2356 X86ISelAddressMode &AM,
2364 if (!Subtarget.hasTBM() &&
2365 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2369 unsigned MaskIdx, MaskLen;
2377 unsigned AMShiftAmt = MaskIdx;
2381 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2383 MVT XVT =
X.getSimpleValueType();
2384 MVT VT =
N.getSimpleValueType();
2409 AM.Scale = 1 << AMShiftAmt;
2410 AM.IndexReg = NewExt;
2417 X86ISelAddressMode &AM,
2419 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2420 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2421 "Illegal index scale");
2427 EVT VT =
N.getValueType();
2428 unsigned Opc =
N.getOpcode();
2431 if (CurDAG->isBaseWithConstantOffset(
N)) {
2433 uint64_t
Offset = (uint64_t)AddVal->getSExtValue() * AM.Scale;
2434 if (!foldOffsetIntoAddress(
Offset, AM))
2435 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2439 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2440 if (AM.Scale <= 4) {
2442 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2447 if (
Opc == X86ISD::VSHLI) {
2448 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2449 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2450 if ((AM.Scale * ScaleAmt) <= 8) {
2451 AM.Scale *= ScaleAmt;
2452 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2460 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2462 if (CurDAG->isBaseWithConstantOffset(Src)) {
2463 SDValue AddSrc = Src.getOperand(0);
2465 int64_t
Offset = AddVal->getSExtValue();
2466 if (!foldOffsetIntoAddress((uint64_t)
Offset * AM.Scale, AM)) {
2474 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2475 CurDAG->RemoveDeadNode(
N.getNode());
2487 unsigned SrcOpc = Src.getOpcode();
2488 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2489 CurDAG->isADDLike(Src,
true)) &&
2491 if (CurDAG->isBaseWithConstantOffset(Src)) {
2492 SDValue AddSrc = Src.getOperand(0);
2493 uint64_t
Offset = Src.getConstantOperandVal(1);
2494 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2504 uint64_t ScaleAmt = 1ULL << ShAmt;
2505 if ((AM.Scale * ScaleAmt) <= 8 &&
2507 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2508 AM.Scale *= ScaleAmt;
2509 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2520 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2524 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2525 CurDAG->RemoveDeadNode(
N.getNode());
2526 return Res ? Res : ExtSrc;
2536bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2539 dbgs() <<
"MatchAddress: ";
2544 return matchAddressBase(
N, AM);
2549 if (AM.isRIPRelative()) {
2553 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2557 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2562 switch (
N.getOpcode()) {
2565 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2568 AM.MCSym = ESNode->getMCSymbol();
2575 if (!foldOffsetIntoAddress(Val, AM))
2580 case X86ISD::Wrapper:
2581 case X86ISD::WrapperRIP:
2582 if (!matchWrapper(
N, AM))
2592 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2593 AM.Base_Reg.
getNode() ==
nullptr &&
2595 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2602 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2606 unsigned Val = CN->getZExtValue();
2611 if (Val == 1 || Val == 2 || Val == 3) {
2613 AM.Scale = 1 << Val;
2614 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2622 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2626 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2627 "Unexpected value size!");
2639 uint64_t
Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2651 if (
N.getResNo() != 0)
break;
2654 case X86ISD::MUL_IMM:
2656 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2657 AM.Base_Reg.
getNode() ==
nullptr &&
2658 AM.IndexReg.
getNode() ==
nullptr) {
2660 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2661 CN->getZExtValue() == 9) {
2662 AM.Scale = unsigned(CN->getZExtValue())-1;
2674 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2675 if (foldOffsetIntoAddress(Disp, AM))
2676 Reg =
N.getOperand(0);
2678 Reg =
N.getOperand(0);
2681 AM.IndexReg = AM.Base_Reg =
Reg;
2697 HandleSDNode Handle(
N);
2700 X86ISelAddressMode Backup = AM;
2701 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2702 N = Handle.getValue();
2706 N = Handle.getValue();
2708 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2723 RHS.getOperand(0).getValueType() == MVT::i32))
2727 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2729 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2733 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2734 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2747 AM.NegateIndex =
true;
2755 if (!CurDAG->isADDLike(
N))
2759 if (!matchAdd(
N, AM,
Depth))
2768 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2772 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2773 "Unexpected value size!");
2778 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2782 uint64_t
Mask =
N.getConstantOperandVal(1);
2807 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2815 if (
SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2817 AM.IndexReg =
Index;
2823 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2825 Mask = MaskC->getAPIntValue();
2826 Src = Src.getOperand(0);
2829 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2831 SDValue ShlSrc = Src.getOperand(0);
2832 SDValue ShlAmt = Src.getOperand(1);
2836 unsigned ShAmtV = ShAmtC->getZExtValue();
2844 if (!Src->getFlags().hasNoUnsignedWrap() &&
2845 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2853 MVT VT =
N.getSimpleValueType();
2857 if (!
Mask.isAllOnes()) {
2858 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2860 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2867 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2868 CurDAG->RemoveDeadNode(
N.getNode());
2871 AM.Scale = 1 << ShAmtV;
2875 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2879 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2882 Src.getOperand(0), AM))
2887 Src.getOperand(0), AM))
2892 Src.getOperand(0), AM, *Subtarget))
2900 return matchAddressBase(
N, AM);
2905bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2907 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
2920 AM.BaseType = X86ISelAddressMode::RegBase;
2925bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2926 X86ISelAddressMode &AM,
2929 dbgs() <<
"MatchVectorAddress: ";
2934 return matchAddressBase(
N, AM);
2937 switch (
N.getOpcode()) {
2940 if (!foldOffsetIntoAddress(Val, AM))
2944 case X86ISD::Wrapper:
2945 if (!matchWrapper(
N, AM))
2951 HandleSDNode Handle(
N);
2953 X86ISelAddressMode Backup = AM;
2954 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2955 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2961 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2963 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2968 N = Handle.getValue();
2973 return matchAddressBase(
N, AM);
2979bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2980 return matchVectorAddressRecursively(
N, AM, 0);
2983bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
2988 X86ISelAddressMode AM;
2994 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2996 AM.IndexReg = IndexOp;
3000 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3002 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3004 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3007 MVT VT =
BasePtr.getSimpleValueType();
3010 if (matchVectorAddress(BasePtr, AM))
3013 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3026 SDValue &Segment,
bool HasNDDM) {
3027 X86ISelAddressMode AM;
3034 Parent->
getOpcode() != X86ISD::TLSCALL &&
3035 Parent->
getOpcode() != X86ISD::ENQCMD &&
3036 Parent->
getOpcode() != X86ISD::ENQCMDS &&
3037 Parent->
getOpcode() != X86ISD::EH_SJLJ_SETJMP &&
3038 Parent->
getOpcode() != X86ISD::EH_SJLJ_LONGJMP) {
3039 unsigned AddrSpace =
3042 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3044 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3046 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3051 MVT VT =
N.getSimpleValueType();
3053 if (matchAddress(
N, AM))
3056 if (!HasNDDM && !AM.isRIPRelative())
3059 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3066 return selectAddr(Parent,
N,
Base, Scale, Index, Disp, Segment,
3067 Subtarget->hasNDDM());
3079 if (
N->getOpcode() != X86ISD::Wrapper)
3082 N =
N.getOperand(0);
3099 return CR->getUnsignedMax().ult(1ull << 32);
3101 return !TM.isLargeGlobalValue(GV);
3110 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3116 SubReg = X86::sub_8bit;
3118 SubReg = X86::sub_16bit;
3120 SubReg = X86::sub_32bit;
3123 if (RN &&
RN->getReg() == 0)
3124 Base = CurDAG->getRegister(0, MVT::i64);
3131 Base = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef,
Base);
3134 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3136 if (RN &&
RN->getReg() == 0)
3137 Index = CurDAG->getRegister(0, MVT::i64);
3140 "Expect to be extending 8/16/32-bit registers for use in LEA");
3143 Index = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef, Index);
3151bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3155 X86ISelAddressMode AM;
3159 MVT VT =
N.getSimpleValueType();
3164 SDValue T = CurDAG->getRegister(0, MVT::i32);
3166 if (matchAddress(
N, AM))
3171 unsigned Complexity = 0;
3172 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3174 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3190 if (AM.hasSymbolicDisplacement()) {
3192 if (Subtarget->is64Bit())
3202 auto isMathWithFlags = [](
SDValue V) {
3203 switch (
V.getOpcode()) {
3217 return !
SDValue(
V.getNode(), 1).use_empty();
3224 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3232 if (Complexity <= 2)
3235 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3246 X86ISelAddressMode AM;
3248 AM.GV = GA->getGlobal();
3249 AM.Disp += GA->getOffset();
3250 AM.SymbolFlags = GA->getTargetFlags();
3253 AM.ES = SA->getSymbol();
3254 AM.SymbolFlags = SA->getTargetFlags();
3257 if (Subtarget->is32Bit()) {
3259 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3262 MVT VT =
N.getSimpleValueType();
3263 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3271 EVT VT =
N.getValueType();
3272 bool WasTruncated =
false;
3274 WasTruncated =
true;
3275 N =
N.getOperand(0);
3278 if (
N.getOpcode() != X86ISD::Wrapper)
3284 unsigned Opc =
N.getOperand(0)->getOpcode();
3286 Op =
N.getOperand(0);
3289 return !WasTruncated;
3294 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3295 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3299 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3300 GA->getOffset(), GA->getTargetFlags());
3304bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
3308 assert(Root &&
P &&
"Unknown root/parent nodes");
3310 !IsProfitableToFold(
N,
P, Root) ||
3311 !IsLegalToFold(
N,
P, Root, OptLevel))
3314 return selectAddr(
N.getNode(),
3315 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3318bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
3322 assert(Root &&
P &&
"Unknown root/parent nodes");
3323 if (
N->getOpcode() != X86ISD::VBROADCAST_LOAD ||
3324 !IsProfitableToFold(
N,
P, Root) ||
3325 !IsLegalToFold(
N,
P, Root, OptLevel))
3328 return selectAddr(
N.getNode(),
3329 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3335SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3338 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3341bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3343 N =
N->getOperand(0).getNode();
3344 if (
N->getOpcode() != X86ISD::Wrapper)
3351 auto *GV = GA->getGlobal();
3354 return CR->getSignedMin().sge(-1ull << Width) &&
3355 CR->getSignedMax().slt(1ull << Width);
3361 !TM.isLargeGlobalValue(GV);
3365 assert(
N->isMachineOpcode() &&
"Unexpected node");
3366 unsigned Opc =
N->getMachineOpcode();
3367 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3372 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3377bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3379 for (SDUse &Use :
Flags->uses()) {
3381 if (
Use.getResNo() !=
Flags.getResNo())
3389 for (SDUse &FlagUse :
User->uses()) {
3391 if (FlagUse.getResNo() != 1)
3394 if (!FlagUse.getUser()->isMachineOpcode())
3414bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3416 for (SDUse &Use :
Flags->uses()) {
3418 if (
Use.getResNo() !=
Flags.getResNo())
3426 for (SDUse &FlagUse :
User->uses()) {
3428 if (FlagUse.getResNo() != 1)
3431 if (!FlagUse.getUser()->isMachineOpcode())
3471 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3473 for (SDUse &Use :
Flags->uses()) {
3475 if (
Use.getResNo() !=
Flags.getResNo())
3479 unsigned UserOpc =
User->getOpcode();
3486 for (SDUse &FlagUse :
User->uses()) {
3488 if (FlagUse.getResNo() != 1)
3491 if (!FlagUse.getUser()->isMachineOpcode())
3511 case X86ISD::SETCC: CCOpNo = 0;
break;
3512 case X86ISD::SETCC_CARRY: CCOpNo = 0;
break;
3513 case X86ISD::CMOV: CCOpNo = 2;
break;
3514 case X86ISD::BRCOND: CCOpNo = 2;
break;
3524bool X86DAGToDAGISel::checkTCRetEnoughRegs(SDNode *
N)
const {
3527 const X86RegisterInfo *RI = Subtarget->getRegisterInfo();
3531 if (Subtarget->is64Bit()) {
3532 const TargetRegisterClass *TCGPRs =
3534 ? &X86::GR64_TCW64RegClass
3535 : &X86::GR64_TCRegClass;
3541 const TargetRegisterClass *TCGPRs =
3543 ? &X86::GR32RegClass
3544 : &X86::GR32_TCRegClass;
3551 unsigned LoadGPRs = 2;
3553 assert(
N->getOpcode() == X86ISD::TC_RETURN);
3556 if (Subtarget->is32Bit()) {
3562 }
else if (
BasePtr.getOpcode() == X86ISD::Wrapper &&
3564 assert(!getTargetMachine().isPositionIndependent());
3571 for (
unsigned I = 3,
E =
N->getNumOperands();
I !=
E; ++
I) {
3573 if (!RI->isGeneralPurposeRegister(*MF,
RN->getReg()))
3575 if (++
ArgGPRs + LoadGPRs > AvailGPRs)
3591 if (StoredVal.
getResNo() != 0)
return false;
3608 if (!Load.hasOneUse())
3616 bool FoundLoad =
false;
3620 const unsigned int Max = 1024;
3662 if (Chain == Load.getValue(1)) {
3668 if (
Op == Load.getValue(1)) {
3684 if (
Op.getNode() != LoadNode)
3716bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3718 SDValue StoredVal = StoreNode->getOperand(1);
3724 EVT MemVT = StoreNode->getMemoryVT();
3725 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3729 bool IsCommutable =
false;
3730 bool IsNegate =
false;
3744 IsCommutable =
true;
3748 unsigned LoadOpNo = IsNegate ? 1 : 0;
3749 LoadSDNode *LoadNode =
nullptr;
3752 LoadNode, InputChain)) {
3759 LoadNode, InputChain))
3764 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3768 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3789 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3792 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3799 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
3803 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3805 ((
Opc == X86ISD::ADD) == IsOne)
3806 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
3807 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
3809 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3820 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
3823 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
3826 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
3829 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
3832 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
3835 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
3838 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
3840 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
3846 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
3849 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
3852 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
3855 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
3858 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
3861 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
3864 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
3867 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
3874 unsigned NewOpc = SelectRegOpcode(
Opc);
3880 int64_t OperandV = OperandC->getSExtValue();
3885 if ((
Opc == X86ISD::ADD ||
Opc == X86ISD::SUB) &&
3887 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
3889 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3890 OperandV = -OperandV;
3891 Opc =
Opc == X86ISD::ADD ? X86ISD::SUB : X86ISD::ADD;
3894 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
3895 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
3896 NewOpc = SelectImmOpcode(
Opc);
3900 if (
Opc == X86ISD::ADC ||
Opc == X86ISD::SBB) {
3902 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
3906 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
3907 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3911 Segment, Operand, InputChain};
3912 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3921 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
3923 CurDAG->setNodeMemRefs(Result, MemOps);
3929 CurDAG->RemoveDeadNode(Node);
3940bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
3944 "Should be either an and-mask, or right-shift after clearing high bits.");
3947 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
3950 MVT NVT =
Node->getSimpleValueType(0);
3953 if (NVT != MVT::i32 && NVT != MVT::i64)
3961 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
3962 auto checkUses = [AllowExtraUsesByDefault](
3964 std::optional<bool> AllowExtraUses) {
3965 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
3966 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
3968 auto checkOneUse = [checkUses](
SDValue Op,
3969 std::optional<bool> AllowExtraUses =
3971 return checkUses(
Op, 1, AllowExtraUses);
3973 auto checkTwoUse = [checkUses](
SDValue Op,
3974 std::optional<bool> AllowExtraUses =
3976 return checkUses(
Op, 2, AllowExtraUses);
3979 auto peekThroughOneUseTruncation = [checkOneUse](
SDValue V) {
3981 assert(
V.getSimpleValueType() == MVT::i32 &&
3982 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
3983 "Expected i64 -> i32 truncation");
3984 V =
V.getOperand(0);
3990 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
3993 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
3999 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4004 NBits =
M0->getOperand(1);
4005 NegateNBits =
false;
4009 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](
SDValue V) {
4010 V = peekThroughOneUseTruncation(V);
4011 return CurDAG->MaskedValueIsAllOnes(
4017 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
4020 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
4023 if (!isAllOnes(
Mask->getOperand(1)))
4026 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4030 if (!isAllOnes(
M0->getOperand(0)))
4032 NBits =
M0->getOperand(1);
4033 NegateNBits =
false;
4039 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](
SDValue ShiftAmt,
4040 unsigned Bitwidth) {
4045 NBits = NBits.getOperand(0);
4051 if (!V0 || V0->getZExtValue() != Bitwidth)
4053 NBits = NBits.getOperand(1);
4054 NegateNBits =
false;
4060 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
4063 Mask = peekThroughOneUseTruncation(Mask);
4064 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
4066 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
4073 if (!checkOneUse(
M1))
4075 canonicalizeShiftAmt(
M1, Bitwidth);
4080 return !NegateNBits;
4088 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
4089 AllowExtraUsesByDefault, &NegateNBits,
4090 &
X](SDNode *
Node) ->
bool {
4102 canonicalizeShiftAmt(N1, Bitwidth);
4106 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
4107 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4113 auto matchLowBitMask = [matchPatternA, matchPatternB,
4115 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4119 X =
Node->getOperand(0);
4122 if (matchLowBitMask(Mask)) {
4126 if (!matchLowBitMask(Mask))
4129 }
else if (matchLowBitMask(
SDValue(Node, 0))) {
4130 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4131 }
else if (!matchPatternD(Node))
4136 if (NegateNBits && !Subtarget->hasBMI2())
4141 if (NBits.getSimpleValueType() != MVT::i8) {
4148 ConstantSDNode *
Imm =
nullptr;
4149 if (NBits->getOpcode() ==
ISD::AND)
4151 NBits = NBits->getOperand(0);
4156 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4159 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4161 NBits =
SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4162 MVT::i32, ImplDef, NBits, SRIdxVal),
4168 CurDAG->getNode(
ISD::AND,
DL, MVT::i32, NBits,
4169 CurDAG->getConstant(
Imm->getZExtValue(),
DL, MVT::i32));
4179 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4183 if (Subtarget->hasBMI2()) {
4185 if (NVT != MVT::i32) {
4191 SDValue Extract = CurDAG->getNode(X86ISD::BZHI,
DL, NVT,
X, NBits);
4192 ReplaceNode(Node, Extract.
getNode());
4193 SelectCode(Extract.
getNode());
4202 SDValue RealX = peekThroughOneUseTruncation(
X);
4208 MVT XVT =
X.getSimpleValueType();
4218 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4226 SDValue ShiftAmt =
X.getOperand(1);
4227 X =
X.getOperand(0);
4230 "Expected shift amount to be i8");
4234 SDValue OrigShiftAmt = ShiftAmt;
4239 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4244 if (XVT != MVT::i32) {
4250 SDValue Extract = CurDAG->getNode(X86ISD::BEXTR,
DL, XVT,
X, Control);
4258 ReplaceNode(Node, Extract.
getNode());
4259 SelectCode(Extract.
getNode());
4265MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4266 MVT NVT =
Node->getSimpleValueType(0);
4279 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4280 if (!PreferBEXTR && !Subtarget->hasBMI2())
4292 if (NVT != MVT::i32 && NVT != MVT::i64)
4298 if (!MaskCst || !ShiftCst)
4302 uint64_t
Mask = MaskCst->getZExtValue();
4306 uint64_t Shift = ShiftCst->getZExtValue();
4311 if (Shift == 8 && MaskSize == 8)
4322 if (!PreferBEXTR && MaskSize <= 32)
4326 unsigned ROpc, MOpc;
4328#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4330 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4334 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4339 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4340 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4346 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4347 if (Subtarget->hasTBM()) {
4348 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4349 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4351 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4357 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4358 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4362 MachineSDNode *NewNode;
4364 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4365 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4367 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4368 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4369 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4373 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4375 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4380 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4384 CurDAG->getMachineNode(NewOpc, dl, NVT,
SDValue(NewNode, 0), ShAmt);
4391MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4392 bool MayFoldLoad,
const SDLoc &dl,
4393 MVT VT, SDNode *Node) {
4398 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4401 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4402 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4405 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4406 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4415 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4416 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4423MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4424 bool MayFoldLoad,
const SDLoc &dl,
4425 MVT VT, SDNode *Node,
4431 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4434 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4435 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4438 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4439 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4449 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4450 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4455bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4456 EVT VT =
N->getValueType(0);
4463 unsigned Size = VT == MVT::i64 ? 64 : 32;
4466 SDValue ShiftAmt = OrigShiftAmt;
4485 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4489 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4490 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4494 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4503 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4504 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4510 Add0C->getZExtValue() != 0) {
4513 if (Add0C->getZExtValue() %
Size == 0)
4516 Add0C->getZExtValue() % 32 == 0) {
4524 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4528 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4550 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4557 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4558 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4562 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4564 if (UpdatedNode !=
N) {
4567 ReplaceNode(
N, UpdatedNode);
4574 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4582bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4583 MVT NVT =
N->getSimpleValueType(0);
4584 unsigned Opcode =
N->getOpcode();
4596 int64_t Val = Cst->getSExtValue();
4601 bool FoundAnyExtend =
false;
4605 FoundAnyExtend =
true;
4613 if (NVT != MVT::i32 && NVT != MVT::i64)
4620 uint64_t ShAmt = ShlCst->getZExtValue();
4624 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4625 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4630 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4634 ShiftedVal = (uint64_t)Val >> ShAmt;
4638 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4641 ShiftedVal = Val >> ShAmt;
4647 ShiftedVal = (uint64_t)Val >> ShAmt;
4655 if (!CanShrinkImmediate(ShiftedVal))
4665 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4671 NeededMask &= ~Cst->getAPIntValue();
4673 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4678 if (FoundAnyExtend) {
4684 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4686 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4695bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4696 SDNode *ParentB, SDNode *ParentC,
4699 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4700 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4702 auto tryFoldLoadOrBCast =
4705 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4711 L =
L.getOperand(0);
4714 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
4719 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4723 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4726 bool FoldedLoad =
false;
4727 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4728 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4730 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4735 uint8_t OldImm =
Imm;
4736 Imm = OldImm & 0xa5;
4737 if (OldImm & 0x02)
Imm |= 0x10;
4738 if (OldImm & 0x10)
Imm |= 0x02;
4739 if (OldImm & 0x08)
Imm |= 0x40;
4740 if (OldImm & 0x40)
Imm |= 0x08;
4741 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4746 uint8_t OldImm =
Imm;
4747 Imm = OldImm & 0x99;
4748 if (OldImm & 0x02)
Imm |= 0x04;
4749 if (OldImm & 0x04)
Imm |= 0x02;
4750 if (OldImm & 0x20)
Imm |= 0x40;
4751 if (OldImm & 0x40)
Imm |= 0x20;
4756 SDValue TImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
4760 MachineSDNode *MNode;
4762 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4765 if (
C.getOpcode() == X86ISD::VBROADCAST_LOAD) {
4767 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4768 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4770 bool UseD = EltSize == 32;
4772 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4774 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4776 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4782 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4784 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4786 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4792 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
4795 ReplaceUses(
C.getValue(1),
SDValue(MNode, 1));
4802 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
4804 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
4806 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
4810 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
4814 CurDAG->RemoveDeadNode(Root);
4820bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
4821 MVT NVT =
N->getSimpleValueType(0);
4824 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
4832 auto getFoldableLogicOp = [](
SDValue Op) {
4835 Op =
Op.getOperand(0);
4837 if (!
Op.hasOneUse())
4840 unsigned Opc =
Op.getOpcode();
4842 Opc == X86ISD::ANDNP)
4851 auto tryPeelOuterNotWrappingLogic = [&](SDNode *
Op) {
4854 SDValue InnerOp = getFoldableLogicOp(
Op->getOperand(0));
4861 if ((FoldableOp = getFoldableLogicOp(N1))) {
4865 if ((FoldableOp = getFoldableLogicOp(N0))) {
4873 bool PeeledOuterNot =
false;
4875 if (
SDValue InnerOp = tryPeelOuterNotWrappingLogic(
N)) {
4876 PeeledOuterNot =
true;
4882 if ((FoldableOp = getFoldableLogicOp(N1)))
4884 else if ((FoldableOp = getFoldableLogicOp(N0)))
4892 SDNode *ParentA =
N;
4893 SDNode *ParentB = FoldableOp.
getNode();
4894 SDNode *ParentC = FoldableOp.
getNode();
4898 uint8_t TernlogMagicA = 0xf0;
4899 uint8_t TernlogMagicB = 0xcc;
4900 uint8_t TernlogMagicC = 0xaa;
4905 auto PeekThroughNot = [](
SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
4909 Parent =
Op.getNode();
4910 Op =
Op.getOperand(0);
4914 PeekThroughNot(
A, ParentA, TernlogMagicA);
4915 PeekThroughNot(
B, ParentB, TernlogMagicB);
4916 PeekThroughNot(
C, ParentC, TernlogMagicC);
4921 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
4922 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
4923 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
4924 case X86ISD::ANDNP:
Imm = ~(TernlogMagicB) & TernlogMagicC;
break;
4927 switch (
N->getOpcode()) {
4931 Imm &= ~TernlogMagicA;
4933 Imm = ~(
Imm) & TernlogMagicA;
4943 return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC,
A,
B,
C, Imm);
4953bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
4956 MVT VT =
And->getSimpleValueType(0);
4957 if (VT != MVT::i32 && VT != MVT::i64)
4969 APInt MaskVal = And1C->getAPIntValue();
4971 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
4975 if (VT == MVT::i64 && MaskLZ >= 32) {
4977 MaskVal = MaskVal.
trunc(32);
4982 APInt NegMaskVal = MaskVal | HighZeros;
4991 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
4992 NegMaskVal = NegMaskVal.
zext(64);
4993 HighZeros = HighZeros.
zext(64);
4999 KnownBits Known0 = CurDAG->computeKnownBits(And0);
5011 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
5020 bool FoldedBCast,
bool Masked) {
5021#define VPTESTM_CASE(VT, SUFFIX) \
5024 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
5025 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
5028#define VPTESTM_BROADCAST_CASES(SUFFIX) \
5029default: llvm_unreachable("Unexpected VT!"); \
5030VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
5031VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
5032VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
5033VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
5034VPTESTM_CASE(v16i32, DZ##SUFFIX) \
5035VPTESTM_CASE(v8i64, QZ##SUFFIX)
5037#define VPTESTM_FULL_CASES(SUFFIX) \
5038VPTESTM_BROADCAST_CASES(SUFFIX) \
5039VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
5040VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
5041VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
5042VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
5043VPTESTM_CASE(v64i8, BZ##SUFFIX) \
5044VPTESTM_CASE(v32i16, WZ##SUFFIX)
5062#undef VPTESTM_FULL_CASES
5063#undef VPTESTM_BROADCAST_CASES
5073 if (
Reg.isVirtual())
5078 if (GetPhysReg(N1) == LoReg && GetPhysReg(N0) != LoReg)
5084bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root,
SDValue Setcc,
5086 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
5131 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P,
SDValue &
L,
5136 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
5141 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
5147 L =
L.getOperand(0);
5150 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
5154 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5157 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5161 bool CanFoldLoads = Src0 != Src1;
5163 bool FoldedLoad =
false;
5164 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5166 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5170 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5177 bool FoldedBCast = FoldedLoad && Src1.
getOpcode() == X86ISD::VBROADCAST_LOAD;
5179 bool IsMasked = InMask.
getNode() !=
nullptr;
5188 unsigned SubReg = CmpVT.
is128BitVector() ? X86::sub_xmm : X86::sub_ymm;
5192 SDValue ImplDef =
SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5194 Src0 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src0);
5197 Src1 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src1);
5202 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5203 InMask =
SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5204 dl, MaskVT, InMask, RC), 0);
5212 MachineSDNode *CNode;
5214 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5217 SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5219 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5221 SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5223 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5229 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5232 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5234 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5240 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5241 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5242 dl, ResVT,
SDValue(CNode, 0), RC);
5246 CurDAG->RemoveDeadNode(Root);
5252bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5255 MVT NVT =
N->getSimpleValueType(0);
5258 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5292 SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5293 SDValue Ternlog = CurDAG->getNode(X86ISD::VPTERNLOG, dl, NVT,
A,
B,
C, Imm);
5300void X86DAGToDAGISel::Select(SDNode *Node) {
5301 MVT NVT =
Node->getSimpleValueType(0);
5302 unsigned Opcode =
Node->getOpcode();
5305 if (
Node->isMachineOpcode()) {
5307 Node->setNodeId(-1);
5314 unsigned IntNo =
Node->getConstantOperandVal(1);
5317 case Intrinsic::x86_encodekey128:
5318 case Intrinsic::x86_encodekey256: {
5319 if (!Subtarget->hasKL())
5325 case Intrinsic::x86_encodekey128:
5326 Opcode = X86::ENCODEKEY128;
5328 case Intrinsic::x86_encodekey256:
5329 Opcode = X86::ENCODEKEY256;
5334 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5336 if (Opcode == X86::ENCODEKEY256)
5337 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5340 MachineSDNode *Res = CurDAG->getMachineNode(
5341 Opcode, dl,
Node->getVTList(),
5342 {Node->getOperand(2), Chain, Chain.getValue(1)});
5343 ReplaceNode(Node, Res);
5346 case Intrinsic::x86_tileloaddrs64_internal:
5347 case Intrinsic::x86_tileloaddrst164_internal:
5348 if (!Subtarget->hasAMXMOVRS())
5351 case Intrinsic::x86_tileloadd64_internal:
5352 case Intrinsic::x86_tileloaddt164_internal: {
5353 if (!Subtarget->hasAMXTILE())
5356 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5357 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5362 case Intrinsic::x86_tileloaddrs64_internal:
5363 Opc = X86::PTILELOADDRSV;
5365 case Intrinsic::x86_tileloaddrst164_internal:
5366 Opc = X86::PTILELOADDRST1V;
5368 case Intrinsic::x86_tileloadd64_internal:
5369 Opc = X86::PTILELOADDV;
5371 case Intrinsic::x86_tileloaddt164_internal:
5372 Opc = X86::PTILELOADDT1V;
5377 SDValue Scale = getI8Imm(1, dl);
5379 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5380 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5382 MachineSDNode *CNode;
5384 Node->getOperand(3),
5391 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5392 ReplaceNode(Node, CNode);
5399 unsigned IntNo =
Node->getConstantOperandVal(1);
5402 case Intrinsic::x86_sse3_monitor:
5403 case Intrinsic::x86_monitorx:
5404 case Intrinsic::x86_clzero: {
5405 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5410 case Intrinsic::x86_sse3_monitor:
5411 if (!Subtarget->hasSSE3())
5413 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5415 case Intrinsic::x86_monitorx:
5416 if (!Subtarget->hasMWAITX())
5418 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5420 case Intrinsic::x86_clzero:
5421 if (!Subtarget->hasCLZERO())
5423 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5428 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5429 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5433 if (IntNo == Intrinsic::x86_sse3_monitor ||
5434 IntNo == Intrinsic::x86_monitorx) {
5436 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5439 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5444 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5446 ReplaceNode(Node, CNode);
5452 case Intrinsic::x86_tilestored64_internal: {
5454 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5455 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5456 unsigned Opc = X86::PTILESTOREDV;
5459 SDValue Scale = getI8Imm(1, dl);
5461 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5462 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5464 MachineSDNode *CNode;
5466 Node->getOperand(3),
5472 Node->getOperand(6),
5474 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5475 ReplaceNode(Node, CNode);
5478 case Intrinsic::x86_tileloaddrs64:
5479 case Intrinsic::x86_tileloaddrst164:
5480 if (!Subtarget->hasAMXMOVRS())
5483 case Intrinsic::x86_tileloadd64:
5484 case Intrinsic::x86_tileloaddt164:
5485 case Intrinsic::x86_tilestored64: {
5486 if (!Subtarget->hasAMXTILE())
5489 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5490 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5494 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5495 case Intrinsic::x86_tileloaddrs64:
5496 Opc = X86::PTILELOADDRS;
5498 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5499 case Intrinsic::x86_tileloaddrst164:
5500 Opc = X86::PTILELOADDRST1;
5502 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5505 unsigned TIndex =
Node->getConstantOperandVal(2);
5508 SDValue Scale = getI8Imm(1, dl);
5510 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5511 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5513 MachineSDNode *CNode;
5514 if (
Opc == X86::PTILESTORED) {
5516 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5519 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5521 ReplaceNode(Node, CNode);
5528 case X86ISD::NT_BRIND: {
5529 if (Subtarget->isTarget64BitILP32()) {
5534 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5535 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5536 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5537 Node->getOperand(0), ZextTarget);
5538 ReplaceNode(Node, Brind.
getNode());
5539 SelectCode(ZextTarget.
getNode());
5546 ReplaceNode(Node, getGlobalBaseReg());
5553 ReplaceUses(
SDValue(Node, 0),
Node->getOperand(0));
5554 CurDAG->RemoveDeadNode(Node);
5560 if (matchBitExtract(Node))
5565 if (tryShiftAmountMod(Node))
5569 case X86ISD::VPTERNLOG: {
5570 uint8_t
Imm =
Node->getConstantOperandVal(3);
5571 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5572 Node->getOperand(1),
Node->getOperand(2), Imm))
5578 if (tryVPTERNLOG(Node))
5588 tryVPTESTM(Node, N0, N1))
5591 tryVPTESTM(Node, N1, N0))
5595 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5597 CurDAG->RemoveDeadNode(Node);
5600 if (matchBitExtract(Node))
5608 if (tryShrinkShlLogicImm(Node))
5610 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5612 if (tryVPTERNLOG(Node))
5617 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5627 if (!CurDAG->shouldOptForSize())
5631 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5641 int64_t Val = Cst->getSExtValue();
5649 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5653 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5657 unsigned ROpc, MOpc;
5766 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5767 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5769 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5770 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5776 CurDAG->RemoveDeadNode(Node);
5781 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
5790 case X86ISD::UMUL: {
5794 unsigned LoReg, ROpc, MOpc;
5799 ROpc = Opcode == X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
5800 MOpc = Opcode == X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
5819 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5820 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5823 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5831 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
5833 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5836 MachineSDNode *CNode;
5842 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5844 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
5848 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5859 VTs = CurDAG->getVTList(NVT, MVT::i32);
5861 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
5863 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
5867 ReplaceUses(
SDValue(Node, 1),
SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
5868 CurDAG->RemoveDeadNode(Node);
5878 unsigned LoReg, HiReg;
5880 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
5881 bool UseMULXHi = UseMULX &&
SDValue(Node, 0).use_empty();
5885 Opc = UseMULXHi ? X86::MULX32Hrr
5887 : IsSigned ?
X86::IMUL32r
5889 MOpc = UseMULXHi ? X86::MULX32Hrm
5891 : IsSigned ?
X86::IMUL32m
5893 LoReg = UseMULX ? X86::EDX : X86::EAX;
5897 Opc = UseMULXHi ? X86::MULX64Hrr
5899 : IsSigned ?
X86::IMUL64r
5901 MOpc = UseMULXHi ? X86::MULX64Hrm
5903 : IsSigned ?
X86::IMUL64m
5905 LoReg = UseMULX ? X86::RDX : X86::RAX;
5910 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5911 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5914 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5922 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
5924 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5929 MachineSDNode *CNode =
nullptr;
5933 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5934 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5937 }
else if (UseMULX) {
5938 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
5939 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5944 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5945 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5951 ReplaceUses(N1.
getValue(1), Chain);
5957 SDVTList VTs = CurDAG->getVTList(NVT);
5958 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5960 }
else if (UseMULX) {
5961 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
5962 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5966 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
5967 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5973 if (!
SDValue(Node, 0).use_empty()) {
5975 assert(LoReg &&
"Register for low half is not defined!");
5976 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
5980 ReplaceUses(
SDValue(Node, 0), ResLo);
5985 if (!
SDValue(Node, 1).use_empty()) {
5987 assert(HiReg &&
"Register for high half is not defined!");
5988 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
5992 ReplaceUses(
SDValue(Node, 1), ResHi);
5997 CurDAG->RemoveDeadNode(Node);
6006 unsigned ROpc, MOpc;
6011 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
6012 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
6013 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
6014 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
6019 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
6020 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
6021 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
6022 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
6026 unsigned LoReg, HiReg, ClrReg;
6027 unsigned SExtOpcode;
6031 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
6035 LoReg = X86::AX; HiReg = X86::DX;
6037 SExtOpcode = X86::CWD;
6040 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
6041 SExtOpcode = X86::CDQ;
6044 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
6045 SExtOpcode = X86::CQO;
6049 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6050 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6051 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
6054 if (NVT == MVT::i8) {
6057 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
6058 MachineSDNode *Move;
6059 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6061 unsigned Opc = (isSigned && !signBitIsZero) ? X86::MOVSX16rm8
6063 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
6065 ReplaceUses(N0.
getValue(1), Chain);
6069 unsigned Opc = (isSigned && !signBitIsZero) ? X86::MOVSX16rr8
6071 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
6072 Chain = CurDAG->getEntryNode();
6074 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX,
SDValue(Move, 0),
6079 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
6080 LoReg, N0,
SDValue()).getValue(1);
6081 if (isSigned && !signBitIsZero) {
6084 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
6087 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
6089 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
6093 SDValue(CurDAG->getMachineNode(
6094 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
6095 CurDAG->getTargetConstant(X86::sub_16bit, dl,
6103 CurDAG->getMachineNode(
6104 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, ClrNode,
6105 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
6112 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
6113 ClrNode, InGlue).getValue(1);
6120 MachineSDNode *CNode =
6121 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
6129 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
6139 if (HiReg == X86::AH && !
SDValue(Node, 1).use_empty()) {
6140 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
6141 unsigned AHExtOpcode =
6142 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6144 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6145 MVT::Glue, AHCopy, InGlue);
6150 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6152 ReplaceUses(
SDValue(Node, 1), Result);
6157 if (!
SDValue(Node, 0).use_empty()) {
6158 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6159 LoReg, NVT, InGlue);
6160 InGlue =
Result.getValue(2);
6161 ReplaceUses(
SDValue(Node, 0), Result);
6166 if (!
SDValue(Node, 1).use_empty()) {
6167 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6168 HiReg, NVT, InGlue);
6169 InGlue =
Result.getValue(2);
6170 ReplaceUses(
SDValue(Node, 1), Result);
6174 CurDAG->RemoveDeadNode(Node);
6179 case X86ISD::STRICT_FCMP:
6180 case X86ISD::STRICT_FCMPS: {
6181 bool IsStrictCmp =
Node->getOpcode() == X86ISD::STRICT_FCMP ||
6182 Node->getOpcode() == X86ISD::STRICT_FCMPS;
6183 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6184 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6190 if (Subtarget->canUseCMOV())
6193 bool IsSignaling =
Node->getOpcode() == X86ISD::STRICT_FCMPS;
6199 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6202 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6205 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6210 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6213 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6214 Chain =
SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6217 Glue =
SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6222 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6226 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6230 assert(Subtarget->canUseLAHFSAHF() &&
6231 "Target doesn't support SAHF or FCOMI?");
6232 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract,
SDValue());
6235 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6238 ReplaceUses(
SDValue(Node, 1), Chain);
6240 ReplaceUses(
SDValue(Node, 0), SAHF);
6241 CurDAG->RemoveDeadNode(Node);
6261 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6262 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6265 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6267 CurDAG->RemoveDeadNode(Node);
6287 uint64_t
Mask = MaskC->getZExtValue();
6294 onlyUsesZeroFlag(
SDValue(Node, 0))) {
6299 unsigned TestOpcode;
6307 if (LeadingZeros == 0 && SavesBytes) {
6312 ShiftAmt = TrailingZeros;
6314 TestOpcode = X86::TEST64rr;
6315 }
else if (TrailingZeros == 0 && SavesBytes) {
6320 ShiftAmt = LeadingZeros;
6322 TestOpcode = X86::TEST64rr;
6323 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6326 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6327 if (PopCount == 8) {
6329 ShiftAmt = TrailingZeros;
6330 SubRegIdx = X86::sub_8bit;
6332 TestOpcode = X86::TEST8rr;
6333 }
else if (PopCount == 16) {
6335 ShiftAmt = TrailingZeros;
6336 SubRegIdx = X86::sub_16bit;
6337 SubRegVT = MVT::i16;
6338 TestOpcode = X86::TEST16rr;
6339 }
else if (PopCount == 32) {
6341 ShiftAmt = TrailingZeros;
6342 SubRegIdx = X86::sub_32bit;
6343 SubRegVT = MVT::i32;
6344 TestOpcode = X86::TEST32rr;
6348 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6350 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6353 if (SubRegIdx != 0) {
6355 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6357 MachineSDNode *
Test =
6358 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6359 ReplaceNode(Node,
Test);
6366 unsigned ROpc, MOpc;
6374 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6375 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6378 SubRegOp = X86::sub_8bit;
6379 ROpc = X86::TEST8ri;
6380 MOpc = X86::TEST8mi;
6381 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6382 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6383 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6389 SubRegOp = X86::sub_16bit;
6390 ROpc = X86::TEST16ri;
6391 MOpc = X86::TEST16mi;
6393 ((!(Mask & 0x80000000) &&
6396 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6397 CmpVT == MVT::i32 ||
6398 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6405 SubRegOp = X86::sub_32bit;
6406 ROpc = X86::TEST32ri;
6407 MOpc = X86::TEST32mi;
6413 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6417 MachineSDNode *NewNode;
6418 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6419 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6421 if (!LoadN->isSimple()) {
6422 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6423 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6424 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6425 (MOpc == X86::TEST32mi && NumVolBits != 32))
6430 Reg.getOperand(0) };
6431 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6433 ReplaceUses(
Reg.getValue(1),
SDValue(NewNode, 1));
6435 CurDAG->setNodeMemRefs(NewNode,
6440 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6442 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg, Imm);
6445 ReplaceNode(Node, NewNode);
6451 if (!Subtarget->hasSSE42())
6454 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6455 bool NeedMask = !
SDValue(Node, 1).use_empty();
6457 bool MayFoldLoad = !NeedIndex || !NeedMask;
6459 MachineSDNode *CNode;
6462 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6464 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6465 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6468 if (NeedIndex || !NeedMask) {
6470 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6472 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6473 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6479 CurDAG->RemoveDeadNode(Node);
6483 if (!Subtarget->hasSSE42())
6487 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6488 Node->getOperand(1),
6490 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6491 Node->getOperand(3), InGlue).getValue(1);
6493 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6494 bool NeedMask = !
SDValue(Node, 1).use_empty();
6496 bool MayFoldLoad = !NeedIndex || !NeedMask;
6498 MachineSDNode *CNode;
6501 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6503 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6505 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6508 if (NeedIndex || !NeedMask) {
6510 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6512 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6513 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6518 CurDAG->RemoveDeadNode(Node);
6530 if (foldLoadStoreIntoMemOperand(Node))
6534 case X86ISD::SETCC_CARRY: {
6535 MVT VT =
Node->getSimpleValueType(0);
6537 if (Subtarget->hasSBBDepBreaking()) {
6542 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6547 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6548 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6550 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6555 Result = getSBBZero(Node);
6559 if (VT == MVT::i8 || VT == MVT::i16) {
6560 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6561 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6564 ReplaceUses(
SDValue(Node, 0), Result);
6565 CurDAG->RemoveDeadNode(Node);
6577 if (!
SDValue(Node, 0).use_empty()) {
6579 MVT VT =
Node->getSimpleValueType(0);
6580 if (VT == MVT::i8 || VT == MVT::i16) {
6581 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6582 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6584 ReplaceUses(
SDValue(Node, 0), Result);
6587 CurDAG->RemoveDeadNode(Node);
6594 SDValue IndexOp = Mgt->getIndex();
6597 MVT ValueVT =
Node->getSimpleValueType(0);
6598 MVT MaskVT =
Mask.getSimpleValueType();
6615 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6616 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6617 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6618 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6619 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6620 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6621 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6622 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6623 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6624 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6625 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6626 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6627 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6628 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6629 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6630 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6631 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6632 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6633 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6634 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6635 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6636 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6637 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6638 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6640 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6641 "Unexpected mask VT!");
6642 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6643 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6644 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6645 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6646 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6647 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6648 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6649 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6650 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6651 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6652 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6653 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6654 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6655 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6656 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6657 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6664 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6665 Base, Scale, Index, Disp, Segment))
6668 SDValue PassThru = Mgt->getPassThru();
6669 SDValue Chain = Mgt->getChain();
6671 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6673 MachineSDNode *NewNode;
6676 Index, Disp, Segment, Chain};
6677 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6680 Disp, Segment,
Mask, Chain};
6681 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6683 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6686 CurDAG->RemoveDeadNode(Node);
6692 SDValue IndexOp = Sc->getIndex();
6694 MVT ValueVT =
Value.getSimpleValueType();
6709 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6710 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6711 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6712 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6713 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6714 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6715 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6716 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6717 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6718 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6719 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6720 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6721 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6722 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6723 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6724 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6725 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6726 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6727 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6728 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6729 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6730 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6731 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6732 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6737 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6738 Base, Scale, Index, Disp, Segment))
6742 SDValue Chain = Sc->getChain();
6744 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6747 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6748 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6750 CurDAG->RemoveDeadNode(Node);
6754 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6755 auto CallId = MFI->getPreallocatedIdForCallSite(
6758 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6759 MachineSDNode *
New = CurDAG->getMachineNode(
6760 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6762 CurDAG->RemoveDeadNode(Node);
6766 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6770 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6773 Ops[0] = CallIdValue;
6776 MachineSDNode *
New = CurDAG->getMachineNode(
6777 TargetOpcode::PREALLOCATED_ARG, dl,
6778 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
6783 CurDAG->RemoveDeadNode(Node);
6790 if (!Subtarget->hasWIDEKL())
6794 switch (
Node->getOpcode()) {
6798 Opcode = X86::AESENCWIDE128KL;
6801 Opcode = X86::AESDECWIDE128KL;
6804 Opcode = X86::AESENCWIDE256KL;
6807 Opcode = X86::AESDECWIDE256KL;
6815 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
6818 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
6820 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
6822 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
6824 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
6826 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
6828 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
6830 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
6832 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
6835 MachineSDNode *Res = CurDAG->getMachineNode(
6836 Opcode, dl,
Node->getVTList(),
6837 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
6839 ReplaceNode(Node, Res);
6846 if (
Node->getNumValues() == 3)
6847 Glue =
Node->getOperand(2);
6849 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
6850 ReplaceNode(Node,
Copy.getNode());
6858bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
6860 std::vector<SDValue> &OutOps) {
6861 SDValue Op0, Op1, Op2, Op3, Op4;
6862 switch (ConstraintID) {
6865 case InlineAsm::ConstraintCode::o:
6866 case InlineAsm::ConstraintCode::v:
6867 case InlineAsm::ConstraintCode::m:
6868 case InlineAsm::ConstraintCode::X:
6869 case InlineAsm::ConstraintCode::p:
6870 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
6875 OutOps.push_back(Op0);
6876 OutOps.push_back(Op1);
6877 OutOps.push_back(Op2);
6878 OutOps.push_back(Op3);
6879 OutOps.push_back(Op4);
6885 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
6891 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")
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