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);
220 bool selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
SDValue IndexOp,
234 bool tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
244 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
247 bool tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
252 bool isProfitableToFormMaskedOp(SDNode *
N)
const;
255 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
257 std::vector<SDValue> &OutOps)
override;
259 void emitSpecialCodeForMain();
261 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
265 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
266 Base = CurDAG->getTargetFrameIndex(
267 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
268 else if (AM.Base_Reg.
getNode())
271 Base = CurDAG->getRegister(0, VT);
273 Scale = getI8Imm(AM.Scale,
DL);
275#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
277 if (AM.NegateIndex) {
303 Index = CurDAG->getRegister(0, VT);
308 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(),
312 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
313 AM.Disp, AM.SymbolFlags);
315 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
316 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
317 }
else if (AM.MCSym) {
318 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
319 assert(AM.SymbolFlags == 0 &&
"oo");
320 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
321 }
else if (AM.JT != -1) {
322 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
323 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
324 }
else if (AM.BlockAddr)
325 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
328 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
331 Segment = AM.Segment;
333 Segment = CurDAG->getRegister(0, MVT::i16);
338 bool isAMXSDNode(SDNode *
N)
const {
342 for (
unsigned Idx = 0,
E =
N->getNumValues(); Idx !=
E; ++Idx) {
343 if (
N->getValueType(Idx) == MVT::x86amx)
346 for (
unsigned Idx = 0,
E =
N->getNumOperands(); Idx !=
E; ++Idx) {
348 if (
Op.getValueType() == MVT::x86amx)
360 bool shouldAvoidImmediateInstFormsForSize(SDNode *
N)
const {
361 uint32_t UseCount = 0;
366 if (!CurDAG->shouldOptForSize())
370 for (
const SDNode *User :
N->users()) {
376 if (
User->isMachineOpcode()) {
383 User->getOperand(1).getNode() ==
N) {
394 if (
User->getNumOperands() != 2)
415 OtherOp =
User->getOperand(1);
418 RegisterSDNode *RegNode;
422 if ((RegNode->
getReg() == X86::ESP) ||
423 (RegNode->
getReg() == X86::RSP))
432 return (UseCount > 1);
436 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &
DL) {
437 return CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
441 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &
DL) {
442 return CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
446 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &
DL) {
447 return CurDAG->getTargetConstant(Imm,
DL, MVT::i64);
450 SDValue getExtractVEXTRACTImmediate(SDNode *
N,
unsigned VecWidth,
452 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
453 uint64_t
Index =
N->getConstantOperandVal(1);
454 MVT VecVT =
N->getOperand(0).getSimpleValueType();
458 SDValue getInsertVINSERTImmediate(SDNode *
N,
unsigned VecWidth,
460 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
461 uint64_t
Index =
N->getConstantOperandVal(2);
462 MVT VecVT =
N->getSimpleValueType(0);
466 SDValue getPermuteVINSERTCommutedImmediate(SDNode *
N,
unsigned VecWidth,
468 assert(VecWidth == 128 &&
"Unexpected vector width");
469 uint64_t
Index =
N->getConstantOperandVal(2);
470 MVT VecVT =
N->getSimpleValueType(0);
472 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
475 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
480 MVT VT =
N->getSimpleValueType(0);
483 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
485 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
486 if (VT == MVT::i64) {
488 CurDAG->getMachineNode(
489 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, Zero,
490 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
495 unsigned Opcode =
N->getOpcode();
497 "Unexpected opcode for SBB materialization");
498 unsigned FlagOpIndex = Opcode ==
X86ISD::SBB ? 2 : 1;
500 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
501 N->getOperand(FlagOpIndex),
SDValue());
505 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
506 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
507 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
509 CurDAG->getMachineNode(
Opc, dl, VTs,
510 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
516 bool isUnneededShiftMask(SDNode *
N,
unsigned Width)
const {
518 const APInt &Val =
N->getConstantOperandAPInt(1);
523 APInt
Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
524 return Mask.countr_one() >= Width;
530 SDNode *getGlobalBaseReg();
534 const X86TargetMachine &getTargetMachine()
const {
535 return static_cast<const X86TargetMachine &
>(TM);
540 const X86InstrInfo *getInstrInfo()
const {
541 return Subtarget->getInstrInfo();
550 bool ComplexPatternFuncMutatesDAG()
const override {
554 bool isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const;
557 bool useNonTemporalLoad(LoadSDNode *
N)
const {
558 if (!
N->isNonTemporal())
561 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
563 if (
N->getAlign().value() < StoreSize)
572 return Subtarget->hasSSE41();
574 return Subtarget->hasAVX2();
576 return Subtarget->hasAVX512();
580 bool foldLoadStoreIntoMemOperand(SDNode *Node);
581 MachineSDNode *matchBEXTRFromAndImm(SDNode *Node);
582 bool matchBitExtract(SDNode *Node);
583 bool shrinkAndImmediate(SDNode *
N);
584 bool isMaskZeroExtended(SDNode *
N)
const;
585 bool tryShiftAmountMod(SDNode *
N);
586 bool tryShrinkShlLogicImm(SDNode *
N);
587 bool tryVPTERNLOG(SDNode *
N);
588 bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentB,
592 bool tryMatchBitSelect(SDNode *
N);
594 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
595 const SDLoc &dl, MVT VT, SDNode *Node);
596 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
597 const SDLoc &dl, MVT VT, SDNode *Node,
600 bool tryOptimizeRem8Extend(SDNode *
N);
602 bool onlyUsesZeroFlag(
SDValue Flags)
const;
603 bool hasNoSignFlagUses(
SDValue Flags)
const;
604 bool hasNoCarryFlagUses(
SDValue Flags)
const;
605 bool checkTCRetEnoughRegs(SDNode *
N)
const;
611 explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm,
613 : SelectionDAGISelLegacy(
614 ID, std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
618char X86DAGToDAGISelLegacy::ID = 0;
625 unsigned Opcode =
N->getOpcode();
632 EVT OpVT =
N->getOperand(0).getValueType();
636 OpVT =
N->getOperand(1).getValueType();
638 return Subtarget->hasVLX();
652bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
664X86DAGToDAGISel::IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const {
665 if (OptLevel == CodeGenOptLevel::None)
680 switch (
U->getOpcode()) {
707 if (
Imm->getAPIntValue().isSignedIntN(8))
716 Imm->getAPIntValue().getBitWidth() == 64 &&
717 Imm->getAPIntValue().isIntN(32))
724 (
Imm->getAPIntValue() == UINT8_MAX ||
725 Imm->getAPIntValue() == UINT16_MAX ||
726 Imm->getAPIntValue() == UINT32_MAX))
732 (-
Imm->getAPIntValue()).isSignedIntN(8))
736 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
737 hasNoCarryFlagUses(
SDValue(U, 1)))
762 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
766 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
775 if (
C &&
C->getSExtValue() == -2)
781 if (
C &&
C->getSExtValue() == -2)
816bool X86DAGToDAGISel::isProfitableToFormMaskedOp(SDNode *
N)
const {
819 "Unexpected opcode!");
824 return N->getOperand(1).hasOneUse();
833 if (Chain.
getNode() == Load.getNode())
834 Ops.push_back(Load.getOperand(0));
837 "Unexpected chain operand");
840 Ops.push_back(Load.getOperand(0));
846 Ops.push_back(NewChain);
851 Load.getOperand(1), Load.getOperand(2));
869 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
881 if (!Callee.getValue(1).hasOneUse())
912 Callee.getValue(1).hasOneUse())
929 if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
932 uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
933 0x65, 0x66, 0x67, 0xf0, 0xf2};
936 uint8_t Byte = (Imm >> i) & 0xFF;
948 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
951void X86DAGToDAGISel::PreprocessISelDAG() {
952 bool MadeChange =
false;
954 E = CurDAG->allnodes_end();
I !=
E; ) {
973 MVT VT =
N->getSimpleValueType(0);
975 int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
980 "cf-protection-branch");
983 SDValue Complement = CurDAG->getConstant(~Imm, dl, VT,
false,
true);
984 Complement = CurDAG->getNOT(dl, Complement, VT);
986 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Complement);
996 if (
N->getOpcode() ==
X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
998 N->getOperand(0),
N->getOperand(1));
1000 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1024 auto mayPreventLoadFold = [&]() {
1026 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1027 !
N->getOperand(1).hasOneUse();
1030 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1038 MVT VT =
N->getSimpleValueType(0);
1046 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1048 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1055 switch (
N->getOpcode()) {
1057 MVT VT =
N->getSimpleValueType(0);
1059 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1066 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1069 CurDAG->getIntPtrConstant(Index, dl));
1072 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1081 MVT VT =
N->getSimpleValueType(0);
1083 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1087 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1088 SDValue Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1089 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1091 MemNode->getMemOperand());
1094 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1097 CurDAG->getIntPtrConstant(Index, dl));
1101 CurDAG->ReplaceAllUsesWith(
N, To);
1113 MVT VT =
N->getSimpleValueType(0);
1119 SDNode *MaxLd =
nullptr;
1120 SDValue Ptr = Ld->getBasePtr();
1121 SDValue Chain = Ld->getChain();
1122 for (SDNode *User : Ptr->
users()) {
1124 MVT UserVT =
User->getSimpleValueType(0);
1126 UserLd->getBasePtr() == Ptr && UserLd->getChain() == Chain &&
1127 !
User->hasAnyUseOfValue(1) &&
1141 CurDAG->getIntPtrConstant(0, dl));
1142 SDValue Res = CurDAG->getBitcast(VT, Extract);
1146 CurDAG->ReplaceAllUsesWith(
N, To);
1155 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1156 if (EleVT == MVT::i1)
1159 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1160 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1161 "We can't replace VSELECT with BLENDV in vXi16!");
1163 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1166 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1167 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1170 N->getOperand(0),
N->getOperand(1),
1174 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1187 if (!
N->getSimpleValueType(0).isVector())
1191 switch (
N->getOpcode()) {
1201 if (
N->isStrictFPOpcode())
1203 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1204 {
N->getOperand(0),
N->getOperand(1)});
1207 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1210 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1220 if (!
N->getValueType(0).isVector())
1224 switch (
N->getOpcode()) {
1230 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1231 N->getOperand(0),
N->getOperand(1));
1233 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1242 if (!
N->getValueType(0).isVector())
1246 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1248 "Unexpected opcode for mask vector!");
1256 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1259 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1279 switch (
N->getOpcode()) {
1295 bool IsStrict =
N->isStrictFPOpcode();
1299 {
N->getValueType(0), MVT::Other},
1300 {
N->getOperand(0),
N->getOperand(1),
1301 CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
1305 CurDAG->getTargetConstant(Imm, dl, MVT::i32));
1307 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1318 MVT VT =
N->getSimpleValueType(0);
1319 if (VT.
isVector() || VT == MVT::f128)
1322 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1323 : VT == MVT::f32 ? MVT::v4f32
1333 if (Subtarget->hasSSE2()) {
1334 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1338 switch (
N->getOpcode()) {
1345 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1348 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1351 CurDAG->getIntPtrConstant(0, dl));
1353 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1360 if (OptLevel != CodeGenOptLevel::None &&
1363 !Subtarget->useIndirectThunkCalls() &&
1364 ((
N->getOpcode() ==
X86ISD::CALL && !Subtarget->slowTwoMemOps()) ||
1366 (Subtarget->is64Bit() ||
1367 !getTargetMachine().isPositionIndependent())))) {
1408 switch (
N->getOpcode()) {
1413 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1414 MVT DstVT =
N->getSimpleValueType(0);
1422 const X86TargetLowering *X86Lowering =
1423 static_cast<const X86TargetLowering *
>(TLI);
1426 if (SrcIsSSE && DstIsSSE)
1429 if (!SrcIsSSE && !DstIsSSE) {
1434 if (
N->getConstantOperandVal(1))
1442 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1444 MachinePointerInfo MPI =
1451 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1453 MemTmp, MPI, MemVT);
1460 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1469 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1470 MVT DstVT =
N->getSimpleValueType(0);
1478 const X86TargetLowering *X86Lowering =
1479 static_cast<const X86TargetLowering *
>(TLI);
1482 if (SrcIsSSE && DstIsSSE)
1485 if (!SrcIsSSE && !DstIsSSE) {
1490 if (
N->getConstantOperandVal(2))
1498 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1500 MachinePointerInfo MPI =
1509 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1510 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1514 if (
N->getFlags().hasNoFPExcept()) {
1516 Flags.setNoFPExcept(
true);
1517 Store->setFlags(Flags);
1520 assert(SrcVT == MemVT &&
"Unexpected VT!");
1521 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1526 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1528 Result = CurDAG->getMemIntrinsicNode(
1531 if (
N->getFlags().hasNoFPExcept()) {
1533 Flags.setNoFPExcept(
true);
1537 assert(DstVT == MemVT &&
"Unexpected VT!");
1538 Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
1546 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1560 CurDAG->RemoveDeadNodes();
1564bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1565 unsigned Opc =
N->getMachineOpcode();
1566 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1567 Opc != X86::MOVSX64rr8)
1579 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1580 : X86::MOVSX32rr8_NOREX;
1585 if (
Opc == X86::MOVSX64rr8) {
1588 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1590 ReplaceUses(
N, Extend);
1599void X86DAGToDAGISel::PostprocessISelDAG() {
1601 if (TM.getOptLevel() == CodeGenOptLevel::None)
1606 bool MadeChange =
false;
1607 while (Position != CurDAG->allnodes_begin()) {
1608 SDNode *
N = &*--Position;
1610 if (
N->use_empty() || !
N->isMachineOpcode())
1613 if (tryOptimizeRem8Extend(
N)) {
1618 unsigned Opc =
N->getMachineOpcode();
1629 case X86::CTEST16rr:
1630 case X86::CTEST32rr:
1631 case X86::CTEST64rr: {
1637#define CASE_ND(OP) \
1640 switch (
And.getMachineOpcode()) {
1647 if (
And->hasAnyUseOfValue(1))
1650 Ops[0] =
And.getOperand(0);
1651 Ops[1] =
And.getOperand(1);
1652 MachineSDNode *
Test =
1653 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1654 ReplaceUses(
N,
Test);
1662 if (
And->hasAnyUseOfValue(1))
1665 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1666#define FROM_TO(A, B) \
1667 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1669 switch (
And.getMachineOpcode()) {
1679 And.getOperand(3),
And.getOperand(4),
1680 And.getOperand(5),
And.getOperand(0)};
1683 Ops.push_back(
N->getOperand(2));
1684 Ops.push_back(
N->getOperand(3));
1687 Ops.push_back(
And.getOperand(6));
1690 Ops.push_back(
N->getOperand(4));
1692 MachineSDNode *
Test = CurDAG->getMachineNode(
1693 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1694 CurDAG->setNodeMemRefs(
1707 case X86::KORTESTBkk:
1708 case X86::KORTESTWkk:
1709 case X86::KORTESTDkk:
1710 case X86::KORTESTQkk: {
1712 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1727#define FROM_TO(A, B) \
1739 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1742 MachineSDNode *KTest = CurDAG->getMachineNode(
1744 ReplaceUses(
N, KTest);
1749 case TargetOpcode::SUBREG_TO_REG: {
1750 unsigned SubRegIdx =
N->getConstantOperandVal(1);
1751 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1768 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1769 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1770 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1771 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1772 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1773 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1774 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1775 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1780 if (!
In.isMachineOpcode() ||
1781 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1786 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1794 CurDAG->UpdateNodeOperands(
N, In,
N->getOperand(1));
1801 CurDAG->RemoveDeadNodes();
1806void X86DAGToDAGISel::emitSpecialCodeForMain() {
1807 if (Subtarget->isTargetCygMing()) {
1808 TargetLowering::ArgListTy
Args;
1809 auto &
DL = CurDAG->getDataLayout();
1811 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1812 CLI.setChain(CurDAG->getRoot())
1813 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1814 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1816 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1818 CurDAG->setRoot(
Result.second);
1822void X86DAGToDAGISel::emitFunctionEntryCode() {
1825 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1826 emitSpecialCodeForMain();
1839bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t
Offset,
1840 X86ISelAddressMode &AM) {
1845 int64_t Val = AM.Disp +
Offset;
1848 if (Val != 0 && (AM.ES || AM.MCSym))
1852 if (Subtarget->is64Bit()) {
1855 AM.hasSymbolicDisplacement()))
1859 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1878 if (Subtarget->isTarget64BitILP32() &&
1880 !AM.hasBaseOrIndexReg())
1882 }
else if (Subtarget->is16Bit()) {
1885 if (Val < -(int64_t)UINT16_MAX || Val > (int64_t)UINT16_MAX)
1895bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1896 bool AllowSegmentRegForX32) {
1909 !IndirectTlsSegRefs &&
1910 (Subtarget->isTargetGlibc() || Subtarget->isTargetMusl() ||
1911 Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())) {
1912 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1914 switch (
N->getPointerInfo().getAddrSpace()) {
1916 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1919 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1932bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1935 if (AM.hasSymbolicDisplacement())
1938 bool IsRIPRelTLS =
false;
1956 if (IsRIPRel && AM.hasBaseOrIndexReg())
1960 X86ISelAddressMode Backup = AM;
1965 AM.GV =
G->getGlobal();
1966 AM.SymbolFlags =
G->getTargetFlags();
1969 AM.CP = CP->getConstVal();
1970 AM.Alignment = CP->getAlign();
1971 AM.SymbolFlags = CP->getTargetFlags();
1972 Offset = CP->getOffset();
1974 AM.ES = S->getSymbol();
1975 AM.SymbolFlags = S->getTargetFlags();
1977 AM.MCSym = S->getMCSymbol();
1979 AM.JT = J->getIndex();
1980 AM.SymbolFlags = J->getTargetFlags();
1982 AM.BlockAddr = BA->getBlockAddress();
1983 AM.SymbolFlags = BA->getTargetFlags();
1984 Offset = BA->getOffset();
1989 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1990 TM.isLargeGlobalValue(AM.GV)) {
1995 if (foldOffsetIntoAddress(
Offset, AM)) {
2001 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
2009bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
2010 if (matchAddressRecursively(
N, AM, 0))
2017 if (Subtarget->isTarget64BitILP32() &&
2018 AM.BaseType == X86ISelAddressMode::RegBase &&
2019 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
2020 SDValue Save_Base_Reg = AM.Base_Reg;
2023 if (matchLoadInAddress(LoadN, AM,
true))
2024 AM.Base_Reg = Save_Base_Reg;
2030 if (AM.Scale == 2 &&
2031 AM.BaseType == X86ISelAddressMode::RegBase &&
2032 AM.Base_Reg.
getNode() ==
nullptr) {
2033 AM.Base_Reg = AM.IndexReg;
2040 (!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2041 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2042 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2054 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2060bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
2064 HandleSDNode Handle(
N);
2066 X86ISelAddressMode Backup = AM;
2067 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
2068 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
2073 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
2075 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2082 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2085 N = Handle.getValue();
2091 N = Handle.getValue();
2101 if (
N->getNodeId() == -1 ||
2121 X86ISelAddressMode &AM) {
2128 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2129 Mask != (0xffu << ScaleLog))
2132 MVT XVT =
X.getSimpleValueType();
2133 MVT VT =
N.getSimpleValueType();
2158 AM.Scale = (1 << ScaleLog);
2166 X86ISelAddressMode &AM) {
2177 bool FoundAnyExtend =
false;
2181 FoundAnyExtend =
true;
2199 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2202 MVT VT =
N.getSimpleValueType();
2204 if (FoundAnyExtend) {
2225 AM.Scale = 1 << ShiftAmt;
2226 AM.IndexReg = NewAnd;
2260 X86ISelAddressMode &AM) {
2266 unsigned MaskIdx, MaskLen;
2269 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2275 unsigned AMShiftAmt = MaskIdx;
2279 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2283 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2284 if (MaskLZ < ScaleDown)
2286 MaskLZ -= ScaleDown;
2294 bool ReplacingAnyExtend =
false;
2296 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2297 X.getOperand(0).getSimpleValueType().getSizeInBits();
2300 X =
X.getOperand(0);
2301 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2302 ReplacingAnyExtend =
true;
2304 APInt MaskedHighBits =
2311 MVT VT =
N.getSimpleValueType();
2312 if (ReplacingAnyExtend) {
2313 assert(
X.getValueType() != VT);
2320 MVT XVT =
X.getSimpleValueType();
2341 AM.Scale = 1 << AMShiftAmt;
2342 AM.IndexReg = NewExt;
2352 X86ISelAddressMode &AM,
2360 if (!Subtarget.hasTBM() &&
2361 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2365 unsigned MaskIdx, MaskLen;
2373 unsigned AMShiftAmt = MaskIdx;
2377 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2379 MVT XVT =
X.getSimpleValueType();
2380 MVT VT =
N.getSimpleValueType();
2405 AM.Scale = 1 << AMShiftAmt;
2406 AM.IndexReg = NewExt;
2413 X86ISelAddressMode &AM,
2415 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2416 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2417 "Illegal index scale");
2423 EVT VT =
N.getValueType();
2424 unsigned Opc =
N.getOpcode();
2427 if (CurDAG->isBaseWithConstantOffset(
N)) {
2429 uint64_t
Offset = (uint64_t)AddVal->getSExtValue() * AM.Scale;
2430 if (!foldOffsetIntoAddress(
Offset, AM))
2431 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2435 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2436 if (AM.Scale <= 4) {
2438 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2444 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2445 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2446 if ((AM.Scale * ScaleAmt) <= 8) {
2447 AM.Scale *= ScaleAmt;
2448 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2456 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2458 if (CurDAG->isBaseWithConstantOffset(Src)) {
2459 SDValue AddSrc = Src.getOperand(0);
2461 int64_t
Offset = AddVal->getSExtValue();
2462 if (!foldOffsetIntoAddress((uint64_t)
Offset * AM.Scale, AM)) {
2470 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2471 CurDAG->RemoveDeadNode(
N.getNode());
2483 unsigned SrcOpc = Src.getOpcode();
2484 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2485 CurDAG->isADDLike(Src,
true)) &&
2487 if (CurDAG->isBaseWithConstantOffset(Src)) {
2488 SDValue AddSrc = Src.getOperand(0);
2489 uint64_t
Offset = Src.getConstantOperandVal(1);
2490 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2500 uint64_t ScaleAmt = 1ULL << ShAmt;
2501 if ((AM.Scale * ScaleAmt) <= 8 &&
2503 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2504 AM.Scale *= ScaleAmt;
2505 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2516 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2520 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2521 CurDAG->RemoveDeadNode(
N.getNode());
2522 return Res ? Res : ExtSrc;
2532bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2535 dbgs() <<
"MatchAddress: ";
2540 return matchAddressBase(
N, AM);
2545 if (AM.isRIPRelative()) {
2549 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2553 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2558 switch (
N.getOpcode()) {
2561 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2564 AM.MCSym = ESNode->getMCSymbol();
2571 if (!foldOffsetIntoAddress(Val, AM))
2578 if (!matchWrapper(
N, AM))
2588 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2589 AM.Base_Reg.
getNode() ==
nullptr &&
2591 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2598 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2602 unsigned Val = CN->getZExtValue();
2607 if (Val == 1 || Val == 2 || Val == 3) {
2609 AM.Scale = 1 << Val;
2610 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2618 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2622 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2623 "Unexpected value size!");
2635 uint64_t
Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2647 if (
N.getResNo() != 0)
break;
2652 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2653 AM.Base_Reg.
getNode() ==
nullptr &&
2654 AM.IndexReg.
getNode() ==
nullptr) {
2656 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2657 CN->getZExtValue() == 9) {
2658 AM.Scale = unsigned(CN->getZExtValue())-1;
2670 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2671 if (foldOffsetIntoAddress(Disp, AM))
2672 Reg =
N.getOperand(0);
2674 Reg =
N.getOperand(0);
2677 AM.IndexReg = AM.Base_Reg =
Reg;
2693 HandleSDNode Handle(
N);
2696 X86ISelAddressMode Backup = AM;
2697 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2698 N = Handle.getValue();
2702 N = Handle.getValue();
2704 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2719 RHS.getOperand(0).getValueType() == MVT::i32))
2723 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2725 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2729 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2730 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2743 AM.NegateIndex =
true;
2751 if (!CurDAG->isADDLike(
N))
2755 if (!matchAdd(
N, AM,
Depth))
2764 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2768 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2769 "Unexpected value size!");
2774 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2778 uint64_t
Mask =
N.getConstantOperandVal(1);
2803 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2811 if (
SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2813 AM.IndexReg =
Index;
2819 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2821 Mask = MaskC->getAPIntValue();
2822 Src = Src.getOperand(0);
2825 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2827 SDValue ShlSrc = Src.getOperand(0);
2828 SDValue ShlAmt = Src.getOperand(1);
2832 unsigned ShAmtV = ShAmtC->getZExtValue();
2840 if (!Src->getFlags().hasNoUnsignedWrap() &&
2841 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2849 MVT VT =
N.getSimpleValueType();
2853 if (!
Mask.isAllOnes()) {
2854 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2856 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2863 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2864 CurDAG->RemoveDeadNode(
N.getNode());
2867 AM.Scale = 1 << ShAmtV;
2871 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2875 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2878 Src.getOperand(0), AM))
2883 Src.getOperand(0), AM))
2888 Src.getOperand(0), AM, *Subtarget))
2896 return matchAddressBase(
N, AM);
2901bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2903 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
2916 AM.BaseType = X86ISelAddressMode::RegBase;
2921bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2922 X86ISelAddressMode &AM,
2925 dbgs() <<
"MatchVectorAddress: ";
2930 return matchAddressBase(
N, AM);
2933 switch (
N.getOpcode()) {
2936 if (!foldOffsetIntoAddress(Val, AM))
2941 if (!matchWrapper(
N, AM))
2947 HandleSDNode Handle(
N);
2949 X86ISelAddressMode Backup = AM;
2950 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2951 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2957 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2959 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2964 N = Handle.getValue();
2969 return matchAddressBase(
N, AM);
2975bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2976 return matchVectorAddressRecursively(
N, AM, 0);
2979bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
2984 X86ISelAddressMode AM;
2990 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2992 AM.IndexReg = IndexOp;
2996 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
2998 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3000 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3003 MVT VT =
BasePtr.getSimpleValueType();
3006 if (matchVectorAddress(BasePtr, AM))
3009 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3023 X86ISelAddressMode AM;
3035 unsigned AddrSpace =
3038 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3040 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3042 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3047 MVT VT =
N.getSimpleValueType();
3049 if (matchAddress(
N, AM))
3052 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3068 N =
N.getOperand(0);
3085 return CR->getUnsignedMax().ult(1ull << 32);
3087 return !TM.isLargeGlobalValue(GV);
3096 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3109 if (RN &&
RN->getReg() == 0)
3110 Base = CurDAG->getRegister(0, MVT::i64);
3120 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3122 if (RN &&
RN->getReg() == 0)
3123 Index = CurDAG->getRegister(0, MVT::i64);
3126 "Expect to be extending 8/16/32-bit registers for use in LEA");
3129 Index = CurDAG->getTargetInsertSubreg(
SubReg,
DL, MVT::i64, ImplDef, Index);
3137bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3141 X86ISelAddressMode AM;
3145 MVT VT =
N.getSimpleValueType();
3150 SDValue T = CurDAG->getRegister(0, MVT::i32);
3152 if (matchAddress(
N, AM))
3157 unsigned Complexity = 0;
3158 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3160 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3176 if (AM.hasSymbolicDisplacement()) {
3178 if (Subtarget->is64Bit())
3188 auto isMathWithFlags = [](
SDValue V) {
3189 switch (
V.getOpcode()) {
3203 return !
SDValue(
V.getNode(), 1).use_empty();
3210 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3218 if (Complexity <= 2)
3221 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3232 X86ISelAddressMode AM;
3234 AM.GV = GA->getGlobal();
3235 AM.Disp += GA->getOffset();
3236 AM.SymbolFlags = GA->getTargetFlags();
3239 AM.ES = SA->getSymbol();
3240 AM.SymbolFlags = SA->getTargetFlags();
3243 if (Subtarget->is32Bit()) {
3245 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3248 MVT VT =
N.getSimpleValueType();
3249 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3257 EVT VT =
N.getValueType();
3258 bool WasTruncated =
false;
3260 WasTruncated =
true;
3261 N =
N.getOperand(0);
3270 unsigned Opc =
N.getOperand(0)->getOpcode();
3272 Op =
N.getOperand(0);
3275 return !WasTruncated;
3280 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3281 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3285 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3286 GA->getOffset(), GA->getTargetFlags());
3290bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
3294 assert(Root &&
P &&
"Unknown root/parent nodes");
3296 !IsProfitableToFold(
N,
P, Root) ||
3297 !IsLegalToFold(
N,
P, Root, OptLevel))
3300 return selectAddr(
N.getNode(),
3301 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3304bool X86DAGToDAGISel::tryFoldBroadcast(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);
3321SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3324 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3327bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3329 N =
N->getOperand(0).getNode();
3337 auto *GV = GA->getGlobal();
3340 return CR->getSignedMin().sge(-1ull << Width) &&
3341 CR->getSignedMax().slt(1ull << Width);
3347 !TM.isLargeGlobalValue(GV);
3351 assert(
N->isMachineOpcode() &&
"Unexpected node");
3352 unsigned Opc =
N->getMachineOpcode();
3353 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3358 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3363bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3365 for (SDUse &Use :
Flags->uses()) {
3367 if (
Use.getResNo() !=
Flags.getResNo())
3375 for (SDUse &FlagUse :
User->uses()) {
3377 if (FlagUse.getResNo() != 1)
3380 if (!FlagUse.getUser()->isMachineOpcode())
3400bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3402 for (SDUse &Use :
Flags->uses()) {
3404 if (
Use.getResNo() !=
Flags.getResNo())
3412 for (SDUse &FlagUse :
User->uses()) {
3414 if (FlagUse.getResNo() != 1)
3417 if (!FlagUse.getUser()->isMachineOpcode())
3457 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3459 for (SDUse &Use :
Flags->uses()) {
3461 if (
Use.getResNo() !=
Flags.getResNo())
3465 unsigned UserOpc =
User->getOpcode();
3472 for (SDUse &FlagUse :
User->uses()) {
3474 if (FlagUse.getResNo() != 1)
3477 if (!FlagUse.getUser()->isMachineOpcode())
3510bool X86DAGToDAGISel::checkTCRetEnoughRegs(SDNode *
N)
const {
3513 const X86RegisterInfo *RI = Subtarget->getRegisterInfo();
3517 if (Subtarget->is64Bit()) {
3518 const TargetRegisterClass *TCGPRs =
3520 ? &X86::GR64_TCW64RegClass
3521 : &X86::GR64_TCRegClass;
3527 const TargetRegisterClass *TCGPRs =
3529 ? &X86::GR32RegClass
3530 : &X86::GR32_TCRegClass;
3537 unsigned LoadGPRs = 2;
3542 if (Subtarget->is32Bit()) {
3550 assert(!getTargetMachine().isPositionIndependent());
3557 for (
unsigned I = 3,
E =
N->getNumOperands();
I !=
E; ++
I) {
3559 if (!RI->isGeneralPurposeRegister(*MF,
RN->getReg()))
3561 if (++
ArgGPRs + LoadGPRs > AvailGPRs)
3577 if (StoredVal.
getResNo() != 0)
return false;
3594 if (!Load.hasOneUse())
3602 bool FoundLoad =
false;
3606 const unsigned int Max = 1024;
3648 if (Chain == Load.getValue(1)) {
3654 if (
Op == Load.getValue(1)) {
3670 if (
Op.getNode() != LoadNode)
3702bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3704 SDValue StoredVal = StoreNode->getOperand(1);
3710 EVT MemVT = StoreNode->getMemoryVT();
3711 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3715 bool IsCommutable =
false;
3716 bool IsNegate =
false;
3730 IsCommutable =
true;
3734 unsigned LoadOpNo = IsNegate ? 1 : 0;
3735 LoadSDNode *LoadNode =
nullptr;
3738 LoadNode, InputChain)) {
3745 LoadNode, InputChain))
3750 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3754 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3775 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3778 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3785 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
3789 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3792 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
3793 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
3795 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3806 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
3809 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
3812 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
3815 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
3818 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
3821 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
3824 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
3826 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
3832 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
3835 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
3838 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
3841 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
3844 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
3847 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
3850 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
3853 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
3860 unsigned NewOpc = SelectRegOpcode(
Opc);
3866 int64_t OperandV = OperandC->getSExtValue();
3873 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
3875 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3876 OperandV = -OperandV;
3880 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
3881 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
3882 NewOpc = SelectImmOpcode(
Opc);
3888 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
3892 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
3893 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3897 Segment, Operand, InputChain};
3898 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3907 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
3909 CurDAG->setNodeMemRefs(Result, MemOps);
3915 CurDAG->RemoveDeadNode(Node);
3926bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
3930 "Should be either an and-mask, or right-shift after clearing high bits.");
3933 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
3936 MVT NVT =
Node->getSimpleValueType(0);
3939 if (NVT != MVT::i32 && NVT != MVT::i64)
3947 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
3948 auto checkUses = [AllowExtraUsesByDefault](
3950 std::optional<bool> AllowExtraUses) {
3951 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
3952 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
3954 auto checkOneUse = [checkUses](
SDValue Op,
3955 std::optional<bool> AllowExtraUses =
3957 return checkUses(
Op, 1, AllowExtraUses);
3959 auto checkTwoUse = [checkUses](
SDValue Op,
3960 std::optional<bool> AllowExtraUses =
3962 return checkUses(
Op, 2, AllowExtraUses);
3965 auto peekThroughOneUseTruncation = [checkOneUse](
SDValue V) {
3967 assert(
V.getSimpleValueType() == MVT::i32 &&
3968 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
3969 "Expected i64 -> i32 truncation");
3970 V =
V.getOperand(0);
3976 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
3979 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
3985 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3990 NBits =
M0->getOperand(1);
3991 NegateNBits =
false;
3995 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](
SDValue V) {
3996 V = peekThroughOneUseTruncation(V);
3997 return CurDAG->MaskedValueIsAllOnes(
4003 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
4006 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
4009 if (!isAllOnes(
Mask->getOperand(1)))
4012 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4016 if (!isAllOnes(
M0->getOperand(0)))
4018 NBits =
M0->getOperand(1);
4019 NegateNBits =
false;
4025 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](
SDValue ShiftAmt,
4026 unsigned Bitwidth) {
4031 NBits = NBits.getOperand(0);
4037 if (!V0 || V0->getZExtValue() != Bitwidth)
4039 NBits = NBits.getOperand(1);
4040 NegateNBits =
false;
4046 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
4049 Mask = peekThroughOneUseTruncation(Mask);
4050 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
4052 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
4059 if (!checkOneUse(
M1))
4061 canonicalizeShiftAmt(
M1, Bitwidth);
4066 return !NegateNBits;
4074 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
4075 AllowExtraUsesByDefault, &NegateNBits,
4076 &
X](SDNode *
Node) ->
bool {
4088 canonicalizeShiftAmt(N1, Bitwidth);
4092 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
4093 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4099 auto matchLowBitMask = [matchPatternA, matchPatternB,
4101 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4105 X =
Node->getOperand(0);
4108 if (matchLowBitMask(Mask)) {
4112 if (!matchLowBitMask(Mask))
4115 }
else if (matchLowBitMask(
SDValue(Node, 0))) {
4116 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4117 }
else if (!matchPatternD(Node))
4122 if (NegateNBits && !Subtarget->hasBMI2())
4127 if (NBits.getSimpleValueType() != MVT::i8) {
4134 ConstantSDNode *
Imm =
nullptr;
4135 if (NBits->getOpcode() ==
ISD::AND)
4137 NBits = NBits->getOperand(0);
4142 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4145 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4147 NBits =
SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4148 MVT::i32, ImplDef, NBits, SRIdxVal),
4154 CurDAG->getNode(
ISD::AND,
DL, MVT::i32, NBits,
4155 CurDAG->getConstant(
Imm->getZExtValue(),
DL, MVT::i32));
4165 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4169 if (Subtarget->hasBMI2()) {
4171 if (NVT != MVT::i32) {
4178 ReplaceNode(Node, Extract.
getNode());
4179 SelectCode(Extract.
getNode());
4188 SDValue RealX = peekThroughOneUseTruncation(
X);
4194 MVT XVT =
X.getSimpleValueType();
4204 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4212 SDValue ShiftAmt =
X.getOperand(1);
4213 X =
X.getOperand(0);
4216 "Expected shift amount to be i8");
4220 SDValue OrigShiftAmt = ShiftAmt;
4225 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4230 if (XVT != MVT::i32) {
4244 ReplaceNode(Node, Extract.
getNode());
4245 SelectCode(Extract.
getNode());
4251MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4252 MVT NVT =
Node->getSimpleValueType(0);
4265 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4266 if (!PreferBEXTR && !Subtarget->hasBMI2())
4278 if (NVT != MVT::i32 && NVT != MVT::i64)
4284 if (!MaskCst || !ShiftCst)
4288 uint64_t
Mask = MaskCst->getZExtValue();
4292 uint64_t Shift = ShiftCst->getZExtValue();
4297 if (Shift == 8 && MaskSize == 8)
4308 if (!PreferBEXTR && MaskSize <= 32)
4312 unsigned ROpc, MOpc;
4314#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4316 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4320 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4325 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4326 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4332 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4333 if (Subtarget->hasTBM()) {
4334 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4335 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4337 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4343 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4344 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4348 MachineSDNode *NewNode;
4350 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4351 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4353 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4354 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4355 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4359 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4361 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4366 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4370 CurDAG->getMachineNode(NewOpc, dl, NVT,
SDValue(NewNode, 0), ShAmt);
4377MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4378 bool MayFoldLoad,
const SDLoc &dl,
4379 MVT VT, SDNode *Node) {
4384 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4387 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4388 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4391 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4392 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4401 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4402 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4409MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4410 bool MayFoldLoad,
const SDLoc &dl,
4411 MVT VT, SDNode *Node,
4417 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4420 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4421 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4424 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4425 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4435 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4436 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4441bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4442 EVT VT =
N->getValueType(0);
4449 unsigned Size = VT == MVT::i64 ? 64 : 32;
4452 SDValue ShiftAmt = OrigShiftAmt;
4471 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4475 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4476 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4480 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4489 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4490 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4496 Add0C->getZExtValue() != 0) {
4499 if (Add0C->getZExtValue() %
Size == 0)
4502 Add0C->getZExtValue() % 32 == 0) {
4510 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4514 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4536 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4543 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4544 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4548 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4550 if (UpdatedNode !=
N) {
4553 ReplaceNode(
N, UpdatedNode);
4560 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4568bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4569 MVT NVT =
N->getSimpleValueType(0);
4570 unsigned Opcode =
N->getOpcode();
4582 int64_t Val = Cst->getSExtValue();
4587 bool FoundAnyExtend =
false;
4591 FoundAnyExtend =
true;
4599 if (NVT != MVT::i32 && NVT != MVT::i64)
4606 uint64_t ShAmt = ShlCst->getZExtValue();
4610 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4611 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4616 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4620 ShiftedVal = (uint64_t)Val >> ShAmt;
4624 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4627 ShiftedVal = Val >> ShAmt;
4633 ShiftedVal = (uint64_t)Val >> ShAmt;
4641 if (!CanShrinkImmediate(ShiftedVal))
4651 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4657 NeededMask &= ~Cst->getAPIntValue();
4659 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4664 if (FoundAnyExtend) {
4670 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4672 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4681bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4682 SDNode *ParentB, SDNode *ParentC,
4685 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4686 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4688 auto tryFoldLoadOrBCast =
4691 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4697 L =
L.getOperand(0);
4705 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4709 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4712 bool FoldedLoad =
false;
4713 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4714 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4716 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4721 uint8_t OldImm =
Imm;
4722 Imm = OldImm & 0xa5;
4723 if (OldImm & 0x02)
Imm |= 0x10;
4724 if (OldImm & 0x10)
Imm |= 0x02;
4725 if (OldImm & 0x08)
Imm |= 0x40;
4726 if (OldImm & 0x40)
Imm |= 0x08;
4727 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4732 uint8_t OldImm =
Imm;
4733 Imm = OldImm & 0x99;
4734 if (OldImm & 0x02)
Imm |= 0x04;
4735 if (OldImm & 0x04)
Imm |= 0x02;
4736 if (OldImm & 0x20)
Imm |= 0x40;
4737 if (OldImm & 0x40)
Imm |= 0x20;
4742 SDValue TImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
4746 MachineSDNode *MNode;
4748 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4753 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4754 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4756 bool UseD = EltSize == 32;
4758 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4760 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4762 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4768 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4770 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4772 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4778 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
4781 ReplaceUses(
C.getValue(1),
SDValue(MNode, 1));
4788 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
4790 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
4792 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
4796 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
4800 CurDAG->RemoveDeadNode(Root);
4806bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
4807 MVT NVT =
N->getSimpleValueType(0);
4810 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
4818 auto getFoldableLogicOp = [](
SDValue Op) {
4821 Op =
Op.getOperand(0);
4823 if (!
Op.hasOneUse())
4826 unsigned Opc =
Op.getOpcode();
4837 auto tryPeelOuterNotWrappingLogic = [&](SDNode *
Op) {
4840 SDValue InnerOp = getFoldableLogicOp(
Op->getOperand(0));
4847 if ((FoldableOp = getFoldableLogicOp(N1))) {
4851 if ((FoldableOp = getFoldableLogicOp(N0))) {
4859 bool PeeledOuterNot =
false;
4861 if (
SDValue InnerOp = tryPeelOuterNotWrappingLogic(
N)) {
4862 PeeledOuterNot =
true;
4868 if ((FoldableOp = getFoldableLogicOp(N1)))
4870 else if ((FoldableOp = getFoldableLogicOp(N0)))
4878 SDNode *ParentA =
N;
4879 SDNode *ParentB = FoldableOp.
getNode();
4880 SDNode *ParentC = FoldableOp.
getNode();
4884 uint8_t TernlogMagicA = 0xf0;
4885 uint8_t TernlogMagicB = 0xcc;
4886 uint8_t TernlogMagicC = 0xaa;
4891 auto PeekThroughNot = [](
SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
4895 Parent =
Op.getNode();
4896 Op =
Op.getOperand(0);
4900 PeekThroughNot(
A, ParentA, TernlogMagicA);
4901 PeekThroughNot(
B, ParentB, TernlogMagicB);
4902 PeekThroughNot(
C, ParentC, TernlogMagicC);
4907 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
4908 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
4909 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
4913 switch (
N->getOpcode()) {
4917 Imm &= ~TernlogMagicA;
4919 Imm = ~(
Imm) & TernlogMagicA;
4929 return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC,
A,
B,
C, Imm);
4939bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
4942 MVT VT =
And->getSimpleValueType(0);
4943 if (VT != MVT::i32 && VT != MVT::i64)
4955 APInt MaskVal = And1C->getAPIntValue();
4957 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
4961 if (VT == MVT::i64 && MaskLZ >= 32) {
4963 MaskVal = MaskVal.
trunc(32);
4968 APInt NegMaskVal = MaskVal | HighZeros;
4977 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
4978 NegMaskVal = NegMaskVal.
zext(64);
4979 HighZeros = HighZeros.
zext(64);
4985 KnownBits Known0 = CurDAG->computeKnownBits(And0);
4997 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
5006 bool FoldedBCast,
bool Masked) {
5007#define VPTESTM_CASE(VT, SUFFIX) \
5010 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
5011 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
5014#define VPTESTM_BROADCAST_CASES(SUFFIX) \
5015default: llvm_unreachable("Unexpected VT!"); \
5016VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
5017VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
5018VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
5019VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
5020VPTESTM_CASE(v16i32, DZ##SUFFIX) \
5021VPTESTM_CASE(v8i64, QZ##SUFFIX)
5023#define VPTESTM_FULL_CASES(SUFFIX) \
5024VPTESTM_BROADCAST_CASES(SUFFIX) \
5025VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
5026VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
5027VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
5028VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
5029VPTESTM_CASE(v64i8, BZ##SUFFIX) \
5030VPTESTM_CASE(v32i16, WZ##SUFFIX)
5048#undef VPTESTM_FULL_CASES
5049#undef VPTESTM_BROADCAST_CASES
5055bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root,
SDValue Setcc,
5057 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
5102 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P,
SDValue &
L,
5107 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
5112 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
5118 L =
L.getOperand(0);
5125 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5128 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5132 bool CanFoldLoads = Src0 != Src1;
5134 bool FoldedLoad =
false;
5135 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5137 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5141 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5150 bool IsMasked = InMask.
getNode() !=
nullptr;
5163 SDValue ImplDef =
SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5165 Src0 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src0);
5168 Src1 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src1);
5173 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5174 InMask =
SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5175 dl, MaskVT, InMask, RC), 0);
5183 MachineSDNode *CNode;
5185 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5188 SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5190 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5192 SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5194 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5200 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5203 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5205 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5211 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5212 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5213 dl, ResVT,
SDValue(CNode, 0), RC);
5217 CurDAG->RemoveDeadNode(Root);
5223bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5226 MVT NVT =
N->getSimpleValueType(0);
5229 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5263 SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5271void X86DAGToDAGISel::Select(SDNode *Node) {
5272 MVT NVT =
Node->getSimpleValueType(0);
5273 unsigned Opcode =
Node->getOpcode();
5276 if (
Node->isMachineOpcode()) {
5278 Node->setNodeId(-1);
5285 unsigned IntNo =
Node->getConstantOperandVal(1);
5288 case Intrinsic::x86_encodekey128:
5289 case Intrinsic::x86_encodekey256: {
5290 if (!Subtarget->hasKL())
5296 case Intrinsic::x86_encodekey128:
5297 Opcode = X86::ENCODEKEY128;
5299 case Intrinsic::x86_encodekey256:
5300 Opcode = X86::ENCODEKEY256;
5305 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5307 if (Opcode == X86::ENCODEKEY256)
5308 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5311 MachineSDNode *Res = CurDAG->getMachineNode(
5312 Opcode, dl,
Node->getVTList(),
5313 {Node->getOperand(2), Chain, Chain.getValue(1)});
5314 ReplaceNode(Node, Res);
5317 case Intrinsic::x86_tileloaddrs64_internal:
5318 case Intrinsic::x86_tileloaddrst164_internal:
5319 if (!Subtarget->hasAMXMOVRS())
5322 case Intrinsic::x86_tileloadd64_internal:
5323 case Intrinsic::x86_tileloaddt164_internal: {
5324 if (!Subtarget->hasAMXTILE())
5327 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5328 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5333 case Intrinsic::x86_tileloaddrs64_internal:
5334 Opc = X86::PTILELOADDRSV;
5336 case Intrinsic::x86_tileloaddrst164_internal:
5337 Opc = X86::PTILELOADDRST1V;
5339 case Intrinsic::x86_tileloadd64_internal:
5340 Opc = X86::PTILELOADDV;
5342 case Intrinsic::x86_tileloaddt164_internal:
5343 Opc = X86::PTILELOADDT1V;
5348 SDValue Scale = getI8Imm(1, dl);
5350 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5351 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5353 MachineSDNode *CNode;
5355 Node->getOperand(3),
5362 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5363 ReplaceNode(Node, CNode);
5370 unsigned IntNo =
Node->getConstantOperandVal(1);
5373 case Intrinsic::x86_sse3_monitor:
5374 case Intrinsic::x86_monitorx:
5375 case Intrinsic::x86_clzero: {
5376 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5381 case Intrinsic::x86_sse3_monitor:
5382 if (!Subtarget->hasSSE3())
5384 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5386 case Intrinsic::x86_monitorx:
5387 if (!Subtarget->hasMWAITX())
5389 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5391 case Intrinsic::x86_clzero:
5392 if (!Subtarget->hasCLZERO())
5394 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5399 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5400 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5404 if (IntNo == Intrinsic::x86_sse3_monitor ||
5405 IntNo == Intrinsic::x86_monitorx) {
5407 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5410 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5415 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5417 ReplaceNode(Node, CNode);
5423 case Intrinsic::x86_tilestored64_internal: {
5425 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5426 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5427 unsigned Opc = X86::PTILESTOREDV;
5430 SDValue Scale = getI8Imm(1, dl);
5432 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5433 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5435 MachineSDNode *CNode;
5437 Node->getOperand(3),
5443 Node->getOperand(6),
5445 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5446 ReplaceNode(Node, CNode);
5449 case Intrinsic::x86_tileloaddrs64:
5450 case Intrinsic::x86_tileloaddrst164:
5451 if (!Subtarget->hasAMXMOVRS())
5454 case Intrinsic::x86_tileloadd64:
5455 case Intrinsic::x86_tileloaddt164:
5456 case Intrinsic::x86_tilestored64: {
5457 if (!Subtarget->hasAMXTILE())
5460 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5461 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5465 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5466 case Intrinsic::x86_tileloaddrs64:
5467 Opc = X86::PTILELOADDRS;
5469 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5470 case Intrinsic::x86_tileloaddrst164:
5471 Opc = X86::PTILELOADDRST1;
5473 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5476 unsigned TIndex =
Node->getConstantOperandVal(2);
5479 SDValue Scale = getI8Imm(1, dl);
5481 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5482 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5484 MachineSDNode *CNode;
5485 if (
Opc == X86::PTILESTORED) {
5487 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5490 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5492 ReplaceNode(Node, CNode);
5500 if (Subtarget->isTarget64BitILP32()) {
5505 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5506 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5507 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5508 Node->getOperand(0), ZextTarget);
5509 ReplaceNode(Node, Brind.
getNode());
5510 SelectCode(ZextTarget.
getNode());
5517 ReplaceNode(Node, getGlobalBaseReg());
5524 ReplaceUses(
SDValue(Node, 0),
Node->getOperand(0));
5525 CurDAG->RemoveDeadNode(Node);
5531 if (matchBitExtract(Node))
5536 if (tryShiftAmountMod(Node))
5541 uint8_t
Imm =
Node->getConstantOperandVal(3);
5542 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5543 Node->getOperand(1),
Node->getOperand(2), Imm))
5549 if (tryVPTERNLOG(Node))
5559 tryVPTESTM(Node, N0, N1))
5562 tryVPTESTM(Node, N1, N0))
5566 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5568 CurDAG->RemoveDeadNode(Node);
5571 if (matchBitExtract(Node))
5579 if (tryShrinkShlLogicImm(Node))
5581 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5583 if (tryVPTERNLOG(Node))
5588 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5598 if (!CurDAG->shouldOptForSize())
5602 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5612 int64_t Val = Cst->getSExtValue();
5620 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5624 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5628 unsigned ROpc, MOpc;
5737 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5738 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5740 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5741 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5747 CurDAG->RemoveDeadNode(Node);
5752 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
5765 unsigned LoReg, ROpc, MOpc;
5770 ROpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
5771 MOpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
5790 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5791 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5794 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5799 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5802 MachineSDNode *CNode;
5808 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5810 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
5814 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5825 VTs = CurDAG->getVTList(NVT, MVT::i32);
5827 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
5829 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
5833 ReplaceUses(
SDValue(Node, 1),
SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
5834 CurDAG->RemoveDeadNode(Node);
5844 unsigned LoReg, HiReg;
5846 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
5847 bool UseMULXHi = UseMULX &&
SDValue(Node, 0).use_empty();
5851 Opc = UseMULXHi ? X86::MULX32Hrr
5853 : IsSigned ?
X86::IMUL32r
5855 MOpc = UseMULXHi ? X86::MULX32Hrm
5857 : IsSigned ?
X86::IMUL32m
5859 LoReg = UseMULX ? X86::EDX : X86::EAX;
5863 Opc = UseMULXHi ? X86::MULX64Hrr
5865 : IsSigned ?
X86::IMUL64r
5867 MOpc = UseMULXHi ? X86::MULX64Hrm
5869 : IsSigned ?
X86::IMUL64m
5871 LoReg = UseMULX ? X86::RDX : X86::RAX;
5876 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5877 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5880 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5885 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5890 MachineSDNode *CNode =
nullptr;
5894 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5895 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5898 }
else if (UseMULX) {
5899 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
5900 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5905 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5906 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5912 ReplaceUses(N1.
getValue(1), Chain);
5918 SDVTList VTs = CurDAG->getVTList(NVT);
5919 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5921 }
else if (UseMULX) {
5922 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
5923 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5927 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
5928 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5934 if (!
SDValue(Node, 0).use_empty()) {
5936 assert(LoReg &&
"Register for low half is not defined!");
5937 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
5941 ReplaceUses(
SDValue(Node, 0), ResLo);
5946 if (!
SDValue(Node, 1).use_empty()) {
5948 assert(HiReg &&
"Register for high half is not defined!");
5949 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
5953 ReplaceUses(
SDValue(Node, 1), ResHi);
5958 CurDAG->RemoveDeadNode(Node);
5967 unsigned ROpc, MOpc;
5972 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
5973 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
5974 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
5975 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
5980 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
5981 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
5982 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
5983 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
5987 unsigned LoReg, HiReg, ClrReg;
5988 unsigned SExtOpcode;
5992 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
5996 LoReg = X86::AX; HiReg = X86::DX;
5998 SExtOpcode = X86::CWD;
6001 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
6002 SExtOpcode = X86::CDQ;
6005 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
6006 SExtOpcode = X86::CQO;
6010 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6011 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6012 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
6015 if (NVT == MVT::i8) {
6018 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
6019 MachineSDNode *Move;
6020 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6022 unsigned Opc = (isSigned && !signBitIsZero) ? X86::MOVSX16rm8
6024 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
6026 ReplaceUses(N0.
getValue(1), Chain);
6030 unsigned Opc = (isSigned && !signBitIsZero) ? X86::MOVSX16rr8
6032 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
6033 Chain = CurDAG->getEntryNode();
6035 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX,
SDValue(Move, 0),
6040 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
6041 LoReg, N0,
SDValue()).getValue(1);
6042 if (isSigned && !signBitIsZero) {
6045 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
6048 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
6050 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
6054 SDValue(CurDAG->getMachineNode(
6055 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
6056 CurDAG->getTargetConstant(X86::sub_16bit, dl,
6064 CurDAG->getMachineNode(
6065 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, ClrNode,
6066 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
6073 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
6074 ClrNode, InGlue).getValue(1);
6081 MachineSDNode *CNode =
6082 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
6090 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
6100 if (HiReg == X86::AH && !
SDValue(Node, 1).use_empty()) {
6101 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
6102 unsigned AHExtOpcode =
6103 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6105 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6106 MVT::Glue, AHCopy, InGlue);
6111 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6113 ReplaceUses(
SDValue(Node, 1), Result);
6118 if (!
SDValue(Node, 0).use_empty()) {
6119 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6120 LoReg, NVT, InGlue);
6121 InGlue =
Result.getValue(2);
6122 ReplaceUses(
SDValue(Node, 0), Result);
6127 if (!
SDValue(Node, 1).use_empty()) {
6128 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6129 HiReg, NVT, InGlue);
6130 InGlue =
Result.getValue(2);
6131 ReplaceUses(
SDValue(Node, 1), Result);
6135 CurDAG->RemoveDeadNode(Node);
6144 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6145 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6151 if (Subtarget->canUseCMOV())
6160 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6163 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6166 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6171 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6174 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6175 Chain =
SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6178 Glue =
SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6183 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6187 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6191 assert(Subtarget->canUseLAHFSAHF() &&
6192 "Target doesn't support SAHF or FCOMI?");
6193 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract,
SDValue());
6196 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6199 ReplaceUses(
SDValue(Node, 1), Chain);
6201 ReplaceUses(
SDValue(Node, 0), SAHF);
6202 CurDAG->RemoveDeadNode(Node);
6222 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6223 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6226 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6228 CurDAG->RemoveDeadNode(Node);
6248 uint64_t
Mask = MaskC->getZExtValue();
6255 onlyUsesZeroFlag(
SDValue(Node, 0))) {
6260 unsigned TestOpcode;
6268 if (LeadingZeros == 0 && SavesBytes) {
6273 ShiftAmt = TrailingZeros;
6275 TestOpcode = X86::TEST64rr;
6276 }
else if (TrailingZeros == 0 && SavesBytes) {
6281 ShiftAmt = LeadingZeros;
6283 TestOpcode = X86::TEST64rr;
6284 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6287 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6288 if (PopCount == 8) {
6290 ShiftAmt = TrailingZeros;
6291 SubRegIdx = X86::sub_8bit;
6293 TestOpcode = X86::TEST8rr;
6294 }
else if (PopCount == 16) {
6296 ShiftAmt = TrailingZeros;
6297 SubRegIdx = X86::sub_16bit;
6298 SubRegVT = MVT::i16;
6299 TestOpcode = X86::TEST16rr;
6300 }
else if (PopCount == 32) {
6302 ShiftAmt = TrailingZeros;
6303 SubRegIdx = X86::sub_32bit;
6304 SubRegVT = MVT::i32;
6305 TestOpcode = X86::TEST32rr;
6309 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6311 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6314 if (SubRegIdx != 0) {
6316 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6318 MachineSDNode *
Test =
6319 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6320 ReplaceNode(Node,
Test);
6327 unsigned ROpc, MOpc;
6335 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6336 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6339 SubRegOp = X86::sub_8bit;
6340 ROpc = X86::TEST8ri;
6341 MOpc = X86::TEST8mi;
6342 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6343 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6344 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6350 SubRegOp = X86::sub_16bit;
6351 ROpc = X86::TEST16ri;
6352 MOpc = X86::TEST16mi;
6354 ((!(Mask & 0x80000000) &&
6357 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6358 CmpVT == MVT::i32 ||
6359 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6366 SubRegOp = X86::sub_32bit;
6367 ROpc = X86::TEST32ri;
6368 MOpc = X86::TEST32mi;
6374 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6378 MachineSDNode *NewNode;
6379 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6380 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6382 if (!LoadN->isSimple()) {
6383 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6384 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6385 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6386 (MOpc == X86::TEST32mi && NumVolBits != 32))
6391 Reg.getOperand(0) };
6392 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6394 ReplaceUses(
Reg.getValue(1),
SDValue(NewNode, 1));
6396 CurDAG->setNodeMemRefs(NewNode,
6401 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6403 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg, Imm);
6406 ReplaceNode(Node, NewNode);
6412 if (!Subtarget->hasSSE42())
6415 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6416 bool NeedMask = !
SDValue(Node, 1).use_empty();
6418 bool MayFoldLoad = !NeedIndex || !NeedMask;
6420 MachineSDNode *CNode;
6423 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6425 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6426 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6429 if (NeedIndex || !NeedMask) {
6431 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6433 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6434 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6440 CurDAG->RemoveDeadNode(Node);
6444 if (!Subtarget->hasSSE42())
6448 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6449 Node->getOperand(1),
6451 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6452 Node->getOperand(3), InGlue).getValue(1);
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::VPCMPESTRMrri : X86::PCMPESTRMrri;
6464 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6466 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6469 if (NeedIndex || !NeedMask) {
6471 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6473 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6474 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6479 CurDAG->RemoveDeadNode(Node);
6491 if (foldLoadStoreIntoMemOperand(Node))
6496 MVT VT =
Node->getSimpleValueType(0);
6498 if (Subtarget->hasSBBDepBreaking()) {
6503 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6508 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6509 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6511 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6516 Result = getSBBZero(Node);
6520 if (VT == MVT::i8 || VT == MVT::i16) {
6521 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6522 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6525 ReplaceUses(
SDValue(Node, 0), Result);
6526 CurDAG->RemoveDeadNode(Node);
6538 if (!
SDValue(Node, 0).use_empty()) {
6540 MVT VT =
Node->getSimpleValueType(0);
6541 if (VT == MVT::i8 || VT == MVT::i16) {
6542 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6543 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6545 ReplaceUses(
SDValue(Node, 0), Result);
6548 CurDAG->RemoveDeadNode(Node);
6555 SDValue IndexOp = Mgt->getIndex();
6558 MVT ValueVT =
Node->getSimpleValueType(0);
6559 MVT MaskVT =
Mask.getSimpleValueType();
6576 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6577 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6578 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6579 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6580 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6581 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6582 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6583 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6584 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6585 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6586 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6587 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6588 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6589 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6590 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6591 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6592 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6593 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6594 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6595 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6596 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6597 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6598 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6599 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6601 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6602 "Unexpected mask VT!");
6603 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6604 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6605 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6606 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6607 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6608 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6609 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6610 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6611 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6612 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6613 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6614 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6615 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6616 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6617 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6618 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6625 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6626 Base, Scale, Index, Disp, Segment))
6629 SDValue PassThru = Mgt->getPassThru();
6630 SDValue Chain = Mgt->getChain();
6632 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6634 MachineSDNode *NewNode;
6637 Index, Disp, Segment, Chain};
6638 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6641 Disp, Segment,
Mask, Chain};
6642 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6644 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6647 CurDAG->RemoveDeadNode(Node);
6653 SDValue IndexOp = Sc->getIndex();
6655 MVT ValueVT =
Value.getSimpleValueType();
6670 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6671 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6672 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6673 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6674 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6675 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6676 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6677 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6678 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6679 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6680 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6681 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6682 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6683 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6684 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6685 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6686 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6687 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6688 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6689 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6690 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6691 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6692 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6693 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6698 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6699 Base, Scale, Index, Disp, Segment))
6703 SDValue Chain = Sc->getChain();
6705 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6708 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6709 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6711 CurDAG->RemoveDeadNode(Node);
6715 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6716 auto CallId = MFI->getPreallocatedIdForCallSite(
6719 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6720 MachineSDNode *
New = CurDAG->getMachineNode(
6721 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6723 CurDAG->RemoveDeadNode(Node);
6727 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6731 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6734 Ops[0] = CallIdValue;
6737 MachineSDNode *
New = CurDAG->getMachineNode(
6738 TargetOpcode::PREALLOCATED_ARG, dl,
6739 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
6744 CurDAG->RemoveDeadNode(Node);
6751 if (!Subtarget->hasWIDEKL())
6755 switch (
Node->getOpcode()) {
6759 Opcode = X86::AESENCWIDE128KL;
6762 Opcode = X86::AESDECWIDE128KL;
6765 Opcode = X86::AESENCWIDE256KL;
6768 Opcode = X86::AESDECWIDE256KL;
6776 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
6779 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
6781 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
6783 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
6785 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
6787 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
6789 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
6791 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
6793 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
6796 MachineSDNode *Res = CurDAG->getMachineNode(
6797 Opcode, dl,
Node->getVTList(),
6798 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
6800 ReplaceNode(Node, Res);
6807 if (
Node->getNumValues() == 3)
6808 Glue =
Node->getOperand(2);
6810 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
6811 ReplaceNode(Node,
Copy.getNode());
6819bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
6821 std::vector<SDValue> &OutOps) {
6822 SDValue Op0, Op1, Op2, Op3, Op4;
6823 switch (ConstraintID) {
6826 case InlineAsm::ConstraintCode::o:
6827 case InlineAsm::ConstraintCode::v:
6828 case InlineAsm::ConstraintCode::m:
6829 case InlineAsm::ConstraintCode::X:
6830 case InlineAsm::ConstraintCode::p:
6831 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
6836 OutOps.push_back(Op0);
6837 OutOps.push_back(Op1);
6838 OutOps.push_back(Op2);
6839 OutOps.push_back(Op3);
6840 OutOps.push_back(Op4);
6846 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
6852 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 TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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)
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)
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.
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 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.
@ FST
This instruction implements a truncating store from FP stack slots.
@ CMPM
Vector comparison generating mask bits for fp and integer signed and unsigned data types.
@ CMP
X86 compare and logical compare instructions.
@ BLENDV
Dynamic (non-constant condition) vector blend where only the sign bits of the condition elements are ...
@ STRICT_CMPM
Vector comparison generating mask bits for fp and integer signed and unsigned data types.
@ NT_BRIND
BRIND node with NoTrack prefix.
@ FSETCCM
X86 FP SETCC, similar to above, but with output as an i1 mask and and a version with SAE.
@ FXOR
Bitwise logical XOR of floating point values.
@ BRCOND
X86 conditional branches.
@ CALL
These operations represent an abstract X86 call instruction, which includes a bunch of information.
@ FANDN
Bitwise logical ANDNOT of floating point values.
@ GlobalBaseReg
On Darwin, this node represents the result of the popl at function entry, used for PIC code.
@ FLD
This instruction implements an extending load to FP stack slots.
@ TC_RETURN
Tail call return.
@ FOR
Bitwise logical OR of floating point values.
@ Wrapper
A wrapper node for TargetConstantPool, TargetJumpTable, TargetExternalSymbol, TargetGlobalAddress,...
@ ANDNP
Bitwise Logical AND NOT of Packed FP values.
@ POP_FROM_X87_REG
The same as ISD::CopyFromReg except that this node makes it explicit that it may lower to an x87 FPU ...
@ FAND
Bitwise logical AND of floating point values.
@ CMOV
X86 conditional moves.
@ WrapperRIP
Special wrapper used under X86-64 PIC mode for RIP relative displacements.
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