22#include "llvm/Config/llvm-config.h"
27#include "llvm/IR/IntrinsicsX86.h"
38#define DEBUG_TYPE "x86-isel"
39#define PASS_NAME "X86 DAG->DAG Instruction Selection"
41STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
44 cl::desc(
"Enable setting constant bits to reduce size of mask immediates"),
48 "x86-promote-anyext-load",
cl::init(
true),
60 struct X86ISelAddressMode {
68 int Base_FrameIndex = 0;
74 const GlobalValue *GV =
nullptr;
77 const char *ES =
nullptr;
82 bool NegateIndex =
false;
84 X86ISelAddressMode() =
default;
86 bool hasSymbolicDisplacement()
const {
87 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr ||
88 MCSym !=
nullptr || JT != -1 || BlockAddr !=
nullptr;
91 bool hasBaseOrIndexReg()
const {
92 return BaseType == FrameIndexBase ||
93 IndexReg.getNode() !=
nullptr || Base_Reg.getNode() !=
nullptr;
98 if (BaseType != RegBase)
return false;
99 if (RegisterSDNode *RegNode =
101 return RegNode->getReg() == X86::RIP;
110#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
111 void dump(SelectionDAG *DAG =
nullptr) {
112 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
113 dbgs() <<
"Base_Reg ";
114 if (Base_Reg.getNode())
115 Base_Reg.getNode()->dump(DAG);
118 if (BaseType == FrameIndexBase)
119 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
120 dbgs() <<
" Scale " << Scale <<
'\n'
124 if (IndexReg.getNode())
125 IndexReg.getNode()->dump(DAG);
128 dbgs() <<
" Disp " << Disp <<
'\n'
150 dbgs() <<
" JT" << JT <<
" Align" << Alignment.value() <<
'\n';
164 const X86Subtarget *Subtarget;
170 bool IndirectTlsSegRefs;
173 X86DAGToDAGISel() =
delete;
175 explicit X86DAGToDAGISel(X86TargetMachine &tm,
CodeGenOptLevel OptLevel)
176 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr),
177 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
179 bool runOnMachineFunction(MachineFunction &MF)
override {
183 "indirect-tls-seg-refs");
190 void emitFunctionEntryCode()
override;
192 bool IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const override;
194 void PreprocessISelDAG()
override;
195 void PostprocessISelDAG()
override;
198#include "X86GenDAGISel.inc"
201 void Select(SDNode *
N)
override;
203 bool foldOffsetIntoAddress(uint64_t
Offset, X86ISelAddressMode &AM);
204 bool matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
205 bool AllowSegmentRegForX32 =
false);
206 bool matchWrapper(
SDValue N, X86ISelAddressMode &AM);
207 bool matchAddress(
SDValue N, X86ISelAddressMode &AM);
208 bool matchVectorAddress(
SDValue N, X86ISelAddressMode &AM);
209 bool matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
212 bool matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
214 bool matchVectorAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
216 bool matchAddressBase(
SDValue N, X86ISelAddressMode &AM);
220 bool selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
SDValue IndexOp,
234 bool tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
244 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
247 bool tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
252 bool isProfitableToFormMaskedOp(SDNode *
N)
const;
255 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
257 std::vector<SDValue> &OutOps)
override;
259 void emitSpecialCodeForMain();
261 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
265 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
266 Base = CurDAG->getTargetFrameIndex(
267 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
268 else if (AM.Base_Reg.
getNode())
271 Base = CurDAG->getRegister(0, VT);
273 Scale = getI8Imm(AM.Scale,
DL);
275#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
277 if (AM.NegateIndex) {
303 Index = CurDAG->getRegister(0, VT);
308 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(),
312 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
313 AM.Disp, AM.SymbolFlags);
315 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
316 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
317 }
else if (AM.MCSym) {
318 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
319 assert(AM.SymbolFlags == 0 &&
"oo");
320 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
321 }
else if (AM.JT != -1) {
322 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
323 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
324 }
else if (AM.BlockAddr)
325 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
328 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
331 Segment = AM.Segment;
333 Segment = CurDAG->getRegister(0, MVT::i16);
338 bool isAMXSDNode(SDNode *
N)
const {
342 for (
unsigned Idx = 0,
E =
N->getNumValues(); Idx !=
E; ++Idx) {
343 if (
N->getValueType(Idx) == MVT::x86amx)
346 for (
unsigned Idx = 0,
E =
N->getNumOperands(); Idx !=
E; ++Idx) {
348 if (
Op.getValueType() == MVT::x86amx)
360 bool shouldAvoidImmediateInstFormsForSize(SDNode *
N)
const {
361 uint32_t UseCount = 0;
366 if (!CurDAG->shouldOptForSize())
370 for (
const SDNode *User :
N->users()) {
376 if (
User->isMachineOpcode()) {
383 User->getOperand(1).getNode() ==
N) {
394 if (
User->getNumOperands() != 2)
415 OtherOp =
User->getOperand(1);
418 RegisterSDNode *RegNode;
422 if ((RegNode->
getReg() == X86::ESP) ||
423 (RegNode->
getReg() == X86::RSP))
432 return (UseCount > 1);
436 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &
DL) {
437 return CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
441 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &
DL) {
442 return CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
446 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &
DL) {
447 return CurDAG->getTargetConstant(Imm,
DL, MVT::i64);
450 SDValue getExtractVEXTRACTImmediate(SDNode *
N,
unsigned VecWidth,
452 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
453 uint64_t
Index =
N->getConstantOperandVal(1);
454 MVT VecVT =
N->getOperand(0).getSimpleValueType();
458 SDValue getInsertVINSERTImmediate(SDNode *
N,
unsigned VecWidth,
460 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
461 uint64_t
Index =
N->getConstantOperandVal(2);
462 MVT VecVT =
N->getSimpleValueType(0);
466 SDValue getPermuteVINSERTCommutedImmediate(SDNode *
N,
unsigned VecWidth,
468 assert(VecWidth == 128 &&
"Unexpected vector width");
469 uint64_t
Index =
N->getConstantOperandVal(2);
470 MVT VecVT =
N->getSimpleValueType(0);
472 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
475 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
480 MVT VT =
N->getSimpleValueType(0);
483 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
485 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
486 if (VT == MVT::i64) {
488 CurDAG->getMachineNode(
489 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
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)
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())
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()) {
1013 MVT VT =
N->getSimpleValueType(0);
1021 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1023 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1030 switch (
N->getOpcode()) {
1032 MVT VT =
N->getSimpleValueType(0);
1034 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1041 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1044 CurDAG->getIntPtrConstant(Index, dl));
1047 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1056 MVT VT =
N->getSimpleValueType(0);
1058 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1062 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1063 SDValue Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1064 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1066 MemNode->getMemOperand());
1069 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1072 CurDAG->getIntPtrConstant(Index, dl));
1076 CurDAG->ReplaceAllUsesWith(
N, To);
1088 MVT VT =
N->getSimpleValueType(0);
1094 SDNode *MaxLd =
nullptr;
1095 SDValue Ptr = Ld->getBasePtr();
1096 SDValue Chain = Ld->getChain();
1097 for (SDNode *User : Ptr->
users()) {
1099 MVT UserVT =
User->getSimpleValueType(0);
1101 UserLd->getBasePtr() == Ptr && UserLd->getChain() == Chain &&
1102 !
User->hasAnyUseOfValue(1) &&
1116 CurDAG->getIntPtrConstant(0, dl));
1117 SDValue Res = CurDAG->getBitcast(VT, Extract);
1121 CurDAG->ReplaceAllUsesWith(
N, To);
1130 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1131 if (EleVT == MVT::i1)
1134 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1135 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1136 "We can't replace VSELECT with BLENDV in vXi16!");
1138 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1141 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1142 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1145 N->getOperand(0),
N->getOperand(1),
1149 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1162 if (!
N->getSimpleValueType(0).isVector())
1166 switch (
N->getOpcode()) {
1176 if (
N->isStrictFPOpcode())
1178 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1179 {
N->getOperand(0),
N->getOperand(1)});
1182 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1185 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1195 if (!
N->getValueType(0).isVector())
1199 switch (
N->getOpcode()) {
1205 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1206 N->getOperand(0),
N->getOperand(1));
1208 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1217 if (!
N->getValueType(0).isVector())
1221 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1223 "Unexpected opcode for mask vector!");
1231 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1234 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1254 switch (
N->getOpcode()) {
1270 bool IsStrict =
N->isStrictFPOpcode();
1274 {
N->getValueType(0), MVT::Other},
1275 {
N->getOperand(0),
N->getOperand(1),
1276 CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
1280 CurDAG->getTargetConstant(Imm, dl, MVT::i32));
1282 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1293 MVT VT =
N->getSimpleValueType(0);
1294 if (VT.
isVector() || VT == MVT::f128)
1297 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1298 : VT == MVT::f32 ? MVT::v4f32
1308 if (Subtarget->hasSSE2()) {
1309 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1313 switch (
N->getOpcode()) {
1320 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1323 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1326 CurDAG->getIntPtrConstant(0, dl));
1328 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1335 if (OptLevel != CodeGenOptLevel::None &&
1338 !Subtarget->useIndirectThunkCalls() &&
1339 ((
N->getOpcode() ==
X86ISD::CALL && !Subtarget->slowTwoMemOps()) ||
1341 (Subtarget->is64Bit() ||
1342 !getTargetMachine().isPositionIndependent())))) {
1381 switch (
N->getOpcode()) {
1386 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1387 MVT DstVT =
N->getSimpleValueType(0);
1395 const X86TargetLowering *X86Lowering =
1396 static_cast<const X86TargetLowering *
>(TLI);
1399 if (SrcIsSSE && DstIsSSE)
1402 if (!SrcIsSSE && !DstIsSSE) {
1407 if (
N->getConstantOperandVal(1))
1415 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1417 MachinePointerInfo MPI =
1424 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1426 MemTmp, MPI, MemVT);
1433 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1442 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1443 MVT DstVT =
N->getSimpleValueType(0);
1451 const X86TargetLowering *X86Lowering =
1452 static_cast<const X86TargetLowering *
>(TLI);
1455 if (SrcIsSSE && DstIsSSE)
1458 if (!SrcIsSSE && !DstIsSSE) {
1463 if (
N->getConstantOperandVal(2))
1471 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1473 MachinePointerInfo MPI =
1482 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1483 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1487 if (
N->getFlags().hasNoFPExcept()) {
1489 Flags.setNoFPExcept(
true);
1490 Store->setFlags(Flags);
1493 assert(SrcVT == MemVT &&
"Unexpected VT!");
1494 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1499 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1501 Result = CurDAG->getMemIntrinsicNode(
1504 if (
N->getFlags().hasNoFPExcept()) {
1506 Flags.setNoFPExcept(
true);
1510 assert(DstVT == MemVT &&
"Unexpected VT!");
1511 Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
1519 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1533 CurDAG->RemoveDeadNodes();
1537bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1538 unsigned Opc =
N->getMachineOpcode();
1539 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1540 Opc != X86::MOVSX64rr8)
1552 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1553 : X86::MOVSX32rr8_NOREX;
1558 if (
Opc == X86::MOVSX64rr8) {
1561 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1563 ReplaceUses(
N, Extend);
1572void X86DAGToDAGISel::PostprocessISelDAG() {
1574 if (TM.getOptLevel() == CodeGenOptLevel::None)
1579 bool MadeChange =
false;
1580 while (Position != CurDAG->allnodes_begin()) {
1581 SDNode *
N = &*--Position;
1583 if (
N->use_empty() || !
N->isMachineOpcode())
1586 if (tryOptimizeRem8Extend(
N)) {
1591 unsigned Opc =
N->getMachineOpcode();
1602 case X86::CTEST16rr:
1603 case X86::CTEST32rr:
1604 case X86::CTEST64rr: {
1610#define CASE_ND(OP) \
1613 switch (
And.getMachineOpcode()) {
1620 if (
And->hasAnyUseOfValue(1))
1623 Ops[0] =
And.getOperand(0);
1624 Ops[1] =
And.getOperand(1);
1625 MachineSDNode *
Test =
1626 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1627 ReplaceUses(
N,
Test);
1635 if (
And->hasAnyUseOfValue(1))
1638 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1639#define FROM_TO(A, B) \
1640 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1642 switch (
And.getMachineOpcode()) {
1652 And.getOperand(3),
And.getOperand(4),
1653 And.getOperand(5),
And.getOperand(0)};
1656 Ops.push_back(
N->getOperand(2));
1657 Ops.push_back(
N->getOperand(3));
1660 Ops.push_back(
And.getOperand(6));
1663 Ops.push_back(
N->getOperand(4));
1665 MachineSDNode *
Test = CurDAG->getMachineNode(
1666 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1667 CurDAG->setNodeMemRefs(
1680 case X86::KORTESTBkk:
1681 case X86::KORTESTWkk:
1682 case X86::KORTESTDkk:
1683 case X86::KORTESTQkk: {
1685 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1700#define FROM_TO(A, B) \
1712 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1715 MachineSDNode *KTest = CurDAG->getMachineNode(
1717 ReplaceUses(
N, KTest);
1722 case TargetOpcode::SUBREG_TO_REG: {
1723 unsigned SubRegIdx =
N->getConstantOperandVal(2);
1724 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1741 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1742 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1743 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1744 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1745 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1746 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1747 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1748 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1753 if (!
In.isMachineOpcode() ||
1754 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1759 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1767 CurDAG->UpdateNodeOperands(
N,
N->getOperand(0), In,
N->getOperand(2));
1774 CurDAG->RemoveDeadNodes();
1779void X86DAGToDAGISel::emitSpecialCodeForMain() {
1780 if (Subtarget->isTargetCygMing()) {
1781 TargetLowering::ArgListTy
Args;
1782 auto &
DL = CurDAG->getDataLayout();
1784 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1785 CLI.setChain(CurDAG->getRoot())
1786 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1787 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1789 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1791 CurDAG->setRoot(
Result.second);
1795void X86DAGToDAGISel::emitFunctionEntryCode() {
1798 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1799 emitSpecialCodeForMain();
1812bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t
Offset,
1813 X86ISelAddressMode &AM) {
1818 int64_t Val = AM.Disp +
Offset;
1821 if (Val != 0 && (AM.ES || AM.MCSym))
1825 if (Subtarget->is64Bit()) {
1828 AM.hasSymbolicDisplacement()))
1832 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1851 if (Subtarget->isTarget64BitILP32() &&
1853 !AM.hasBaseOrIndexReg())
1863bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1864 bool AllowSegmentRegForX32) {
1877 !IndirectTlsSegRefs &&
1878 (Subtarget->isTargetGlibc() || Subtarget->isTargetMusl() ||
1879 Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())) {
1880 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1882 switch (
N->getPointerInfo().getAddrSpace()) {
1884 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1887 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1900bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1903 if (AM.hasSymbolicDisplacement())
1906 bool IsRIPRelTLS =
false;
1924 if (IsRIPRel && AM.hasBaseOrIndexReg())
1928 X86ISelAddressMode Backup = AM;
1933 AM.GV =
G->getGlobal();
1934 AM.SymbolFlags =
G->getTargetFlags();
1937 AM.CP = CP->getConstVal();
1938 AM.Alignment = CP->getAlign();
1939 AM.SymbolFlags = CP->getTargetFlags();
1940 Offset = CP->getOffset();
1942 AM.ES = S->getSymbol();
1943 AM.SymbolFlags = S->getTargetFlags();
1945 AM.MCSym = S->getMCSymbol();
1947 AM.JT = J->getIndex();
1948 AM.SymbolFlags = J->getTargetFlags();
1950 AM.BlockAddr = BA->getBlockAddress();
1951 AM.SymbolFlags = BA->getTargetFlags();
1952 Offset = BA->getOffset();
1957 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1958 TM.isLargeGlobalValue(AM.GV)) {
1963 if (foldOffsetIntoAddress(
Offset, AM)) {
1969 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
1977bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
1978 if (matchAddressRecursively(
N, AM, 0))
1985 if (Subtarget->isTarget64BitILP32() &&
1986 AM.BaseType == X86ISelAddressMode::RegBase &&
1987 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
1988 SDValue Save_Base_Reg = AM.Base_Reg;
1991 if (matchLoadInAddress(LoadN, AM,
true))
1992 AM.Base_Reg = Save_Base_Reg;
1998 if (AM.Scale == 2 &&
1999 AM.BaseType == X86ISelAddressMode::RegBase &&
2000 AM.Base_Reg.
getNode() ==
nullptr) {
2001 AM.Base_Reg = AM.IndexReg;
2008 (!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2009 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2010 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2022 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2028bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
2032 HandleSDNode Handle(
N);
2034 X86ISelAddressMode Backup = AM;
2035 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
2036 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
2041 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
2043 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2050 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2053 N = Handle.getValue();
2059 N = Handle.getValue();
2069 if (
N->getNodeId() == -1 ||
2089 X86ISelAddressMode &AM) {
2096 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2097 Mask != (0xffu << ScaleLog))
2100 MVT XVT =
X.getSimpleValueType();
2101 MVT VT =
N.getSimpleValueType();
2126 AM.Scale = (1 << ScaleLog);
2134 X86ISelAddressMode &AM) {
2145 bool FoundAnyExtend =
false;
2149 FoundAnyExtend =
true;
2167 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2170 MVT VT =
N.getSimpleValueType();
2172 if (FoundAnyExtend) {
2193 AM.Scale = 1 << ShiftAmt;
2194 AM.IndexReg = NewAnd;
2228 X86ISelAddressMode &AM) {
2234 unsigned MaskIdx, MaskLen;
2237 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2243 unsigned AMShiftAmt = MaskIdx;
2247 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2251 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2252 if (MaskLZ < ScaleDown)
2254 MaskLZ -= ScaleDown;
2262 bool ReplacingAnyExtend =
false;
2264 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2265 X.getOperand(0).getSimpleValueType().getSizeInBits();
2268 X =
X.getOperand(0);
2269 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2270 ReplacingAnyExtend =
true;
2272 APInt MaskedHighBits =
2279 MVT VT =
N.getSimpleValueType();
2280 if (ReplacingAnyExtend) {
2281 assert(
X.getValueType() != VT);
2288 MVT XVT =
X.getSimpleValueType();
2309 AM.Scale = 1 << AMShiftAmt;
2310 AM.IndexReg = NewExt;
2320 X86ISelAddressMode &AM,
2328 if (!Subtarget.hasTBM() &&
2329 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2333 unsigned MaskIdx, MaskLen;
2341 unsigned AMShiftAmt = MaskIdx;
2345 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2347 MVT XVT =
X.getSimpleValueType();
2348 MVT VT =
N.getSimpleValueType();
2373 AM.Scale = 1 << AMShiftAmt;
2374 AM.IndexReg = NewExt;
2381 X86ISelAddressMode &AM,
2383 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2384 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2385 "Illegal index scale");
2391 EVT VT =
N.getValueType();
2392 unsigned Opc =
N.getOpcode();
2395 if (CurDAG->isBaseWithConstantOffset(
N)) {
2397 uint64_t
Offset = (uint64_t)AddVal->getSExtValue() * AM.Scale;
2398 if (!foldOffsetIntoAddress(
Offset, AM))
2399 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2403 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2404 if (AM.Scale <= 4) {
2406 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2412 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2413 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2414 if ((AM.Scale * ScaleAmt) <= 8) {
2415 AM.Scale *= ScaleAmt;
2416 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2424 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2426 if (CurDAG->isBaseWithConstantOffset(Src)) {
2427 SDValue AddSrc = Src.getOperand(0);
2429 int64_t
Offset = AddVal->getSExtValue();
2430 if (!foldOffsetIntoAddress((uint64_t)
Offset * AM.Scale, AM)) {
2438 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2439 CurDAG->RemoveDeadNode(
N.getNode());
2451 unsigned SrcOpc = Src.getOpcode();
2452 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2453 CurDAG->isADDLike(Src,
true)) &&
2455 if (CurDAG->isBaseWithConstantOffset(Src)) {
2456 SDValue AddSrc = Src.getOperand(0);
2457 uint64_t
Offset = Src.getConstantOperandVal(1);
2458 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2468 uint64_t ScaleAmt = 1ULL << ShAmt;
2469 if ((AM.Scale * ScaleAmt) <= 8 &&
2471 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2472 AM.Scale *= ScaleAmt;
2473 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2484 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2488 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2489 CurDAG->RemoveDeadNode(
N.getNode());
2490 return Res ? Res : ExtSrc;
2500bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2503 dbgs() <<
"MatchAddress: ";
2508 return matchAddressBase(
N, AM);
2513 if (AM.isRIPRelative()) {
2517 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2521 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2526 switch (
N.getOpcode()) {
2529 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2532 AM.MCSym = ESNode->getMCSymbol();
2539 if (!foldOffsetIntoAddress(Val, AM))
2546 if (!matchWrapper(
N, AM))
2556 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2557 AM.Base_Reg.
getNode() ==
nullptr &&
2559 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2566 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2570 unsigned Val = CN->getZExtValue();
2575 if (Val == 1 || Val == 2 || Val == 3) {
2577 AM.Scale = 1 << Val;
2578 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2586 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2590 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2591 "Unexpected value size!");
2603 uint64_t
Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2615 if (
N.getResNo() != 0)
break;
2620 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2621 AM.Base_Reg.
getNode() ==
nullptr &&
2622 AM.IndexReg.
getNode() ==
nullptr) {
2624 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2625 CN->getZExtValue() == 9) {
2626 AM.Scale = unsigned(CN->getZExtValue())-1;
2638 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2639 if (foldOffsetIntoAddress(Disp, AM))
2640 Reg =
N.getOperand(0);
2642 Reg =
N.getOperand(0);
2645 AM.IndexReg = AM.Base_Reg =
Reg;
2661 HandleSDNode Handle(
N);
2664 X86ISelAddressMode Backup = AM;
2665 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2666 N = Handle.getValue();
2670 N = Handle.getValue();
2672 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2687 RHS.getOperand(0).getValueType() == MVT::i32))
2691 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2693 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2697 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2698 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2711 AM.NegateIndex =
true;
2719 if (!CurDAG->isADDLike(
N))
2723 if (!matchAdd(
N, AM,
Depth))
2732 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2736 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2737 "Unexpected value size!");
2742 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2746 uint64_t
Mask =
N.getConstantOperandVal(1);
2771 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2779 if (
SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2781 AM.IndexReg =
Index;
2787 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2789 Mask = MaskC->getAPIntValue();
2790 Src = Src.getOperand(0);
2793 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2795 SDValue ShlSrc = Src.getOperand(0);
2796 SDValue ShlAmt = Src.getOperand(1);
2800 unsigned ShAmtV = ShAmtC->getZExtValue();
2808 if (!Src->getFlags().hasNoUnsignedWrap() &&
2809 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2817 MVT VT =
N.getSimpleValueType();
2821 if (!
Mask.isAllOnes()) {
2822 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2824 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2831 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2832 CurDAG->RemoveDeadNode(
N.getNode());
2835 AM.Scale = 1 << ShAmtV;
2839 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2843 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2846 Src.getOperand(0), AM))
2851 Src.getOperand(0), AM))
2856 Src.getOperand(0), AM, *Subtarget))
2864 return matchAddressBase(
N, AM);
2869bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2871 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
2884 AM.BaseType = X86ISelAddressMode::RegBase;
2889bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2890 X86ISelAddressMode &AM,
2893 dbgs() <<
"MatchVectorAddress: ";
2898 return matchAddressBase(
N, AM);
2901 switch (
N.getOpcode()) {
2904 if (!foldOffsetIntoAddress(Val, AM))
2909 if (!matchWrapper(
N, AM))
2915 HandleSDNode Handle(
N);
2917 X86ISelAddressMode Backup = AM;
2918 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2919 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2925 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2927 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2932 N = Handle.getValue();
2937 return matchAddressBase(
N, AM);
2943bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2944 return matchVectorAddressRecursively(
N, AM, 0);
2947bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
2952 X86ISelAddressMode AM;
2958 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2960 AM.IndexReg = IndexOp;
2964 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
2966 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
2968 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
2971 MVT VT =
BasePtr.getSimpleValueType();
2974 if (matchVectorAddress(BasePtr, AM))
2977 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
2991 X86ISelAddressMode AM;
3003 unsigned AddrSpace =
3006 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3008 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3010 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3015 MVT VT =
N.getSimpleValueType();
3017 if (matchAddress(
N, AM))
3020 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3036 N =
N.getOperand(0);
3053 return CR->getUnsignedMax().ult(1ull << 32);
3055 return !TM.isLargeGlobalValue(GV);
3064 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3077 if (RN &&
RN->getReg() == 0)
3078 Base = CurDAG->getRegister(0, MVT::i64);
3088 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3090 if (RN &&
RN->getReg() == 0)
3091 Index = CurDAG->getRegister(0, MVT::i64);
3094 "Expect to be extending 8/16/32-bit registers for use in LEA");
3097 Index = CurDAG->getTargetInsertSubreg(
SubReg,
DL, MVT::i64, ImplDef, Index);
3105bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3109 X86ISelAddressMode AM;
3113 MVT VT =
N.getSimpleValueType();
3118 SDValue T = CurDAG->getRegister(0, MVT::i32);
3120 if (matchAddress(
N, AM))
3125 unsigned Complexity = 0;
3126 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3128 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3144 if (AM.hasSymbolicDisplacement()) {
3146 if (Subtarget->is64Bit())
3156 auto isMathWithFlags = [](
SDValue V) {
3157 switch (
V.getOpcode()) {
3171 return !
SDValue(
V.getNode(), 1).use_empty();
3178 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3186 if (Complexity <= 2)
3189 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3200 X86ISelAddressMode AM;
3202 AM.GV = GA->getGlobal();
3203 AM.Disp += GA->getOffset();
3204 AM.SymbolFlags = GA->getTargetFlags();
3207 AM.ES = SA->getSymbol();
3208 AM.SymbolFlags = SA->getTargetFlags();
3211 if (Subtarget->is32Bit()) {
3213 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3216 MVT VT =
N.getSimpleValueType();
3217 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3225 EVT VT =
N.getValueType();
3226 bool WasTruncated =
false;
3228 WasTruncated =
true;
3229 N =
N.getOperand(0);
3238 unsigned Opc =
N.getOperand(0)->getOpcode();
3240 Op =
N.getOperand(0);
3243 return !WasTruncated;
3248 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3249 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3253 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3254 GA->getOffset(), GA->getTargetFlags());
3258bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
3262 assert(Root &&
P &&
"Unknown root/parent nodes");
3264 !IsProfitableToFold(
N,
P, Root) ||
3265 !IsLegalToFold(
N,
P, Root, OptLevel))
3268 return selectAddr(
N.getNode(),
3269 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3272bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
3276 assert(Root &&
P &&
"Unknown root/parent nodes");
3278 !IsProfitableToFold(
N,
P, Root) ||
3279 !IsLegalToFold(
N,
P, Root, OptLevel))
3282 return selectAddr(
N.getNode(),
3283 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3289SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3292 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3295bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3297 N =
N->getOperand(0).getNode();
3305 auto *GV = GA->getGlobal();
3308 return CR->getSignedMin().sge(-1ull << Width) &&
3309 CR->getSignedMax().slt(1ull << Width);
3315 !TM.isLargeGlobalValue(GV);
3319 assert(
N->isMachineOpcode() &&
"Unexpected node");
3320 unsigned Opc =
N->getMachineOpcode();
3321 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3326 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3331bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3333 for (SDUse &Use :
Flags->uses()) {
3335 if (
Use.getResNo() !=
Flags.getResNo())
3343 for (SDUse &FlagUse :
User->uses()) {
3345 if (FlagUse.getResNo() != 1)
3348 if (!FlagUse.getUser()->isMachineOpcode())
3368bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3370 for (SDUse &Use :
Flags->uses()) {
3372 if (
Use.getResNo() !=
Flags.getResNo())
3380 for (SDUse &FlagUse :
User->uses()) {
3382 if (FlagUse.getResNo() != 1)
3385 if (!FlagUse.getUser()->isMachineOpcode())
3425 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3427 for (SDUse &Use :
Flags->uses()) {
3429 if (
Use.getResNo() !=
Flags.getResNo())
3433 unsigned UserOpc =
User->getOpcode();
3440 for (SDUse &FlagUse :
User->uses()) {
3442 if (FlagUse.getResNo() != 1)
3445 if (!FlagUse.getUser()->isMachineOpcode())
3486 if (StoredVal.
getResNo() != 0)
return false;
3503 if (!Load.hasOneUse())
3511 bool FoundLoad =
false;
3515 const unsigned int Max = 1024;
3557 if (Chain == Load.getValue(1)) {
3563 if (
Op == Load.getValue(1)) {
3579 if (
Op.getNode() != LoadNode)
3611bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3613 SDValue StoredVal = StoreNode->getOperand(1);
3619 EVT MemVT = StoreNode->getMemoryVT();
3620 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3624 bool IsCommutable =
false;
3625 bool IsNegate =
false;
3639 IsCommutable =
true;
3643 unsigned LoadOpNo = IsNegate ? 1 : 0;
3644 LoadSDNode *LoadNode =
nullptr;
3647 LoadNode, InputChain)) {
3654 LoadNode, InputChain))
3659 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3663 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3684 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3687 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3694 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
3698 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3701 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
3702 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
3704 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3715 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
3718 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
3721 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
3724 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
3727 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
3730 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
3733 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
3735 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
3741 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
3744 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
3747 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
3750 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
3753 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
3756 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
3759 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
3762 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
3769 unsigned NewOpc = SelectRegOpcode(
Opc);
3775 int64_t OperandV = OperandC->getSExtValue();
3782 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
3784 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3785 OperandV = -OperandV;
3789 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
3790 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
3791 NewOpc = SelectImmOpcode(
Opc);
3797 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
3801 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
3802 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3806 Segment, Operand, InputChain};
3807 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3816 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
3818 CurDAG->setNodeMemRefs(Result, MemOps);
3824 CurDAG->RemoveDeadNode(Node);
3835bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
3839 "Should be either an and-mask, or right-shift after clearing high bits.");
3842 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
3845 MVT NVT =
Node->getSimpleValueType(0);
3848 if (NVT != MVT::i32 && NVT != MVT::i64)
3856 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
3857 auto checkUses = [AllowExtraUsesByDefault](
3859 std::optional<bool> AllowExtraUses) {
3860 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
3861 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
3863 auto checkOneUse = [checkUses](
SDValue Op,
3864 std::optional<bool> AllowExtraUses =
3866 return checkUses(
Op, 1, AllowExtraUses);
3868 auto checkTwoUse = [checkUses](
SDValue Op,
3869 std::optional<bool> AllowExtraUses =
3871 return checkUses(
Op, 2, AllowExtraUses);
3874 auto peekThroughOneUseTruncation = [checkOneUse](
SDValue V) {
3876 assert(
V.getSimpleValueType() == MVT::i32 &&
3877 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
3878 "Expected i64 -> i32 truncation");
3879 V =
V.getOperand(0);
3885 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
3888 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
3894 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3899 NBits =
M0->getOperand(1);
3900 NegateNBits =
false;
3904 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](
SDValue V) {
3905 V = peekThroughOneUseTruncation(V);
3906 return CurDAG->MaskedValueIsAllOnes(
3912 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
3915 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
3918 if (!isAllOnes(
Mask->getOperand(1)))
3921 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3925 if (!isAllOnes(
M0->getOperand(0)))
3927 NBits =
M0->getOperand(1);
3928 NegateNBits =
false;
3934 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](
SDValue ShiftAmt,
3935 unsigned Bitwidth) {
3940 NBits = NBits.getOperand(0);
3946 if (!V0 || V0->getZExtValue() != Bitwidth)
3948 NBits = NBits.getOperand(1);
3949 NegateNBits =
false;
3955 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
3958 Mask = peekThroughOneUseTruncation(Mask);
3959 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
3961 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
3968 if (!checkOneUse(
M1))
3970 canonicalizeShiftAmt(
M1, Bitwidth);
3975 return !NegateNBits;
3983 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
3984 AllowExtraUsesByDefault, &NegateNBits,
3985 &
X](SDNode *
Node) ->
bool {
3997 canonicalizeShiftAmt(N1, Bitwidth);
4001 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
4002 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4008 auto matchLowBitMask = [matchPatternA, matchPatternB,
4010 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4014 X =
Node->getOperand(0);
4017 if (matchLowBitMask(Mask)) {
4021 if (!matchLowBitMask(Mask))
4024 }
else if (matchLowBitMask(
SDValue(Node, 0))) {
4025 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4026 }
else if (!matchPatternD(Node))
4031 if (NegateNBits && !Subtarget->hasBMI2())
4036 if (NBits.getSimpleValueType() != MVT::i8) {
4043 ConstantSDNode *
Imm =
nullptr;
4044 if (NBits->getOpcode() ==
ISD::AND)
4046 NBits = NBits->getOperand(0);
4051 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4054 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4056 NBits =
SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4057 MVT::i32, ImplDef, NBits, SRIdxVal),
4063 CurDAG->getNode(
ISD::AND,
DL, MVT::i32, NBits,
4064 CurDAG->getConstant(
Imm->getZExtValue(),
DL, MVT::i32));
4074 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4078 if (Subtarget->hasBMI2()) {
4080 if (NVT != MVT::i32) {
4087 ReplaceNode(Node, Extract.
getNode());
4088 SelectCode(Extract.
getNode());
4097 SDValue RealX = peekThroughOneUseTruncation(
X);
4103 MVT XVT =
X.getSimpleValueType();
4113 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4121 SDValue ShiftAmt =
X.getOperand(1);
4122 X =
X.getOperand(0);
4125 "Expected shift amount to be i8");
4129 SDValue OrigShiftAmt = ShiftAmt;
4134 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4139 if (XVT != MVT::i32) {
4153 ReplaceNode(Node, Extract.
getNode());
4154 SelectCode(Extract.
getNode());
4160MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4161 MVT NVT =
Node->getSimpleValueType(0);
4174 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4175 if (!PreferBEXTR && !Subtarget->hasBMI2())
4187 if (NVT != MVT::i32 && NVT != MVT::i64)
4193 if (!MaskCst || !ShiftCst)
4197 uint64_t
Mask = MaskCst->getZExtValue();
4201 uint64_t Shift = ShiftCst->getZExtValue();
4206 if (Shift == 8 && MaskSize == 8)
4217 if (!PreferBEXTR && MaskSize <= 32)
4221 unsigned ROpc, MOpc;
4223#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4225 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4229 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4234 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4235 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4241 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4242 if (Subtarget->hasTBM()) {
4243 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4244 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4246 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4252 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4253 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4257 MachineSDNode *NewNode;
4259 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4260 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4262 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4263 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4264 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4268 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4270 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4275 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4279 CurDAG->getMachineNode(NewOpc, dl, NVT,
SDValue(NewNode, 0), ShAmt);
4286MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4287 bool MayFoldLoad,
const SDLoc &dl,
4288 MVT VT, SDNode *Node) {
4293 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4296 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4297 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4300 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4301 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4310 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4311 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4318MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4319 bool MayFoldLoad,
const SDLoc &dl,
4320 MVT VT, SDNode *Node,
4326 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4329 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4330 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4333 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4334 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4344 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4345 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4350bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4351 EVT VT =
N->getValueType(0);
4358 unsigned Size = VT == MVT::i64 ? 64 : 32;
4361 SDValue ShiftAmt = OrigShiftAmt;
4380 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4384 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4385 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4389 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4398 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4399 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4405 Add0C->getZExtValue() != 0) {
4408 if (Add0C->getZExtValue() %
Size == 0)
4411 Add0C->getZExtValue() % 32 == 0) {
4419 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4423 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4445 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4452 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4453 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4457 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4459 if (UpdatedNode !=
N) {
4462 ReplaceNode(
N, UpdatedNode);
4469 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4477bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4478 MVT NVT =
N->getSimpleValueType(0);
4479 unsigned Opcode =
N->getOpcode();
4491 int64_t Val = Cst->getSExtValue();
4496 bool FoundAnyExtend =
false;
4500 FoundAnyExtend =
true;
4508 if (NVT != MVT::i32 && NVT != MVT::i64)
4515 uint64_t ShAmt = ShlCst->getZExtValue();
4519 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4520 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4525 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4529 ShiftedVal = (uint64_t)Val >> ShAmt;
4533 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4536 ShiftedVal = Val >> ShAmt;
4542 ShiftedVal = (uint64_t)Val >> ShAmt;
4550 if (!CanShrinkImmediate(ShiftedVal))
4560 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4566 NeededMask &= ~Cst->getAPIntValue();
4568 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4573 if (FoundAnyExtend) {
4579 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4581 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4590bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4591 SDNode *ParentB, SDNode *ParentC,
4594 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4595 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4597 auto tryFoldLoadOrBCast =
4600 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4606 L =
L.getOperand(0);
4614 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4618 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4621 bool FoldedLoad =
false;
4622 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4623 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4625 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4630 uint8_t OldImm =
Imm;
4631 Imm = OldImm & 0xa5;
4632 if (OldImm & 0x02)
Imm |= 0x10;
4633 if (OldImm & 0x10)
Imm |= 0x02;
4634 if (OldImm & 0x08)
Imm |= 0x40;
4635 if (OldImm & 0x40)
Imm |= 0x08;
4636 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4641 uint8_t OldImm =
Imm;
4642 Imm = OldImm & 0x99;
4643 if (OldImm & 0x02)
Imm |= 0x04;
4644 if (OldImm & 0x04)
Imm |= 0x02;
4645 if (OldImm & 0x20)
Imm |= 0x40;
4646 if (OldImm & 0x40)
Imm |= 0x20;
4651 SDValue TImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
4655 MachineSDNode *MNode;
4657 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4662 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4663 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4665 bool UseD = EltSize == 32;
4667 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4669 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4671 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4677 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4679 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4681 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4687 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
4690 ReplaceUses(
C.getValue(1),
SDValue(MNode, 1));
4697 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
4699 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
4701 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
4705 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
4709 CurDAG->RemoveDeadNode(Root);
4715bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
4716 MVT NVT =
N->getSimpleValueType(0);
4719 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
4727 auto getFoldableLogicOp = [](
SDValue Op) {
4730 Op =
Op.getOperand(0);
4732 if (!
Op.hasOneUse())
4735 unsigned Opc =
Op.getOpcode();
4746 auto tryPeelOuterNotWrappingLogic = [&](SDNode *
Op) {
4749 SDValue InnerOp = getFoldableLogicOp(
Op->getOperand(0));
4756 if ((FoldableOp = getFoldableLogicOp(N1))) {
4760 if ((FoldableOp = getFoldableLogicOp(N0))) {
4768 bool PeeledOuterNot =
false;
4770 if (
SDValue InnerOp = tryPeelOuterNotWrappingLogic(
N)) {
4771 PeeledOuterNot =
true;
4777 if ((FoldableOp = getFoldableLogicOp(N1)))
4779 else if ((FoldableOp = getFoldableLogicOp(N0)))
4787 SDNode *ParentA =
N;
4788 SDNode *ParentB = FoldableOp.
getNode();
4789 SDNode *ParentC = FoldableOp.
getNode();
4793 uint8_t TernlogMagicA = 0xf0;
4794 uint8_t TernlogMagicB = 0xcc;
4795 uint8_t TernlogMagicC = 0xaa;
4800 auto PeekThroughNot = [](
SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
4804 Parent =
Op.getNode();
4805 Op =
Op.getOperand(0);
4809 PeekThroughNot(
A, ParentA, TernlogMagicA);
4810 PeekThroughNot(
B, ParentB, TernlogMagicB);
4811 PeekThroughNot(
C, ParentC, TernlogMagicC);
4816 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
4817 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
4818 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
4822 switch (
N->getOpcode()) {
4826 Imm &= ~TernlogMagicA;
4828 Imm = ~(
Imm) & TernlogMagicA;
4838 return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC,
A,
B,
C, Imm);
4848bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
4851 MVT VT =
And->getSimpleValueType(0);
4852 if (VT != MVT::i32 && VT != MVT::i64)
4864 APInt MaskVal = And1C->getAPIntValue();
4866 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
4870 if (VT == MVT::i64 && MaskLZ >= 32) {
4872 MaskVal = MaskVal.
trunc(32);
4877 APInt NegMaskVal = MaskVal | HighZeros;
4886 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
4887 NegMaskVal = NegMaskVal.
zext(64);
4888 HighZeros = HighZeros.
zext(64);
4894 KnownBits Known0 = CurDAG->computeKnownBits(And0);
4906 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
4915 bool FoldedBCast,
bool Masked) {
4916#define VPTESTM_CASE(VT, SUFFIX) \
4919 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
4920 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
4923#define VPTESTM_BROADCAST_CASES(SUFFIX) \
4924default: llvm_unreachable("Unexpected VT!"); \
4925VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
4926VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
4927VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
4928VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
4929VPTESTM_CASE(v16i32, DZ##SUFFIX) \
4930VPTESTM_CASE(v8i64, QZ##SUFFIX)
4932#define VPTESTM_FULL_CASES(SUFFIX) \
4933VPTESTM_BROADCAST_CASES(SUFFIX) \
4934VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
4935VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
4936VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
4937VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
4938VPTESTM_CASE(v64i8, BZ##SUFFIX) \
4939VPTESTM_CASE(v32i16, WZ##SUFFIX)
4957#undef VPTESTM_FULL_CASES
4958#undef VPTESTM_BROADCAST_CASES
4964bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root,
SDValue Setcc,
4966 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
5011 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P,
SDValue &
L,
5016 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
5021 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
5027 L =
L.getOperand(0);
5034 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5037 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5041 bool CanFoldLoads = Src0 != Src1;
5043 bool FoldedLoad =
false;
5044 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5046 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5050 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5059 bool IsMasked = InMask.
getNode() !=
nullptr;
5072 SDValue ImplDef =
SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5074 Src0 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src0);
5077 Src1 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src1);
5082 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5083 InMask =
SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5084 dl, MaskVT, InMask, RC), 0);
5092 MachineSDNode *CNode;
5094 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5097 SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5099 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5101 SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5103 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5109 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5112 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5114 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5120 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5121 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5122 dl, ResVT,
SDValue(CNode, 0), RC);
5126 CurDAG->RemoveDeadNode(Root);
5132bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5135 MVT NVT =
N->getSimpleValueType(0);
5138 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5172 SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5180void X86DAGToDAGISel::Select(SDNode *Node) {
5181 MVT NVT =
Node->getSimpleValueType(0);
5182 unsigned Opcode =
Node->getOpcode();
5185 if (
Node->isMachineOpcode()) {
5187 Node->setNodeId(-1);
5194 unsigned IntNo =
Node->getConstantOperandVal(1);
5197 case Intrinsic::x86_encodekey128:
5198 case Intrinsic::x86_encodekey256: {
5199 if (!Subtarget->hasKL())
5205 case Intrinsic::x86_encodekey128:
5206 Opcode = X86::ENCODEKEY128;
5208 case Intrinsic::x86_encodekey256:
5209 Opcode = X86::ENCODEKEY256;
5214 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5216 if (Opcode == X86::ENCODEKEY256)
5217 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5220 MachineSDNode *Res = CurDAG->getMachineNode(
5221 Opcode, dl,
Node->getVTList(),
5222 {Node->getOperand(2), Chain, Chain.getValue(1)});
5223 ReplaceNode(Node, Res);
5226 case Intrinsic::x86_tileloaddrs64_internal:
5227 case Intrinsic::x86_tileloaddrst164_internal:
5228 if (!Subtarget->hasAMXMOVRS())
5231 case Intrinsic::x86_tileloadd64_internal:
5232 case Intrinsic::x86_tileloaddt164_internal: {
5233 if (!Subtarget->hasAMXTILE())
5236 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5237 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5242 case Intrinsic::x86_tileloaddrs64_internal:
5243 Opc = X86::PTILELOADDRSV;
5245 case Intrinsic::x86_tileloaddrst164_internal:
5246 Opc = X86::PTILELOADDRST1V;
5248 case Intrinsic::x86_tileloadd64_internal:
5249 Opc = X86::PTILELOADDV;
5251 case Intrinsic::x86_tileloaddt164_internal:
5252 Opc = X86::PTILELOADDT1V;
5257 SDValue Scale = getI8Imm(1, dl);
5259 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5260 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5262 MachineSDNode *CNode;
5264 Node->getOperand(3),
5271 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5272 ReplaceNode(Node, CNode);
5279 unsigned IntNo =
Node->getConstantOperandVal(1);
5282 case Intrinsic::x86_sse3_monitor:
5283 case Intrinsic::x86_monitorx:
5284 case Intrinsic::x86_clzero: {
5285 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5290 case Intrinsic::x86_sse3_monitor:
5291 if (!Subtarget->hasSSE3())
5293 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5295 case Intrinsic::x86_monitorx:
5296 if (!Subtarget->hasMWAITX())
5298 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5300 case Intrinsic::x86_clzero:
5301 if (!Subtarget->hasCLZERO())
5303 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5308 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5309 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5313 if (IntNo == Intrinsic::x86_sse3_monitor ||
5314 IntNo == Intrinsic::x86_monitorx) {
5316 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5319 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5324 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5326 ReplaceNode(Node, CNode);
5332 case Intrinsic::x86_tilestored64_internal: {
5334 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5335 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5336 unsigned Opc = X86::PTILESTOREDV;
5339 SDValue Scale = getI8Imm(1, dl);
5341 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5342 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5344 MachineSDNode *CNode;
5346 Node->getOperand(3),
5352 Node->getOperand(6),
5354 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5355 ReplaceNode(Node, CNode);
5358 case Intrinsic::x86_tileloaddrs64:
5359 case Intrinsic::x86_tileloaddrst164:
5360 if (!Subtarget->hasAMXMOVRS())
5363 case Intrinsic::x86_tileloadd64:
5364 case Intrinsic::x86_tileloaddt164:
5365 case Intrinsic::x86_tilestored64: {
5366 if (!Subtarget->hasAMXTILE())
5369 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5370 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5374 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5375 case Intrinsic::x86_tileloaddrs64:
5376 Opc = X86::PTILELOADDRS;
5378 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5379 case Intrinsic::x86_tileloaddrst164:
5380 Opc = X86::PTILELOADDRST1;
5382 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5385 unsigned TIndex =
Node->getConstantOperandVal(2);
5388 SDValue Scale = getI8Imm(1, dl);
5390 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5391 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5393 MachineSDNode *CNode;
5394 if (
Opc == X86::PTILESTORED) {
5396 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5399 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5401 ReplaceNode(Node, CNode);
5409 if (Subtarget->isTarget64BitILP32()) {
5414 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5415 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5416 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5417 Node->getOperand(0), ZextTarget);
5418 ReplaceNode(Node, Brind.
getNode());
5419 SelectCode(ZextTarget.
getNode());
5426 ReplaceNode(Node, getGlobalBaseReg());
5433 ReplaceUses(
SDValue(Node, 0),
Node->getOperand(0));
5434 CurDAG->RemoveDeadNode(Node);
5440 if (matchBitExtract(Node))
5445 if (tryShiftAmountMod(Node))
5450 uint8_t
Imm =
Node->getConstantOperandVal(3);
5451 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5452 Node->getOperand(1),
Node->getOperand(2), Imm))
5458 if (tryVPTERNLOG(Node))
5468 tryVPTESTM(Node, N0, N1))
5471 tryVPTESTM(Node, N1, N0))
5475 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5477 CurDAG->RemoveDeadNode(Node);
5480 if (matchBitExtract(Node))
5488 if (tryShrinkShlLogicImm(Node))
5490 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5492 if (tryVPTERNLOG(Node))
5497 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5507 if (!CurDAG->shouldOptForSize())
5511 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5521 int64_t Val = Cst->getSExtValue();
5529 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5533 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5537 unsigned ROpc, MOpc;
5646 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5647 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5649 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5650 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5656 CurDAG->RemoveDeadNode(Node);
5661 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
5674 unsigned LoReg, ROpc, MOpc;
5679 ROpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
5680 MOpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
5699 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5700 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5703 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5708 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5711 MachineSDNode *CNode;
5717 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5719 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
5723 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5734 VTs = CurDAG->getVTList(NVT, MVT::i32);
5736 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
5738 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
5742 ReplaceUses(
SDValue(Node, 1),
SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
5743 CurDAG->RemoveDeadNode(Node);
5753 unsigned LoReg, HiReg;
5755 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
5756 bool UseMULXHi = UseMULX &&
SDValue(Node, 0).use_empty();
5760 Opc = UseMULXHi ? X86::MULX32Hrr
5762 : IsSigned ?
X86::IMUL32r
5764 MOpc = UseMULXHi ? X86::MULX32Hrm
5766 : IsSigned ?
X86::IMUL32m
5768 LoReg = UseMULX ? X86::EDX : X86::EAX;
5772 Opc = UseMULXHi ? X86::MULX64Hrr
5774 : IsSigned ?
X86::IMUL64r
5776 MOpc = UseMULXHi ? X86::MULX64Hrm
5778 : IsSigned ?
X86::IMUL64m
5780 LoReg = UseMULX ? X86::RDX : X86::RAX;
5785 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5786 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5789 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5794 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5799 MachineSDNode *CNode =
nullptr;
5803 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5804 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5807 }
else if (UseMULX) {
5808 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
5809 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5814 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5815 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5821 ReplaceUses(N1.
getValue(1), Chain);
5827 SDVTList VTs = CurDAG->getVTList(NVT);
5828 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5830 }
else if (UseMULX) {
5831 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
5832 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5836 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
5837 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5843 if (!
SDValue(Node, 0).use_empty()) {
5845 assert(LoReg &&
"Register for low half is not defined!");
5846 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
5850 ReplaceUses(
SDValue(Node, 0), ResLo);
5855 if (!
SDValue(Node, 1).use_empty()) {
5857 assert(HiReg &&
"Register for high half is not defined!");
5858 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
5862 ReplaceUses(
SDValue(Node, 1), ResHi);
5867 CurDAG->RemoveDeadNode(Node);
5876 unsigned ROpc, MOpc;
5881 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
5882 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
5883 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
5884 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
5889 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
5890 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
5891 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
5892 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
5896 unsigned LoReg, HiReg, ClrReg;
5897 unsigned SExtOpcode;
5901 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
5905 LoReg = X86::AX; HiReg = X86::DX;
5907 SExtOpcode = X86::CWD;
5910 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
5911 SExtOpcode = X86::CDQ;
5914 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
5915 SExtOpcode = X86::CQO;
5919 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5920 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5921 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
5924 if (NVT == MVT::i8) {
5927 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
5928 MachineSDNode *Move;
5929 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5931 unsigned Opc = (isSigned && !signBitIsZero) ? X86::MOVSX16rm8
5933 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
5935 ReplaceUses(N0.
getValue(1), Chain);
5939 unsigned Opc = (isSigned && !signBitIsZero) ? X86::MOVSX16rr8
5941 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
5942 Chain = CurDAG->getEntryNode();
5944 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX,
SDValue(Move, 0),
5949 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
5950 LoReg, N0,
SDValue()).getValue(1);
5951 if (isSigned && !signBitIsZero) {
5954 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
5957 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
5959 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
5963 SDValue(CurDAG->getMachineNode(
5964 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
5965 CurDAG->getTargetConstant(X86::sub_16bit, dl,
5973 SDValue(CurDAG->getMachineNode(
5974 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
5975 CurDAG->getTargetConstant(0, dl, MVT::i64), ClrNode,
5976 CurDAG->getTargetConstant(X86::sub_32bit, dl,
5984 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
5985 ClrNode, InGlue).getValue(1);
5992 MachineSDNode *CNode =
5993 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
6001 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
6011 if (HiReg == X86::AH && !
SDValue(Node, 1).use_empty()) {
6012 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
6013 unsigned AHExtOpcode =
6014 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6016 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6017 MVT::Glue, AHCopy, InGlue);
6022 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6024 ReplaceUses(
SDValue(Node, 1), Result);
6029 if (!
SDValue(Node, 0).use_empty()) {
6030 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6031 LoReg, NVT, InGlue);
6032 InGlue =
Result.getValue(2);
6033 ReplaceUses(
SDValue(Node, 0), Result);
6038 if (!
SDValue(Node, 1).use_empty()) {
6039 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6040 HiReg, NVT, InGlue);
6041 InGlue =
Result.getValue(2);
6042 ReplaceUses(
SDValue(Node, 1), Result);
6046 CurDAG->RemoveDeadNode(Node);
6055 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6056 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6062 if (Subtarget->canUseCMOV())
6071 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6074 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6077 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6082 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6085 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6086 Chain =
SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6089 Glue =
SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6094 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6098 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6102 assert(Subtarget->canUseLAHFSAHF() &&
6103 "Target doesn't support SAHF or FCOMI?");
6104 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract,
SDValue());
6107 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6110 ReplaceUses(
SDValue(Node, 1), Chain);
6112 ReplaceUses(
SDValue(Node, 0), SAHF);
6113 CurDAG->RemoveDeadNode(Node);
6133 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6134 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6137 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6139 CurDAG->RemoveDeadNode(Node);
6159 uint64_t
Mask = MaskC->getZExtValue();
6166 onlyUsesZeroFlag(
SDValue(Node, 0))) {
6171 unsigned TestOpcode;
6179 if (LeadingZeros == 0 && SavesBytes) {
6184 ShiftAmt = TrailingZeros;
6186 TestOpcode = X86::TEST64rr;
6187 }
else if (TrailingZeros == 0 && SavesBytes) {
6192 ShiftAmt = LeadingZeros;
6194 TestOpcode = X86::TEST64rr;
6195 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6198 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6199 if (PopCount == 8) {
6201 ShiftAmt = TrailingZeros;
6202 SubRegIdx = X86::sub_8bit;
6204 TestOpcode = X86::TEST8rr;
6205 }
else if (PopCount == 16) {
6207 ShiftAmt = TrailingZeros;
6208 SubRegIdx = X86::sub_16bit;
6209 SubRegVT = MVT::i16;
6210 TestOpcode = X86::TEST16rr;
6211 }
else if (PopCount == 32) {
6213 ShiftAmt = TrailingZeros;
6214 SubRegIdx = X86::sub_32bit;
6215 SubRegVT = MVT::i32;
6216 TestOpcode = X86::TEST32rr;
6220 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6222 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6225 if (SubRegIdx != 0) {
6227 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6229 MachineSDNode *
Test =
6230 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6231 ReplaceNode(Node,
Test);
6238 unsigned ROpc, MOpc;
6246 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6247 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6250 SubRegOp = X86::sub_8bit;
6251 ROpc = X86::TEST8ri;
6252 MOpc = X86::TEST8mi;
6253 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6254 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6255 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6261 SubRegOp = X86::sub_16bit;
6262 ROpc = X86::TEST16ri;
6263 MOpc = X86::TEST16mi;
6265 ((!(Mask & 0x80000000) &&
6268 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6269 CmpVT == MVT::i32 ||
6270 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6277 SubRegOp = X86::sub_32bit;
6278 ROpc = X86::TEST32ri;
6279 MOpc = X86::TEST32mi;
6285 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6289 MachineSDNode *NewNode;
6290 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6291 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6293 if (!LoadN->isSimple()) {
6294 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6295 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6296 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6297 (MOpc == X86::TEST32mi && NumVolBits != 32))
6302 Reg.getOperand(0) };
6303 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6305 ReplaceUses(
Reg.getValue(1),
SDValue(NewNode, 1));
6307 CurDAG->setNodeMemRefs(NewNode,
6312 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6314 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg, Imm);
6317 ReplaceNode(Node, NewNode);
6323 if (!Subtarget->hasSSE42())
6326 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6327 bool NeedMask = !
SDValue(Node, 1).use_empty();
6329 bool MayFoldLoad = !NeedIndex || !NeedMask;
6331 MachineSDNode *CNode;
6334 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6336 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6337 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6340 if (NeedIndex || !NeedMask) {
6342 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6344 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6345 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6351 CurDAG->RemoveDeadNode(Node);
6355 if (!Subtarget->hasSSE42())
6359 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6360 Node->getOperand(1),
6362 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6363 Node->getOperand(3), InGlue).getValue(1);
6365 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6366 bool NeedMask = !
SDValue(Node, 1).use_empty();
6368 bool MayFoldLoad = !NeedIndex || !NeedMask;
6370 MachineSDNode *CNode;
6373 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6375 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6377 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6380 if (NeedIndex || !NeedMask) {
6382 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6384 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6385 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6390 CurDAG->RemoveDeadNode(Node);
6402 if (foldLoadStoreIntoMemOperand(Node))
6407 MVT VT =
Node->getSimpleValueType(0);
6409 if (Subtarget->hasSBBDepBreaking()) {
6414 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6419 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6420 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6422 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6427 Result = getSBBZero(Node);
6431 if (VT == MVT::i8 || VT == MVT::i16) {
6432 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6433 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6436 ReplaceUses(
SDValue(Node, 0), Result);
6437 CurDAG->RemoveDeadNode(Node);
6449 if (!
SDValue(Node, 0).use_empty()) {
6451 MVT VT =
Node->getSimpleValueType(0);
6452 if (VT == MVT::i8 || VT == MVT::i16) {
6453 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6454 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6456 ReplaceUses(
SDValue(Node, 0), Result);
6459 CurDAG->RemoveDeadNode(Node);
6466 SDValue IndexOp = Mgt->getIndex();
6469 MVT ValueVT =
Node->getSimpleValueType(0);
6470 MVT MaskVT =
Mask.getSimpleValueType();
6487 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6488 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6489 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6490 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6491 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6492 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6493 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6494 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6495 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6496 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6497 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6498 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6499 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6500 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6501 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6502 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6503 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6504 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6505 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6506 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6507 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6508 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6509 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6510 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6512 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6513 "Unexpected mask VT!");
6514 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6515 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6516 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6517 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6518 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6519 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6520 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6521 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6522 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6523 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6524 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6525 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6526 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6527 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6528 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6529 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6536 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6537 Base, Scale, Index, Disp, Segment))
6540 SDValue PassThru = Mgt->getPassThru();
6541 SDValue Chain = Mgt->getChain();
6543 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6545 MachineSDNode *NewNode;
6548 Index, Disp, Segment, Chain};
6549 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6552 Disp, Segment,
Mask, Chain};
6553 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6555 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6558 CurDAG->RemoveDeadNode(Node);
6564 SDValue IndexOp = Sc->getIndex();
6566 MVT ValueVT =
Value.getSimpleValueType();
6581 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6582 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6583 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6584 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6585 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6586 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6587 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6588 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6589 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6590 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6591 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6592 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6593 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6594 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6595 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6596 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6597 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6598 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6599 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6600 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6601 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6602 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6603 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6604 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6609 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6610 Base, Scale, Index, Disp, Segment))
6614 SDValue Chain = Sc->getChain();
6616 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6619 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6620 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6622 CurDAG->RemoveDeadNode(Node);
6626 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6627 auto CallId = MFI->getPreallocatedIdForCallSite(
6630 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6631 MachineSDNode *
New = CurDAG->getMachineNode(
6632 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6634 CurDAG->RemoveDeadNode(Node);
6638 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6642 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6645 Ops[0] = CallIdValue;
6648 MachineSDNode *
New = CurDAG->getMachineNode(
6649 TargetOpcode::PREALLOCATED_ARG, dl,
6650 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
6655 CurDAG->RemoveDeadNode(Node);
6662 if (!Subtarget->hasWIDEKL())
6666 switch (
Node->getOpcode()) {
6670 Opcode = X86::AESENCWIDE128KL;
6673 Opcode = X86::AESDECWIDE128KL;
6676 Opcode = X86::AESENCWIDE256KL;
6679 Opcode = X86::AESDECWIDE256KL;
6687 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
6690 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
6692 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
6694 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
6696 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
6698 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
6700 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
6702 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
6704 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
6707 MachineSDNode *Res = CurDAG->getMachineNode(
6708 Opcode, dl,
Node->getVTList(),
6709 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
6711 ReplaceNode(Node, Res);
6718 if (
Node->getNumValues() == 3)
6719 Glue =
Node->getOperand(2);
6721 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
6722 ReplaceNode(Node,
Copy.getNode());
6730bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
6732 std::vector<SDValue> &OutOps) {
6733 SDValue Op0, Op1, Op2, Op3, Op4;
6734 switch (ConstraintID) {
6737 case InlineAsm::ConstraintCode::o:
6738 case InlineAsm::ConstraintCode::v:
6739 case InlineAsm::ConstraintCode::m:
6740 case InlineAsm::ConstraintCode::X:
6741 case InlineAsm::ConstraintCode::p:
6742 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
6747 OutOps.push_back(Op0);
6748 OutOps.push_back(Op1);
6749 OutOps.push_back(Op2);
6750 OutOps.push_back(Op3);
6751 OutOps.push_back(Op4);
6757 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
6763 return new X86DAGToDAGISelLegacy(TM, OptLevel);
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
#define CASE(ATTRNAME, AANAME,...)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
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.
iterator_range< user_iterator > users()
op_iterator op_end() const
op_iterator op_begin() const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISelPass(std::unique_ptr< SelectionDAGISel > Selector)
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
static int getUninvalidatedNodeId(SDNode *N)
virtual bool runOnMachineFunction(MachineFunction &mf)
static void InvalidateNodeId(SDNode *N)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
void RepositionNode(allnodes_iterator Position, SDNode *N)
Move node N in the AllNodes list to be immediately before the given iterator Position.
ilist< SDNode >::iterator allnodes_iterator
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
unsigned 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.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ PREALLOCATED_SETUP
PREALLOCATED_SETUP - This has 2 operands: an input chain and a SRCVALUE with the preallocated call Va...
@ PREALLOCATED_ARG
PREALLOCATED_ARG - This has 3 operands: an input chain, a SRCVALUE with the preallocated call Value,...
@ BRIND
BRIND - Indirect branch.
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ LOCAL_RECOVER
LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ X86
Windows x64, Windows Itanium (IA-64)
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ FST
This instruction implements a truncating store from FP stack slots.
@ CMPM
Vector comparison generating mask bits for fp and integer signed and unsigned data types.
@ CMP
X86 compare and logical compare instructions.
@ BLENDV
Dynamic (non-constant condition) vector blend where only the sign bits of the condition elements are ...
@ STRICT_CMPM
Vector comparison generating mask bits for fp and integer signed and unsigned data types.
@ NT_BRIND
BRIND node with NoTrack prefix.
@ FSETCCM
X86 FP SETCC, similar to above, but with output as an i1 mask and and a version with SAE.
@ FXOR
Bitwise logical XOR of floating point values.
@ BRCOND
X86 conditional branches.
@ CALL
These operations represent an abstract X86 call instruction, which includes a bunch of information.
@ FANDN
Bitwise logical ANDNOT of floating point values.
@ GlobalBaseReg
On Darwin, this node represents the result of the popl at function entry, used for PIC code.
@ FLD
This instruction implements an extending load to FP stack slots.
@ TC_RETURN
Tail call return.
@ FOR
Bitwise logical OR of floating point values.
@ Wrapper
A wrapper node for TargetConstantPool, TargetJumpTable, TargetExternalSymbol, TargetGlobalAddress,...
@ ANDNP
Bitwise Logical AND NOT of Packed FP values.
@ POP_FROM_X87_REG
The same as ISD::CopyFromReg except that this node makes it explicit that it may lower to an x87 FPU ...
@ FAND
Bitwise logical AND of floating point values.
@ CMOV
X86 conditional moves.
@ WrapperRIP
Special wrapper used under X86-64 PIC mode for RIP relative displacements.
int getCondSrcNoFromDesc(const MCInstrDesc &MCID)
Return the source operand # for condition code by MCID.
bool mayFoldLoad(SDValue Op, const X86Subtarget &Subtarget, bool AssumeSingleUse=false, bool IgnoreAlignment=false)
Check if Op is a load operation that could be folded into some other x86 instruction as a memory oper...
bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M, bool hasSymbolicDisplacement)
Returns true of the given offset can be fit into displacement field of the instruction.
bool isConstantSplat(SDValue Op, APInt &SplatVal, bool AllowPartialUndefs)
If Op is a constant whose elements are all the same constant or undefined, return true and return the...
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isa_and_nonnull(const Y &Val)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
unsigned M1(unsigned Val)
auto dyn_cast_or_null(const Y &Val)
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
FunctionPass * createX86ISelDag(X86TargetMachine &TM, CodeGenOptLevel OptLevel)
This pass converts a legalized DAG into a X86-specific DAG, ready for instruction scheduling.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
bool isVector() const
Return true if this is a vector value type.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
bool isConstant() const
Returns true if we know the value of all bits.
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
bool hasNoUnsignedWrap() const