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()) {
382 if (
User->getOpcode() == ISD::STORE &&
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,
490 CurDAG->getTargetConstant(0, dl, MVT::i64), Zero,
491 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
496 unsigned Opcode =
N->getOpcode();
498 "Unexpected opcode for SBB materialization");
499 unsigned FlagOpIndex = Opcode ==
X86ISD::SBB ? 2 : 1;
501 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
502 N->getOperand(FlagOpIndex),
SDValue());
506 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
507 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
508 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
510 CurDAG->getMachineNode(
Opc, dl, VTs,
511 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
517 bool isUnneededShiftMask(SDNode *
N,
unsigned Width)
const {
519 const APInt &Val =
N->getConstantOperandAPInt(1);
524 APInt
Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
525 return Mask.countr_one() >= Width;
531 SDNode *getGlobalBaseReg();
535 const X86TargetMachine &getTargetMachine()
const {
536 return static_cast<const X86TargetMachine &
>(
TM);
541 const X86InstrInfo *getInstrInfo()
const {
542 return Subtarget->getInstrInfo();
551 bool ComplexPatternFuncMutatesDAG()
const override {
555 bool isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const;
558 bool useNonTemporalLoad(LoadSDNode *
N)
const {
559 if (!
N->isNonTemporal())
562 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
564 if (
N->getAlign().value() < StoreSize)
573 return Subtarget->hasSSE41();
575 return Subtarget->hasAVX2();
577 return Subtarget->hasAVX512();
581 bool foldLoadStoreIntoMemOperand(SDNode *Node);
582 MachineSDNode *matchBEXTRFromAndImm(SDNode *Node);
583 bool matchBitExtract(SDNode *Node);
584 bool shrinkAndImmediate(SDNode *
N);
585 bool isMaskZeroExtended(SDNode *
N)
const;
586 bool tryShiftAmountMod(SDNode *
N);
587 bool tryShrinkShlLogicImm(SDNode *
N);
588 bool tryVPTERNLOG(SDNode *
N);
589 bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentB,
593 bool tryMatchBitSelect(SDNode *
N);
595 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
596 const SDLoc &dl, MVT VT, SDNode *Node);
597 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
598 const SDLoc &dl, MVT VT, SDNode *Node,
601 bool tryOptimizeRem8Extend(SDNode *
N);
603 bool onlyUsesZeroFlag(
SDValue Flags)
const;
604 bool hasNoSignFlagUses(
SDValue Flags)
const;
605 bool hasNoCarryFlagUses(
SDValue Flags)
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)
671 if (
N.getOpcode() != ISD::LOAD)
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())
879 while (HasCallSeq && Chain.
getOpcode() != ISD::CALLSEQ_START) {
896 Callee.getValue(1).hasOneUse())
904 if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
907 uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
908 0x65, 0x66, 0x67, 0xf0, 0xf2};
911 uint8_t Byte = (Imm >> i) & 0xFF;
923 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
926void X86DAGToDAGISel::PreprocessISelDAG() {
927 bool MadeChange =
false;
929 E = CurDAG->allnodes_end();
I !=
E; ) {
948 MVT VT =
N->getSimpleValueType(0);
950 int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
955 "cf-protection-branch");
958 SDValue Complement = CurDAG->getConstant(~Imm, dl, VT,
false,
true);
959 Complement = CurDAG->getNOT(dl, Complement, VT);
961 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Complement);
971 if (
N->getOpcode() ==
X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
973 N->getOperand(0),
N->getOperand(1));
975 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
999 auto mayPreventLoadFold = [&]() {
1001 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1002 !
N->getOperand(1).hasOneUse();
1005 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1011 MVT VT =
N->getSimpleValueType(0);
1019 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1021 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1028 switch (
N->getOpcode()) {
1030 MVT VT =
N->getSimpleValueType(0);
1032 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1039 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1042 CurDAG->getIntPtrConstant(Index, dl));
1045 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1054 MVT VT =
N->getSimpleValueType(0);
1056 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1060 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1061 SDValue Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1062 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1064 MemNode->getMemOperand());
1067 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1070 CurDAG->getIntPtrConstant(Index, dl));
1074 CurDAG->ReplaceAllUsesWith(
N, To);
1086 MVT VT =
N->getSimpleValueType(0);
1092 SDNode *MaxLd =
nullptr;
1094 SDValue Chain = Ld->getChain();
1095 for (SDNode *User :
Ptr->users()) {
1097 MVT UserVT =
User->getSimpleValueType(0);
1099 UserLd->getBasePtr() ==
Ptr && UserLd->getChain() == Chain &&
1100 !
User->hasAnyUseOfValue(1) &&
1114 CurDAG->getIntPtrConstant(0, dl));
1115 SDValue Res = CurDAG->getBitcast(VT, Extract);
1119 CurDAG->ReplaceAllUsesWith(
N, To);
1128 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1129 if (EleVT == MVT::i1)
1132 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1133 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1134 "We can't replace VSELECT with BLENDV in vXi16!");
1136 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1139 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1140 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1143 N->getOperand(0),
N->getOperand(1),
1147 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1160 if (!
N->getSimpleValueType(0).isVector())
1164 switch (
N->getOpcode()) {
1174 if (
N->isStrictFPOpcode())
1176 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1177 {
N->getOperand(0),
N->getOperand(1)});
1180 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1183 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1193 if (!
N->getValueType(0).isVector())
1197 switch (
N->getOpcode()) {
1203 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1204 N->getOperand(0),
N->getOperand(1));
1206 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1215 if (!
N->getValueType(0).isVector())
1219 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1221 "Unexpected opcode for mask vector!");
1229 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1232 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1243 case ISD::FROUNDEVEN:
1245 case ISD::FNEARBYINT:
1252 switch (
N->getOpcode()) {
1255 case ISD::FCEIL:
Imm = 0xA;
break;
1257 case ISD::FFLOOR:
Imm = 0x9;
break;
1259 case ISD::FTRUNC:
Imm = 0xB;
break;
1261 case ISD::FROUNDEVEN:
Imm = 0x8;
break;
1263 case ISD::FNEARBYINT:
Imm = 0xC;
break;
1265 case ISD::FRINT:
Imm = 0x4;
break;
1268 bool IsStrict =
N->isStrictFPOpcode();
1272 {
N->getValueType(0), MVT::Other},
1273 {
N->getOperand(0),
N->getOperand(1),
1274 CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
1278 CurDAG->getTargetConstant(Imm, dl, MVT::i32));
1280 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1291 MVT VT =
N->getSimpleValueType(0);
1292 if (VT.
isVector() || VT == MVT::f128)
1295 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1296 : VT == MVT::f32 ? MVT::v4f32
1306 if (Subtarget->hasSSE2()) {
1307 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1308 Op0 = CurDAG->getNode(ISD::BITCAST, dl, IntVT, Op0);
1309 Op1 = CurDAG->getNode(ISD::BITCAST, dl, IntVT, Op1);
1311 switch (
N->getOpcode()) {
1318 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1319 Res = CurDAG->getNode(ISD::BITCAST, dl, VecVT, Res);
1321 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1324 CurDAG->getIntPtrConstant(0, dl));
1326 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1333 if (OptLevel != CodeGenOptLevel::None &&
1336 !Subtarget->useIndirectThunkCalls() &&
1337 ((
N->getOpcode() ==
X86ISD::CALL && !Subtarget->slowTwoMemOps()) ||
1339 (Subtarget->is64Bit() ||
1340 !getTargetMachine().isPositionIndependent())))) {
1379 switch (
N->getOpcode()) {
1382 case ISD::FP_EXTEND:
1384 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1385 MVT DstVT =
N->getSimpleValueType(0);
1393 const X86TargetLowering *X86Lowering =
1394 static_cast<const X86TargetLowering *
>(TLI);
1397 if (SrcIsSSE && DstIsSSE)
1400 if (!SrcIsSSE && !DstIsSSE) {
1402 if (
N->getOpcode() == ISD::FP_EXTEND)
1405 if (
N->getConstantOperandVal(1))
1413 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1415 MachinePointerInfo MPI =
1422 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1424 MemTmp, MPI, MemVT);
1431 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1440 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1441 MVT DstVT =
N->getSimpleValueType(0);
1449 const X86TargetLowering *X86Lowering =
1450 static_cast<const X86TargetLowering *
>(TLI);
1453 if (SrcIsSSE && DstIsSSE)
1456 if (!SrcIsSSE && !DstIsSSE) {
1461 if (
N->getConstantOperandVal(2))
1469 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1471 MachinePointerInfo MPI =
1480 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1481 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1485 if (
N->getFlags().hasNoFPExcept()) {
1487 Flags.setNoFPExcept(
true);
1488 Store->setFlags(Flags);
1491 assert(SrcVT == MemVT &&
"Unexpected VT!");
1492 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1497 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1499 Result = CurDAG->getMemIntrinsicNode(
1502 if (
N->getFlags().hasNoFPExcept()) {
1504 Flags.setNoFPExcept(
true);
1508 assert(DstVT == MemVT &&
"Unexpected VT!");
1509 Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
1517 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1531 CurDAG->RemoveDeadNodes();
1535bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1536 unsigned Opc =
N->getMachineOpcode();
1537 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1538 Opc != X86::MOVSX64rr8)
1550 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1551 : X86::MOVSX32rr8_NOREX;
1556 if (
Opc == X86::MOVSX64rr8) {
1559 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1561 ReplaceUses(
N, Extend);
1570void X86DAGToDAGISel::PostprocessISelDAG() {
1572 if (
TM.getOptLevel() == CodeGenOptLevel::None)
1577 bool MadeChange =
false;
1578 while (Position != CurDAG->allnodes_begin()) {
1579 SDNode *
N = &*--Position;
1581 if (
N->use_empty() || !
N->isMachineOpcode())
1584 if (tryOptimizeRem8Extend(
N)) {
1589 unsigned Opc =
N->getMachineOpcode();
1600 case X86::CTEST16rr:
1601 case X86::CTEST32rr:
1602 case X86::CTEST64rr: {
1608#define CASE_ND(OP) \
1611 switch (
And.getMachineOpcode()) {
1618 if (
And->hasAnyUseOfValue(1))
1621 Ops[0] =
And.getOperand(0);
1622 Ops[1] =
And.getOperand(1);
1623 MachineSDNode *
Test =
1624 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1625 ReplaceUses(
N,
Test);
1633 if (
And->hasAnyUseOfValue(1))
1636 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1637#define FROM_TO(A, B) \
1638 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1640 switch (
And.getMachineOpcode()) {
1650 And.getOperand(3),
And.getOperand(4),
1651 And.getOperand(5),
And.getOperand(0)};
1654 Ops.push_back(
N->getOperand(2));
1655 Ops.push_back(
N->getOperand(3));
1658 Ops.push_back(
And.getOperand(6));
1661 Ops.push_back(
N->getOperand(4));
1663 MachineSDNode *
Test = CurDAG->getMachineNode(
1664 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1665 CurDAG->setNodeMemRefs(
1678 case X86::KORTESTBkk:
1679 case X86::KORTESTWkk:
1680 case X86::KORTESTDkk:
1681 case X86::KORTESTQkk: {
1683 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1698#define FROM_TO(A, B) \
1710 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1713 MachineSDNode *KTest = CurDAG->getMachineNode(
1715 ReplaceUses(
N, KTest);
1720 case TargetOpcode::SUBREG_TO_REG: {
1721 unsigned SubRegIdx =
N->getConstantOperandVal(2);
1722 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1739 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1740 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1741 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1742 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1743 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1744 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1745 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1746 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1751 if (!
In.isMachineOpcode() ||
1752 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1757 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1765 CurDAG->UpdateNodeOperands(
N,
N->getOperand(0), In,
N->getOperand(2));
1772 CurDAG->RemoveDeadNodes();
1777void X86DAGToDAGISel::emitSpecialCodeForMain() {
1778 if (Subtarget->isTargetCygMing()) {
1779 TargetLowering::ArgListTy
Args;
1780 auto &
DL = CurDAG->getDataLayout();
1782 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1783 CLI.setChain(CurDAG->getRoot())
1784 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1785 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1787 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1789 CurDAG->setRoot(
Result.second);
1793void X86DAGToDAGISel::emitFunctionEntryCode() {
1796 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1797 emitSpecialCodeForMain();
1810bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t
Offset,
1811 X86ISelAddressMode &AM) {
1816 int64_t Val = AM.Disp +
Offset;
1819 if (Val != 0 && (AM.ES || AM.MCSym))
1823 if (Subtarget->is64Bit()) {
1826 AM.hasSymbolicDisplacement()))
1830 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1849 if (Subtarget->isTarget64BitILP32() &&
1851 !AM.hasBaseOrIndexReg())
1861bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1862 bool AllowSegmentRegForX32) {
1875 !IndirectTlsSegRefs &&
1876 (Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() ||
1877 Subtarget->isTargetFuchsia())) {
1878 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1880 switch (
N->getPointerInfo().getAddrSpace()) {
1882 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1885 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1898bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1901 if (AM.hasSymbolicDisplacement())
1904 bool IsRIPRelTLS =
false;
1922 if (IsRIPRel && AM.hasBaseOrIndexReg())
1926 X86ISelAddressMode Backup = AM;
1931 AM.GV =
G->getGlobal();
1932 AM.SymbolFlags =
G->getTargetFlags();
1935 AM.CP =
CP->getConstVal();
1936 AM.Alignment =
CP->getAlign();
1937 AM.SymbolFlags =
CP->getTargetFlags();
1940 AM.ES = S->getSymbol();
1941 AM.SymbolFlags = S->getTargetFlags();
1943 AM.MCSym = S->getMCSymbol();
1945 AM.JT = J->getIndex();
1946 AM.SymbolFlags = J->getTargetFlags();
1948 AM.BlockAddr = BA->getBlockAddress();
1949 AM.SymbolFlags = BA->getTargetFlags();
1950 Offset = BA->getOffset();
1955 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1956 TM.isLargeGlobalValue(AM.GV)) {
1961 if (foldOffsetIntoAddress(
Offset, AM)) {
1967 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
1975bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
1976 if (matchAddressRecursively(
N, AM, 0))
1983 if (Subtarget->isTarget64BitILP32() &&
1984 AM.BaseType == X86ISelAddressMode::RegBase &&
1985 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
1986 SDValue Save_Base_Reg = AM.Base_Reg;
1989 if (matchLoadInAddress(LoadN, AM,
true))
1990 AM.Base_Reg = Save_Base_Reg;
1996 if (AM.Scale == 2 &&
1997 AM.BaseType == X86ISelAddressMode::RegBase &&
1998 AM.Base_Reg.
getNode() ==
nullptr) {
1999 AM.Base_Reg = AM.IndexReg;
2006 (!AM.GV || !
TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2007 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2008 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2020 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2026bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
2030 HandleSDNode Handle(
N);
2032 X86ISelAddressMode Backup = AM;
2033 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
2034 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
2039 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
2041 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2048 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2051 N = Handle.getValue();
2057 N = Handle.getValue();
2067 if (
N->getNodeId() == -1 ||
2087 X86ISelAddressMode &AM) {
2094 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2095 Mask != (0xffu << ScaleLog))
2098 MVT XVT =
X.getSimpleValueType();
2099 MVT VT =
N.getSimpleValueType();
2124 AM.Scale = (1 << ScaleLog);
2132 X86ISelAddressMode &AM) {
2143 bool FoundAnyExtend =
false;
2147 FoundAnyExtend =
true;
2165 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2168 MVT VT =
N.getSimpleValueType();
2170 if (FoundAnyExtend) {
2191 AM.Scale = 1 << ShiftAmt;
2192 AM.IndexReg = NewAnd;
2226 X86ISelAddressMode &AM) {
2232 unsigned MaskIdx, MaskLen;
2235 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2241 unsigned AMShiftAmt = MaskIdx;
2245 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2249 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2250 if (MaskLZ < ScaleDown)
2252 MaskLZ -= ScaleDown;
2260 bool ReplacingAnyExtend =
false;
2262 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2263 X.getOperand(0).getSimpleValueType().getSizeInBits();
2266 X =
X.getOperand(0);
2267 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2268 ReplacingAnyExtend =
true;
2270 APInt MaskedHighBits =
2277 MVT VT =
N.getSimpleValueType();
2278 if (ReplacingAnyExtend) {
2279 assert(
X.getValueType() != VT);
2286 MVT XVT =
X.getSimpleValueType();
2307 AM.Scale = 1 << AMShiftAmt;
2308 AM.IndexReg = NewExt;
2318 X86ISelAddressMode &AM,
2326 if (!Subtarget.hasTBM() &&
2327 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2331 unsigned MaskIdx, MaskLen;
2339 unsigned AMShiftAmt = MaskIdx;
2343 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2345 MVT XVT =
X.getSimpleValueType();
2346 MVT VT =
N.getSimpleValueType();
2371 AM.Scale = 1 << AMShiftAmt;
2372 AM.IndexReg = NewExt;
2379 X86ISelAddressMode &AM,
2381 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2382 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2383 "Illegal index scale");
2389 EVT VT =
N.getValueType();
2390 unsigned Opc =
N.getOpcode();
2393 if (CurDAG->isBaseWithConstantOffset(
N)) {
2395 uint64_t
Offset = (uint64_t)AddVal->getSExtValue() * AM.Scale;
2396 if (!foldOffsetIntoAddress(
Offset, AM))
2397 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2401 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2402 if (AM.Scale <= 4) {
2404 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2410 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2411 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2412 if ((AM.Scale * ScaleAmt) <= 8) {
2413 AM.Scale *= ScaleAmt;
2414 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2422 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2424 if (CurDAG->isBaseWithConstantOffset(Src)) {
2425 SDValue AddSrc = Src.getOperand(0);
2427 int64_t
Offset = AddVal->getSExtValue();
2428 if (!foldOffsetIntoAddress((uint64_t)
Offset * AM.Scale, AM)) {
2436 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2437 CurDAG->RemoveDeadNode(
N.getNode());
2449 unsigned SrcOpc = Src.getOpcode();
2450 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2451 CurDAG->isADDLike(Src,
true)) &&
2453 if (CurDAG->isBaseWithConstantOffset(Src)) {
2454 SDValue AddSrc = Src.getOperand(0);
2455 uint64_t
Offset = Src.getConstantOperandVal(1);
2456 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2466 uint64_t ScaleAmt = 1ULL << ShAmt;
2467 if ((AM.Scale * ScaleAmt) <= 8 &&
2469 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2470 AM.Scale *= ScaleAmt;
2471 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2482 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2486 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2487 CurDAG->RemoveDeadNode(
N.getNode());
2488 return Res ? Res : ExtSrc;
2498bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2501 dbgs() <<
"MatchAddress: ";
2506 return matchAddressBase(
N, AM);
2511 if (AM.isRIPRelative()) {
2515 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2519 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2524 switch (
N.getOpcode()) {
2527 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2530 AM.MCSym = ESNode->getMCSymbol();
2537 if (!foldOffsetIntoAddress(Val, AM))
2544 if (!matchWrapper(
N, AM))
2554 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2555 AM.Base_Reg.
getNode() ==
nullptr &&
2557 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2564 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2568 unsigned Val = CN->getZExtValue();
2573 if (Val == 1 || Val == 2 || Val == 3) {
2575 AM.Scale = 1 << Val;
2576 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2584 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2588 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2589 "Unexpected value size!");
2601 uint64_t
Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2613 if (
N.getResNo() != 0)
break;
2618 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2619 AM.Base_Reg.
getNode() ==
nullptr &&
2620 AM.IndexReg.
getNode() ==
nullptr) {
2622 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2623 CN->getZExtValue() == 9) {
2624 AM.Scale = unsigned(CN->getZExtValue())-1;
2636 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2637 if (foldOffsetIntoAddress(Disp, AM))
2638 Reg =
N.getOperand(0);
2640 Reg =
N.getOperand(0);
2643 AM.IndexReg = AM.Base_Reg =
Reg;
2659 HandleSDNode Handle(
N);
2662 X86ISelAddressMode Backup = AM;
2663 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2664 N = Handle.getValue();
2668 N = Handle.getValue();
2670 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2685 RHS.getOperand(0).getValueType() == MVT::i32))
2689 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2691 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2695 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2696 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2709 AM.NegateIndex =
true;
2717 if (!CurDAG->isADDLike(
N))
2721 if (!matchAdd(
N, AM,
Depth))
2730 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2734 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2735 "Unexpected value size!");
2740 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2744 uint64_t
Mask =
N.getConstantOperandVal(1);
2769 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2777 if (
SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2779 AM.IndexReg =
Index;
2785 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2787 Mask = MaskC->getAPIntValue();
2788 Src = Src.getOperand(0);
2791 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2793 SDValue ShlSrc = Src.getOperand(0);
2794 SDValue ShlAmt = Src.getOperand(1);
2798 unsigned ShAmtV = ShAmtC->getZExtValue();
2806 if (!Src->getFlags().hasNoUnsignedWrap() &&
2807 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2815 MVT VT =
N.getSimpleValueType();
2819 if (!
Mask.isAllOnes()) {
2820 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2822 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2829 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2830 CurDAG->RemoveDeadNode(
N.getNode());
2833 AM.Scale = 1 << ShAmtV;
2837 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2841 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2844 Src.getOperand(0), AM))
2849 Src.getOperand(0), AM))
2854 Src.getOperand(0), AM, *Subtarget))
2862 return matchAddressBase(
N, AM);
2867bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2869 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
2882 AM.BaseType = X86ISelAddressMode::RegBase;
2887bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2888 X86ISelAddressMode &AM,
2891 dbgs() <<
"MatchVectorAddress: ";
2896 return matchAddressBase(
N, AM);
2899 switch (
N.getOpcode()) {
2902 if (!foldOffsetIntoAddress(Val, AM))
2907 if (!matchWrapper(
N, AM))
2913 HandleSDNode Handle(
N);
2915 X86ISelAddressMode Backup = AM;
2916 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2917 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2923 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2925 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2930 N = Handle.getValue();
2935 return matchAddressBase(
N, AM);
2941bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2942 return matchVectorAddressRecursively(
N, AM, 0);
2945bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
2950 X86ISelAddressMode AM;
2956 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2958 AM.IndexReg = IndexOp;
2962 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
2964 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
2966 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
2969 MVT VT =
BasePtr.getSimpleValueType();
2972 if (matchVectorAddress(BasePtr, AM))
2975 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
2989 X86ISelAddressMode AM;
3001 unsigned AddrSpace =
3004 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3006 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3008 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3013 MVT VT =
N.getSimpleValueType();
3015 if (matchAddress(
N, AM))
3018 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3034 N =
N.getOperand(0);
3051 return CR->getUnsignedMax().ult(1ull << 32);
3053 return !
TM.isLargeGlobalValue(GV);
3062 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3075 if (RN &&
RN->getReg() == 0)
3076 Base = CurDAG->getRegister(0, MVT::i64);
3086 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3088 if (RN &&
RN->getReg() == 0)
3089 Index = CurDAG->getRegister(0, MVT::i64);
3092 "Expect to be extending 8/16/32-bit registers for use in LEA");
3095 Index = CurDAG->getTargetInsertSubreg(
SubReg,
DL, MVT::i64, ImplDef, Index);
3103bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3107 X86ISelAddressMode AM;
3111 MVT VT =
N.getSimpleValueType();
3116 SDValue T = CurDAG->getRegister(0, MVT::i32);
3118 if (matchAddress(
N, AM))
3123 unsigned Complexity = 0;
3124 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3126 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3142 if (AM.hasSymbolicDisplacement()) {
3144 if (Subtarget->is64Bit())
3154 auto isMathWithFlags = [](
SDValue V) {
3155 switch (
V.getOpcode()) {
3169 return !
SDValue(
V.getNode(), 1).use_empty();
3176 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3184 if (Complexity <= 2)
3187 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3198 X86ISelAddressMode AM;
3200 AM.GV = GA->getGlobal();
3201 AM.Disp += GA->getOffset();
3202 AM.SymbolFlags = GA->getTargetFlags();
3205 AM.ES = SA->getSymbol();
3206 AM.SymbolFlags = SA->getTargetFlags();
3209 if (Subtarget->is32Bit()) {
3211 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3214 MVT VT =
N.getSimpleValueType();
3215 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3223 EVT VT =
N.getValueType();
3224 bool WasTruncated =
false;
3226 WasTruncated =
true;
3227 N =
N.getOperand(0);
3236 unsigned Opc =
N.getOperand(0)->getOpcode();
3238 Op =
N.getOperand(0);
3241 return !WasTruncated;
3246 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3247 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3251 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3252 GA->getOffset(), GA->getTargetFlags());
3256bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
3260 assert(Root &&
P &&
"Unknown root/parent nodes");
3262 !IsProfitableToFold(
N,
P, Root) ||
3263 !IsLegalToFold(
N,
P, Root, OptLevel))
3266 return selectAddr(
N.getNode(),
3267 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3270bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
3274 assert(Root &&
P &&
"Unknown root/parent nodes");
3276 !IsProfitableToFold(
N,
P, Root) ||
3277 !IsLegalToFold(
N,
P, Root, OptLevel))
3280 return selectAddr(
N.getNode(),
3281 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3287SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3290 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3293bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3295 N =
N->getOperand(0).getNode();
3303 auto *GV = GA->getGlobal();
3306 return CR->getSignedMin().sge(-1ull << Width) &&
3307 CR->getSignedMax().slt(1ull << Width);
3312 return Width == 32 && !
TM.isLargeGlobalValue(GV);
3316 assert(
N->isMachineOpcode() &&
"Unexpected node");
3317 unsigned Opc =
N->getMachineOpcode();
3318 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3323 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3328bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3330 for (SDUse &Use :
Flags->uses()) {
3332 if (
Use.getResNo() !=
Flags.getResNo())
3340 for (SDUse &FlagUse :
User->uses()) {
3342 if (FlagUse.getResNo() != 1)
3345 if (!FlagUse.getUser()->isMachineOpcode())
3365bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3367 for (SDUse &Use :
Flags->uses()) {
3369 if (
Use.getResNo() !=
Flags.getResNo())
3377 for (SDUse &FlagUse :
User->uses()) {
3379 if (FlagUse.getResNo() != 1)
3382 if (!FlagUse.getUser()->isMachineOpcode())
3422 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3424 for (SDUse &Use :
Flags->uses()) {
3426 if (
Use.getResNo() !=
Flags.getResNo())
3430 unsigned UserOpc =
User->getOpcode();
3437 for (SDUse &FlagUse :
User->uses()) {
3439 if (FlagUse.getResNo() != 1)
3442 if (!FlagUse.getUser()->isMachineOpcode())
3483 if (StoredVal.
getResNo() != 0)
return false;
3500 if (!Load.hasOneUse())
3508 bool FoundLoad =
false;
3512 const unsigned int Max = 1024;
3554 if (Chain == Load.getValue(1)) {
3560 if (
Op == Load.getValue(1)) {
3576 if (
Op.getNode() != LoadNode)
3608bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3610 SDValue StoredVal = StoreNode->getOperand(1);
3616 EVT MemVT = StoreNode->getMemoryVT();
3617 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3621 bool IsCommutable =
false;
3622 bool IsNegate =
false;
3636 IsCommutable =
true;
3640 unsigned LoadOpNo = IsNegate ? 1 : 0;
3641 LoadSDNode *LoadNode =
nullptr;
3644 LoadNode, InputChain)) {
3651 LoadNode, InputChain))
3656 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3660 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3681 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3684 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3691 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
3695 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3698 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
3699 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
3701 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3712 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
3715 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
3718 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
3721 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
3724 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
3727 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
3730 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
3732 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
3738 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
3741 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
3744 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
3747 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
3750 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
3753 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
3756 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
3759 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
3766 unsigned NewOpc = SelectRegOpcode(
Opc);
3772 int64_t OperandV = OperandC->getSExtValue();
3779 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
3781 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3782 OperandV = -OperandV;
3786 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
3787 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
3788 NewOpc = SelectImmOpcode(
Opc);
3794 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
3798 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
3799 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3803 Segment, Operand, InputChain};
3804 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3813 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
3815 CurDAG->setNodeMemRefs(Result, MemOps);
3821 CurDAG->RemoveDeadNode(Node);
3832bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
3836 "Should be either an and-mask, or right-shift after clearing high bits.");
3839 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
3842 MVT NVT =
Node->getSimpleValueType(0);
3845 if (NVT != MVT::i32 && NVT != MVT::i64)
3853 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
3854 auto checkUses = [AllowExtraUsesByDefault](
3856 std::optional<bool> AllowExtraUses) {
3857 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
3858 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
3860 auto checkOneUse = [checkUses](
SDValue Op,
3861 std::optional<bool> AllowExtraUses =
3863 return checkUses(
Op, 1, AllowExtraUses);
3865 auto checkTwoUse = [checkUses](
SDValue Op,
3866 std::optional<bool> AllowExtraUses =
3868 return checkUses(
Op, 2, AllowExtraUses);
3871 auto peekThroughOneUseTruncation = [checkOneUse](
SDValue V) {
3873 assert(
V.getSimpleValueType() == MVT::i32 &&
3874 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
3875 "Expected i64 -> i32 truncation");
3876 V =
V.getOperand(0);
3882 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
3885 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
3891 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3896 NBits =
M0->getOperand(1);
3897 NegateNBits =
false;
3901 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](
SDValue V) {
3902 V = peekThroughOneUseTruncation(V);
3903 return CurDAG->MaskedValueIsAllOnes(
3909 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
3912 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
3915 if (!isAllOnes(
Mask->getOperand(1)))
3918 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3922 if (!isAllOnes(
M0->getOperand(0)))
3924 NBits =
M0->getOperand(1);
3925 NegateNBits =
false;
3931 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](
SDValue ShiftAmt,
3932 unsigned Bitwidth) {
3937 NBits = NBits.getOperand(0);
3943 if (!V0 || V0->getZExtValue() != Bitwidth)
3945 NBits = NBits.getOperand(1);
3946 NegateNBits =
false;
3952 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
3955 Mask = peekThroughOneUseTruncation(Mask);
3956 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
3958 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
3965 if (!checkOneUse(
M1))
3967 canonicalizeShiftAmt(
M1, Bitwidth);
3972 return !NegateNBits;
3980 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
3981 AllowExtraUsesByDefault, &NegateNBits,
3982 &
X](SDNode *
Node) ->
bool {
3994 canonicalizeShiftAmt(N1, Bitwidth);
3998 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
3999 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4005 auto matchLowBitMask = [matchPatternA, matchPatternB,
4007 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4011 X =
Node->getOperand(0);
4014 if (matchLowBitMask(Mask)) {
4018 if (!matchLowBitMask(Mask))
4021 }
else if (matchLowBitMask(
SDValue(Node, 0))) {
4022 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4023 }
else if (!matchPatternD(Node))
4028 if (NegateNBits && !Subtarget->hasBMI2())
4040 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4043 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4045 NBits =
SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4046 MVT::i32, ImplDef, NBits, SRIdxVal),
4056 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4060 if (Subtarget->hasBMI2()) {
4062 if (NVT != MVT::i32) {
4069 ReplaceNode(Node, Extract.
getNode());
4070 SelectCode(Extract.
getNode());
4079 SDValue RealX = peekThroughOneUseTruncation(
X);
4085 MVT XVT =
X.getSimpleValueType();
4095 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4103 SDValue ShiftAmt =
X.getOperand(1);
4104 X =
X.getOperand(0);
4107 "Expected shift amount to be i8");
4111 SDValue OrigShiftAmt = ShiftAmt;
4116 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4121 if (XVT != MVT::i32) {
4135 ReplaceNode(Node, Extract.
getNode());
4136 SelectCode(Extract.
getNode());
4142MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4143 MVT NVT =
Node->getSimpleValueType(0);
4156 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4157 if (!PreferBEXTR && !Subtarget->hasBMI2())
4169 if (NVT != MVT::i32 && NVT != MVT::i64)
4175 if (!MaskCst || !ShiftCst)
4179 uint64_t
Mask = MaskCst->getZExtValue();
4183 uint64_t Shift = ShiftCst->getZExtValue();
4188 if (Shift == 8 && MaskSize == 8)
4199 if (!PreferBEXTR && MaskSize <= 32)
4203 unsigned ROpc, MOpc;
4205#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4207 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4211 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4216 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4217 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4223 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4224 if (Subtarget->hasTBM()) {
4225 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4226 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4228 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4234 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4235 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4239 MachineSDNode *NewNode;
4241 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4242 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4244 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4245 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4246 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4250 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4252 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4257 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4261 CurDAG->getMachineNode(NewOpc, dl, NVT,
SDValue(NewNode, 0), ShAmt);
4268MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4269 bool MayFoldLoad,
const SDLoc &dl,
4270 MVT VT, SDNode *Node) {
4275 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4278 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4279 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4282 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4283 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4292 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4293 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4300MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4301 bool MayFoldLoad,
const SDLoc &dl,
4302 MVT VT, SDNode *Node,
4308 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4311 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4312 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4315 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4316 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4326 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4327 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4332bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4333 EVT VT =
N->getValueType(0);
4340 unsigned Size = VT == MVT::i64 ? 64 : 32;
4343 SDValue ShiftAmt = OrigShiftAmt;
4362 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4366 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4367 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4371 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4380 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4381 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4387 Add0C->getZExtValue() != 0) {
4390 if (Add0C->getZExtValue() %
Size == 0)
4393 Add0C->getZExtValue() % 32 == 0) {
4401 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4405 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4427 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4434 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4435 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4439 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4441 if (UpdatedNode !=
N) {
4444 ReplaceNode(
N, UpdatedNode);
4451 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4459bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4460 MVT NVT =
N->getSimpleValueType(0);
4461 unsigned Opcode =
N->getOpcode();
4473 int64_t Val = Cst->getSExtValue();
4478 bool FoundAnyExtend =
false;
4482 FoundAnyExtend =
true;
4490 if (NVT != MVT::i32 && NVT != MVT::i64)
4497 uint64_t ShAmt = ShlCst->getZExtValue();
4501 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4502 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4507 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4511 ShiftedVal = (uint64_t)Val >> ShAmt;
4515 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4518 ShiftedVal = Val >> ShAmt;
4524 ShiftedVal = (uint64_t)Val >> ShAmt;
4532 if (!CanShrinkImmediate(ShiftedVal))
4542 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4548 NeededMask &= ~Cst->getAPIntValue();
4550 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4555 if (FoundAnyExtend) {
4561 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4563 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4572bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4573 SDNode *ParentB, SDNode *ParentC,
4576 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4577 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4579 auto tryFoldLoadOrBCast =
4582 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4586 if (
L.getOpcode() == ISD::BITCAST &&
L.hasOneUse()) {
4588 L =
L.getOperand(0);
4596 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4600 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4603 bool FoldedLoad =
false;
4604 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4605 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4607 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4612 uint8_t OldImm =
Imm;
4613 Imm = OldImm & 0xa5;
4614 if (OldImm & 0x02)
Imm |= 0x10;
4615 if (OldImm & 0x10)
Imm |= 0x02;
4616 if (OldImm & 0x08)
Imm |= 0x40;
4617 if (OldImm & 0x40)
Imm |= 0x08;
4618 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4623 uint8_t OldImm =
Imm;
4624 Imm = OldImm & 0x99;
4625 if (OldImm & 0x02)
Imm |= 0x04;
4626 if (OldImm & 0x04)
Imm |= 0x02;
4627 if (OldImm & 0x20)
Imm |= 0x40;
4628 if (OldImm & 0x40)
Imm |= 0x20;
4633 SDValue TImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
4637 MachineSDNode *MNode;
4639 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4644 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4645 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4647 bool UseD = EltSize == 32;
4649 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4651 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4653 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4659 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4661 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4663 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4669 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
4672 ReplaceUses(
C.getValue(1),
SDValue(MNode, 1));
4679 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
4681 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
4683 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
4687 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
4691 CurDAG->RemoveDeadNode(Root);
4697bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
4698 MVT NVT =
N->getSimpleValueType(0);
4701 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
4709 auto getFoldableLogicOp = [](
SDValue Op) {
4711 if (
Op.getOpcode() == ISD::BITCAST &&
Op.hasOneUse())
4712 Op =
Op.getOperand(0);
4714 if (!
Op.hasOneUse())
4717 unsigned Opc =
Op.getOpcode();
4728 auto tryPeelOuterNotWrappingLogic = [&](SDNode *
Op) {
4733 if (!getFoldableLogicOp(InnerOp))
4738 if ((FoldableOp = getFoldableLogicOp(N1))) {
4742 if ((FoldableOp = getFoldableLogicOp(N0))) {
4750 bool PeeledOuterNot =
false;
4752 if (
SDValue InnerOp = tryPeelOuterNotWrappingLogic(
N)) {
4753 PeeledOuterNot =
true;
4759 if ((FoldableOp = getFoldableLogicOp(N1)))
4761 else if ((FoldableOp = getFoldableLogicOp(N0)))
4769 SDNode *ParentA =
N;
4770 SDNode *ParentB = FoldableOp.
getNode();
4771 SDNode *ParentC = FoldableOp.
getNode();
4775 uint8_t TernlogMagicA = 0xf0;
4776 uint8_t TernlogMagicB = 0xcc;
4777 uint8_t TernlogMagicC = 0xaa;
4782 auto PeekThroughNot = [](
SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
4786 Parent =
Op.getNode();
4787 Op =
Op.getOperand(0);
4791 PeekThroughNot(
A, ParentA, TernlogMagicA);
4792 PeekThroughNot(
B, ParentB, TernlogMagicB);
4793 PeekThroughNot(
C, ParentC, TernlogMagicC);
4798 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
4799 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
4800 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
4804 switch (
N->getOpcode()) {
4808 Imm &= ~TernlogMagicA;
4810 Imm = ~(
Imm) & TernlogMagicA;
4820 return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC,
A,
B,
C, Imm);
4830bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
4833 MVT VT =
And->getSimpleValueType(0);
4834 if (VT != MVT::i32 && VT != MVT::i64)
4846 APInt MaskVal = And1C->getAPIntValue();
4848 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
4852 if (VT == MVT::i64 && MaskLZ >= 32) {
4854 MaskVal = MaskVal.
trunc(32);
4859 APInt NegMaskVal = MaskVal | HighZeros;
4868 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
4869 NegMaskVal = NegMaskVal.
zext(64);
4870 HighZeros = HighZeros.
zext(64);
4876 KnownBits Known0 = CurDAG->computeKnownBits(And0);
4888 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
4897 bool FoldedBCast,
bool Masked) {
4898#define VPTESTM_CASE(VT, SUFFIX) \
4901 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
4902 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
4905#define VPTESTM_BROADCAST_CASES(SUFFIX) \
4906default: llvm_unreachable("Unexpected VT!"); \
4907VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
4908VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
4909VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
4910VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
4911VPTESTM_CASE(v16i32, DZ##SUFFIX) \
4912VPTESTM_CASE(v8i64, QZ##SUFFIX)
4914#define VPTESTM_FULL_CASES(SUFFIX) \
4915VPTESTM_BROADCAST_CASES(SUFFIX) \
4916VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
4917VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
4918VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
4919VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
4920VPTESTM_CASE(v64i8, BZ##SUFFIX) \
4921VPTESTM_CASE(v32i16, WZ##SUFFIX)
4939#undef VPTESTM_FULL_CASES
4940#undef VPTESTM_BROADCAST_CASES
4946bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root,
SDValue Setcc,
4948 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
4993 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P,
SDValue &
L,
4998 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
5003 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
5007 if (
L.getOpcode() == ISD::BITCAST &&
L.hasOneUse()) {
5009 L =
L.getOperand(0);
5016 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5019 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5023 bool CanFoldLoads = Src0 != Src1;
5025 bool FoldedLoad =
false;
5026 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5028 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5032 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5041 bool IsMasked = InMask.
getNode() !=
nullptr;
5054 SDValue ImplDef =
SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5056 Src0 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src0);
5059 Src1 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src1);
5064 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5065 InMask =
SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5066 dl, MaskVT, InMask, RC), 0);
5074 MachineSDNode *CNode;
5076 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5079 SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5081 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5083 SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5085 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5091 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5094 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5096 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5102 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5103 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5104 dl, ResVT,
SDValue(CNode, 0), RC);
5108 CurDAG->RemoveDeadNode(Root);
5114bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5117 MVT NVT =
N->getSimpleValueType(0);
5120 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5154 SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5162void X86DAGToDAGISel::Select(SDNode *Node) {
5163 MVT NVT =
Node->getSimpleValueType(0);
5164 unsigned Opcode =
Node->getOpcode();
5167 if (
Node->isMachineOpcode()) {
5169 Node->setNodeId(-1);
5176 unsigned IntNo =
Node->getConstantOperandVal(1);
5179 case Intrinsic::x86_encodekey128:
5180 case Intrinsic::x86_encodekey256: {
5181 if (!Subtarget->hasKL())
5187 case Intrinsic::x86_encodekey128:
5188 Opcode = X86::ENCODEKEY128;
5190 case Intrinsic::x86_encodekey256:
5191 Opcode = X86::ENCODEKEY256;
5196 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5198 if (Opcode == X86::ENCODEKEY256)
5199 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5202 MachineSDNode *Res = CurDAG->getMachineNode(
5203 Opcode, dl,
Node->getVTList(),
5204 {Node->getOperand(2), Chain, Chain.getValue(1)});
5205 ReplaceNode(Node, Res);
5208 case Intrinsic::x86_tileloaddrs64_internal:
5209 case Intrinsic::x86_tileloaddrst164_internal:
5210 if (!Subtarget->hasAMXMOVRS())
5213 case Intrinsic::x86_tileloadd64_internal:
5214 case Intrinsic::x86_tileloaddt164_internal: {
5215 if (!Subtarget->hasAMXTILE())
5218 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5219 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5224 case Intrinsic::x86_tileloaddrs64_internal:
5225 Opc = X86::PTILELOADDRSV;
5227 case Intrinsic::x86_tileloaddrst164_internal:
5228 Opc = X86::PTILELOADDRST1V;
5230 case Intrinsic::x86_tileloadd64_internal:
5231 Opc = X86::PTILELOADDV;
5233 case Intrinsic::x86_tileloaddt164_internal:
5234 Opc = X86::PTILELOADDT1V;
5239 SDValue Scale = getI8Imm(1, dl);
5241 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5242 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5244 MachineSDNode *CNode;
5246 Node->getOperand(3),
5253 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5254 ReplaceNode(Node, CNode);
5261 unsigned IntNo =
Node->getConstantOperandVal(1);
5264 case Intrinsic::x86_sse3_monitor:
5265 case Intrinsic::x86_monitorx:
5266 case Intrinsic::x86_clzero: {
5267 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5272 case Intrinsic::x86_sse3_monitor:
5273 if (!Subtarget->hasSSE3())
5275 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5277 case Intrinsic::x86_monitorx:
5278 if (!Subtarget->hasMWAITX())
5280 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5282 case Intrinsic::x86_clzero:
5283 if (!Subtarget->hasCLZERO())
5285 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5290 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5291 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5295 if (IntNo == Intrinsic::x86_sse3_monitor ||
5296 IntNo == Intrinsic::x86_monitorx) {
5298 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5301 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5306 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5308 ReplaceNode(Node, CNode);
5314 case Intrinsic::x86_tilestored64_internal: {
5316 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5317 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5318 unsigned Opc = X86::PTILESTOREDV;
5321 SDValue Scale = getI8Imm(1, dl);
5323 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5324 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5326 MachineSDNode *CNode;
5328 Node->getOperand(3),
5334 Node->getOperand(6),
5336 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5337 ReplaceNode(Node, CNode);
5340 case Intrinsic::x86_tileloaddrs64:
5341 case Intrinsic::x86_tileloaddrst164:
5342 if (!Subtarget->hasAMXMOVRS())
5345 case Intrinsic::x86_tileloadd64:
5346 case Intrinsic::x86_tileloaddt164:
5347 case Intrinsic::x86_tilestored64: {
5348 if (!Subtarget->hasAMXTILE())
5351 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5352 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5356 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5357 case Intrinsic::x86_tileloaddrs64:
5358 Opc = X86::PTILELOADDRS;
5360 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5361 case Intrinsic::x86_tileloaddrst164:
5362 Opc = X86::PTILELOADDRST1;
5364 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5367 unsigned TIndex =
Node->getConstantOperandVal(2);
5370 SDValue Scale = getI8Imm(1, dl);
5372 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5373 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5375 MachineSDNode *CNode;
5376 if (
Opc == X86::PTILESTORED) {
5378 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5381 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5383 ReplaceNode(Node, CNode);
5391 if (Subtarget->isTarget64BitILP32()) {
5396 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5397 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5398 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5399 Node->getOperand(0), ZextTarget);
5400 ReplaceNode(Node, Brind.
getNode());
5401 SelectCode(ZextTarget.
getNode());
5408 ReplaceNode(Node, getGlobalBaseReg());
5415 ReplaceUses(
SDValue(Node, 0),
Node->getOperand(0));
5416 CurDAG->RemoveDeadNode(Node);
5422 if (matchBitExtract(Node))
5427 if (tryShiftAmountMod(Node))
5432 uint8_t
Imm =
Node->getConstantOperandVal(3);
5433 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5434 Node->getOperand(1),
Node->getOperand(2), Imm))
5440 if (tryVPTERNLOG(Node))
5450 tryVPTESTM(Node, N0, N1))
5453 tryVPTESTM(Node, N1, N0))
5457 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5459 CurDAG->RemoveDeadNode(Node);
5462 if (matchBitExtract(Node))
5470 if (tryShrinkShlLogicImm(Node))
5472 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5474 if (tryVPTERNLOG(Node))
5479 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5489 if (!CurDAG->shouldOptForSize())
5493 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5503 int64_t Val = Cst->getSExtValue();
5511 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5515 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5519 unsigned ROpc, MOpc;
5628 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5629 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5631 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5632 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5638 CurDAG->RemoveDeadNode(Node);
5643 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
5656 unsigned LoReg, ROpc, MOpc;
5661 ROpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
5662 MOpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
5681 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5682 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5685 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5690 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5693 MachineSDNode *CNode;
5699 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5701 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
5705 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5716 VTs = CurDAG->getVTList(NVT, MVT::i32);
5718 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
5720 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
5724 ReplaceUses(
SDValue(Node, 1),
SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
5725 CurDAG->RemoveDeadNode(Node);
5735 unsigned LoReg, HiReg;
5737 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
5738 bool UseMULXHi = UseMULX &&
SDValue(Node, 0).use_empty();
5742 Opc = UseMULXHi ? X86::MULX32Hrr
5744 : IsSigned ?
X86::IMUL32r
5746 MOpc = UseMULXHi ? X86::MULX32Hrm
5748 : IsSigned ?
X86::IMUL32m
5750 LoReg = UseMULX ? X86::EDX : X86::EAX;
5754 Opc = UseMULXHi ? X86::MULX64Hrr
5756 : IsSigned ?
X86::IMUL64r
5758 MOpc = UseMULXHi ? X86::MULX64Hrm
5760 : IsSigned ?
X86::IMUL64m
5762 LoReg = UseMULX ? X86::RDX : X86::RAX;
5767 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5768 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5771 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5776 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5781 MachineSDNode *CNode =
nullptr;
5785 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5786 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5789 }
else if (UseMULX) {
5790 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
5791 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5796 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5797 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5803 ReplaceUses(N1.
getValue(1), Chain);
5809 SDVTList VTs = CurDAG->getVTList(NVT);
5810 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5812 }
else if (UseMULX) {
5813 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
5814 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5818 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
5819 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5825 if (!
SDValue(Node, 0).use_empty()) {
5827 assert(LoReg &&
"Register for low half is not defined!");
5828 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
5832 ReplaceUses(
SDValue(Node, 0), ResLo);
5837 if (!
SDValue(Node, 1).use_empty()) {
5839 assert(HiReg &&
"Register for high half is not defined!");
5840 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
5844 ReplaceUses(
SDValue(Node, 1), ResHi);
5849 CurDAG->RemoveDeadNode(Node);
5858 unsigned ROpc, MOpc;
5863 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
5864 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
5865 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
5866 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
5871 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
5872 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
5873 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
5874 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
5878 unsigned LoReg, HiReg, ClrReg;
5879 unsigned SExtOpcode;
5883 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
5887 LoReg = X86::AX; HiReg = X86::DX;
5889 SExtOpcode = X86::CWD;
5892 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
5893 SExtOpcode = X86::CDQ;
5896 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
5897 SExtOpcode = X86::CQO;
5901 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5902 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5903 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
5906 if (NVT == MVT::i8) {
5909 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
5910 MachineSDNode *Move;
5911 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5913 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rm8
5915 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
5917 ReplaceUses(N0.
getValue(1), Chain);
5921 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rr8
5923 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
5924 Chain = CurDAG->getEntryNode();
5926 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX,
SDValue(Move, 0),
5931 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
5932 LoReg, N0,
SDValue()).getValue(1);
5936 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
5939 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
5941 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
5945 SDValue(CurDAG->getMachineNode(
5946 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
5947 CurDAG->getTargetConstant(X86::sub_16bit, dl,
5955 SDValue(CurDAG->getMachineNode(
5956 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
5957 CurDAG->getTargetConstant(0, dl, MVT::i64), ClrNode,
5958 CurDAG->getTargetConstant(X86::sub_32bit, dl,
5966 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
5967 ClrNode, InGlue).getValue(1);
5974 MachineSDNode *CNode =
5975 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
5983 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
5993 if (HiReg == X86::AH && !
SDValue(Node, 1).use_empty()) {
5994 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
5995 unsigned AHExtOpcode =
5996 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
5998 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
5999 MVT::Glue, AHCopy, InGlue);
6004 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6006 ReplaceUses(
SDValue(Node, 1), Result);
6011 if (!
SDValue(Node, 0).use_empty()) {
6012 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6013 LoReg, NVT, InGlue);
6014 InGlue =
Result.getValue(2);
6015 ReplaceUses(
SDValue(Node, 0), Result);
6020 if (!
SDValue(Node, 1).use_empty()) {
6021 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6022 HiReg, NVT, InGlue);
6023 InGlue =
Result.getValue(2);
6024 ReplaceUses(
SDValue(Node, 1), Result);
6028 CurDAG->RemoveDeadNode(Node);
6037 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6038 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6044 if (Subtarget->canUseCMOV())
6053 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6056 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6059 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6064 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6067 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6068 Chain =
SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6071 Glue =
SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6076 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6080 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6084 assert(Subtarget->canUseLAHFSAHF() &&
6085 "Target doesn't support SAHF or FCOMI?");
6086 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract,
SDValue());
6089 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6092 ReplaceUses(
SDValue(Node, 1), Chain);
6094 ReplaceUses(
SDValue(Node, 0), SAHF);
6095 CurDAG->RemoveDeadNode(Node);
6115 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6116 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6119 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6121 CurDAG->RemoveDeadNode(Node);
6141 uint64_t
Mask = MaskC->getZExtValue();
6148 onlyUsesZeroFlag(
SDValue(Node, 0))) {
6153 unsigned TestOpcode;
6161 if (LeadingZeros == 0 && SavesBytes) {
6166 ShiftAmt = TrailingZeros;
6168 TestOpcode = X86::TEST64rr;
6169 }
else if (TrailingZeros == 0 && SavesBytes) {
6174 ShiftAmt = LeadingZeros;
6176 TestOpcode = X86::TEST64rr;
6177 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6180 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6181 if (PopCount == 8) {
6183 ShiftAmt = TrailingZeros;
6184 SubRegIdx = X86::sub_8bit;
6186 TestOpcode = X86::TEST8rr;
6187 }
else if (PopCount == 16) {
6189 ShiftAmt = TrailingZeros;
6190 SubRegIdx = X86::sub_16bit;
6191 SubRegVT = MVT::i16;
6192 TestOpcode = X86::TEST16rr;
6193 }
else if (PopCount == 32) {
6195 ShiftAmt = TrailingZeros;
6196 SubRegIdx = X86::sub_32bit;
6197 SubRegVT = MVT::i32;
6198 TestOpcode = X86::TEST32rr;
6202 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6204 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6207 if (SubRegIdx != 0) {
6209 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6211 MachineSDNode *
Test =
6212 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6213 ReplaceNode(Node,
Test);
6220 unsigned ROpc, MOpc;
6228 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6229 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6232 SubRegOp = X86::sub_8bit;
6233 ROpc = X86::TEST8ri;
6234 MOpc = X86::TEST8mi;
6235 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6236 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6237 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6243 SubRegOp = X86::sub_16bit;
6244 ROpc = X86::TEST16ri;
6245 MOpc = X86::TEST16mi;
6247 ((!(Mask & 0x80000000) &&
6250 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6251 CmpVT == MVT::i32 ||
6252 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6259 SubRegOp = X86::sub_32bit;
6260 ROpc = X86::TEST32ri;
6261 MOpc = X86::TEST32mi;
6267 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6271 MachineSDNode *NewNode;
6272 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6273 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6275 if (!LoadN->isSimple()) {
6276 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6277 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6278 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6279 (MOpc == X86::TEST32mi && NumVolBits != 32))
6284 Reg.getOperand(0) };
6285 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6287 ReplaceUses(
Reg.getValue(1),
SDValue(NewNode, 1));
6289 CurDAG->setNodeMemRefs(NewNode,
6294 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6296 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg, Imm);
6299 ReplaceNode(Node, NewNode);
6305 if (!Subtarget->hasSSE42())
6308 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6309 bool NeedMask = !
SDValue(Node, 1).use_empty();
6311 bool MayFoldLoad = !NeedIndex || !NeedMask;
6313 MachineSDNode *CNode;
6316 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6318 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6319 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6322 if (NeedIndex || !NeedMask) {
6324 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6326 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6327 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6333 CurDAG->RemoveDeadNode(Node);
6337 if (!Subtarget->hasSSE42())
6341 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6342 Node->getOperand(1),
6344 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6345 Node->getOperand(3), InGlue).getValue(1);
6347 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6348 bool NeedMask = !
SDValue(Node, 1).use_empty();
6350 bool MayFoldLoad = !NeedIndex || !NeedMask;
6352 MachineSDNode *CNode;
6355 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6357 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6359 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6362 if (NeedIndex || !NeedMask) {
6364 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6366 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6367 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6372 CurDAG->RemoveDeadNode(Node);
6384 if (foldLoadStoreIntoMemOperand(Node))
6389 MVT VT =
Node->getSimpleValueType(0);
6391 if (Subtarget->hasSBBDepBreaking()) {
6396 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6401 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6402 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6404 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6409 Result = getSBBZero(Node);
6413 if (VT == MVT::i8 || VT == MVT::i16) {
6414 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6415 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6418 ReplaceUses(
SDValue(Node, 0), Result);
6419 CurDAG->RemoveDeadNode(Node);
6431 if (!
SDValue(Node, 0).use_empty()) {
6433 MVT VT =
Node->getSimpleValueType(0);
6434 if (VT == MVT::i8 || VT == MVT::i16) {
6435 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6436 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6438 ReplaceUses(
SDValue(Node, 0), Result);
6441 CurDAG->RemoveDeadNode(Node);
6448 SDValue IndexOp = Mgt->getIndex();
6451 MVT ValueVT =
Node->getSimpleValueType(0);
6452 MVT MaskVT =
Mask.getSimpleValueType();
6469 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6470 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6471 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6472 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6473 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6474 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6475 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6476 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6477 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6478 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6479 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6480 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6481 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6482 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6483 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6484 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6485 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6486 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6487 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6488 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6489 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6490 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6491 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6492 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6494 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6495 "Unexpected mask VT!");
6496 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6497 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6498 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6499 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6500 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6501 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6502 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6503 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6504 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6505 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6506 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6507 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6508 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6509 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6510 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6511 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6518 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6519 Base, Scale, Index, Disp, Segment))
6522 SDValue PassThru = Mgt->getPassThru();
6523 SDValue Chain = Mgt->getChain();
6525 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6527 MachineSDNode *NewNode;
6530 Index, Disp, Segment, Chain};
6531 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6534 Disp, Segment,
Mask, Chain};
6535 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6537 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6540 CurDAG->RemoveDeadNode(Node);
6546 SDValue IndexOp = Sc->getIndex();
6548 MVT ValueVT =
Value.getSimpleValueType();
6563 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6564 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6565 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6566 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6567 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6568 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6569 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6570 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6571 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6572 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6573 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6574 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6575 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6576 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6577 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6578 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6579 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6580 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6581 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6582 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6583 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6584 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6585 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6586 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6591 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6592 Base, Scale, Index, Disp, Segment))
6596 SDValue Chain = Sc->getChain();
6598 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6601 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6602 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6604 CurDAG->RemoveDeadNode(Node);
6607 case ISD::PREALLOCATED_SETUP: {
6608 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6609 auto CallId = MFI->getPreallocatedIdForCallSite(
6612 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6613 MachineSDNode *
New = CurDAG->getMachineNode(
6614 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6616 CurDAG->RemoveDeadNode(Node);
6619 case ISD::PREALLOCATED_ARG: {
6620 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6624 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6627 Ops[0] = CallIdValue;
6630 MachineSDNode *
New = CurDAG->getMachineNode(
6631 TargetOpcode::PREALLOCATED_ARG, dl,
6632 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
6637 CurDAG->RemoveDeadNode(Node);
6644 if (!Subtarget->hasWIDEKL())
6648 switch (
Node->getOpcode()) {
6652 Opcode = X86::AESENCWIDE128KL;
6655 Opcode = X86::AESDECWIDE128KL;
6658 Opcode = X86::AESENCWIDE256KL;
6661 Opcode = X86::AESDECWIDE256KL;
6669 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
6672 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
6674 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
6676 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
6678 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
6680 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
6682 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
6684 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
6686 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
6689 MachineSDNode *Res = CurDAG->getMachineNode(
6690 Opcode, dl,
Node->getVTList(),
6691 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
6693 ReplaceNode(Node, Res);
6700 if (
Node->getNumValues() == 3)
6701 Glue =
Node->getOperand(2);
6703 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
6704 ReplaceNode(Node,
Copy.getNode());
6712bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
6714 std::vector<SDValue> &OutOps) {
6715 SDValue Op0, Op1, Op2, Op3, Op4;
6716 switch (ConstraintID) {
6719 case InlineAsm::ConstraintCode::o:
6720 case InlineAsm::ConstraintCode::v:
6721 case InlineAsm::ConstraintCode::m:
6722 case InlineAsm::ConstraintCode::X:
6723 case InlineAsm::ConstraintCode::p:
6724 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
6729 OutOps.push_back(Op0);
6730 OutOps.push_back(Op1);
6731 OutOps.push_back(Op2);
6732 OutOps.push_back(Op3);
6733 OutOps.push_back(Op4);
6739 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
6745 return new X86DAGToDAGISelLegacy(TM, OptLevel);
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
#define CASE(ATTRNAME, AANAME,...)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isSigned(unsigned int Opcode)
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
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).
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 a 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.
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 getID() const
Return the register class ID number.
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.
@ 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.
@ 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...
@ 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...
@ 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.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
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)
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.
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