22#include "llvm/Config/llvm-config.h"
27#include "llvm/IR/IntrinsicsX86.h"
39#define DEBUG_TYPE "x86-isel"
40#define PASS_NAME "X86 DAG->DAG Instruction Selection"
42STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
45 cl::desc(
"Enable setting constant bits to reduce size of mask immediates"),
49 "x86-promote-anyext-load",
cl::init(
true),
61 struct X86ISelAddressMode {
69 int Base_FrameIndex = 0;
75 const GlobalValue *GV =
nullptr;
78 const char *ES =
nullptr;
83 bool NegateIndex =
false;
88 bool IsForLEA =
false;
90 X86ISelAddressMode() =
default;
92 bool hasSymbolicDisplacement()
const {
93 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr ||
94 MCSym !=
nullptr || JT != -1 || BlockAddr !=
nullptr;
97 bool hasBaseOrIndexReg()
const {
98 return BaseType == FrameIndexBase ||
99 IndexReg.getNode() !=
nullptr || Base_Reg.getNode() !=
nullptr;
104 if (BaseType != RegBase)
return false;
105 if (RegisterSDNode *RegNode =
107 return RegNode->getReg() == X86::RIP;
111 void setBaseReg(SDValue
Reg) {
116#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
117 void dump(SelectionDAG *DAG =
nullptr) {
118 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
119 dbgs() <<
"Base_Reg ";
120 if (Base_Reg.getNode())
121 Base_Reg.getNode()->dump(DAG);
124 if (BaseType == FrameIndexBase)
125 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
126 dbgs() <<
" Scale " << Scale <<
'\n'
130 if (IndexReg.getNode())
131 IndexReg.getNode()->dump(DAG);
134 dbgs() <<
" Disp " << Disp <<
'\n'
156 dbgs() <<
" JT" << JT <<
" Align" << Alignment.value() <<
'\n';
170 const X86Subtarget *Subtarget;
176 bool IndirectTlsSegRefs;
179 X86DAGToDAGISel() =
delete;
181 explicit X86DAGToDAGISel(X86TargetMachine &tm,
CodeGenOptLevel OptLevel)
182 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr),
183 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
189 "indirect-tls-seg-refs");
196 void emitFunctionEntryCode()
override;
198 bool IsProfitableToFold(SDValue
N, SDNode *U, SDNode *Root)
const override;
200 void PreprocessISelDAG()
override;
201 void PostprocessISelDAG()
override;
204#include "X86GenDAGISel.inc"
207 void Select(SDNode *
N)
override;
209 bool foldOffsetIntoAddress(
uint64_t Offset, X86ISelAddressMode &AM);
210 bool matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
211 bool AllowSegmentRegForX32 =
false);
212 bool matchWrapper(SDValue
N, X86ISelAddressMode &AM);
213 bool matchAddress(SDValue
N, X86ISelAddressMode &AM);
214 bool matchVectorAddress(SDValue
N, X86ISelAddressMode &AM);
215 bool matchAdd(SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
216 bool hasMaterializingUse(SDValue V)
const;
217 SDValue matchIndexRecursively(SDValue
N, X86ISelAddressMode &AM,
219 bool matchAddressRecursively(SDValue
N, X86ISelAddressMode &AM,
221 bool matchVectorAddressRecursively(SDValue
N, X86ISelAddressMode &AM,
223 bool matchAddressBase(SDValue
N, X86ISelAddressMode &AM);
224 bool selectAddr(SDNode *Parent, SDValue
N, SDValue &
Base, SDValue &Scale,
225 SDValue &Index, SDValue &Disp, SDValue &Segment,
226 bool HasNDDM =
true);
227 bool selectNDDAddr(SDNode *Parent, SDValue
N, SDValue &
Base, SDValue &Scale,
228 SDValue &Index, SDValue &Disp, SDValue &Segment);
229 bool selectVectorAddr(MemSDNode *Parent, SDValue BasePtr, SDValue IndexOp,
230 SDValue ScaleOp, SDValue &
Base, SDValue &Scale,
231 SDValue &Index, SDValue &Disp, SDValue &Segment);
232 bool selectMOV64Imm32(SDValue
N, SDValue &
Imm);
233 bool selectLEAAddr(SDValue
N, SDValue &
Base,
234 SDValue &Scale, SDValue &Index, SDValue &Disp,
236 bool selectLEA64_Addr(SDValue
N, SDValue &
Base, SDValue &Scale,
237 SDValue &Index, SDValue &Disp, SDValue &Segment);
238 bool selectTLSADDRAddr(SDValue
N, SDValue &
Base,
239 SDValue &Scale, SDValue &Index, SDValue &Disp,
241 bool selectRelocImm(SDValue
N, SDValue &
Op);
243 bool tryFoldLoad(SDNode *Root, SDNode *
P, SDValue
N,
244 SDValue &
Base, SDValue &Scale,
245 SDValue &Index, SDValue &Disp,
249 bool tryFoldLoad(SDNode *
P, SDValue
N,
250 SDValue &
Base, SDValue &Scale,
251 SDValue &Index, SDValue &Disp,
253 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
256 bool tryFoldBroadcast(SDNode *Root, SDNode *
P, SDValue
N,
257 SDValue &
Base, SDValue &Scale,
258 SDValue &Index, SDValue &Disp,
261 bool isProfitableToFormMaskedOp(SDNode *
N)
const;
264 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
266 std::vector<SDValue> &OutOps)
override;
268 void emitSpecialCodeForMain();
270 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
271 MVT VT, SDValue &
Base, SDValue &Scale,
272 SDValue &Index, SDValue &Disp,
274 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
275 Base = CurDAG->getTargetFrameIndex(
276 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
277 else if (AM.Base_Reg.
getNode())
280 Base = CurDAG->getRegister(0, VT);
282 Scale = getI8Imm(AM.Scale,
DL);
284#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
285#define GET_NDM_IF_ENABLED(OPC) \
286 (Subtarget->hasNDD() && Subtarget->hasNDDM() ? OPC##_ND : OPC)
288 if (AM.NegateIndex) {
306 SDValue Neg = SDValue(CurDAG->getMachineNode(NegOpc,
DL, VT, MVT::i32,
314 Index = CurDAG->getRegister(0, VT);
319 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(),
323 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
324 AM.Disp, AM.SymbolFlags);
326 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
327 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
328 }
else if (AM.MCSym) {
329 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
330 assert(AM.SymbolFlags == 0 &&
"oo");
331 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
332 }
else if (AM.JT != -1) {
333 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
334 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
335 }
else if (AM.BlockAddr)
336 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
339 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
342 Segment = AM.Segment;
344 Segment = CurDAG->getRegister(0, MVT::i16);
349 bool isAMXSDNode(SDNode *
N)
const {
353 for (
unsigned Idx = 0,
E =
N->getNumValues(); Idx !=
E; ++Idx) {
354 if (
N->getValueType(Idx) == MVT::x86amx)
357 for (
unsigned Idx = 0,
E =
N->getNumOperands(); Idx !=
E; ++Idx) {
358 SDValue
Op =
N->getOperand(Idx);
359 if (
Op.getValueType() == MVT::x86amx)
371 bool shouldAvoidImmediateInstFormsForSize(SDNode *
N)
const {
372 uint32_t UseCount = 0;
377 if (!CurDAG->shouldOptForSize())
381 for (
const SDNode *User :
N->users()) {
387 if (
User->isMachineOpcode()) {
394 User->getOperand(1).getNode() ==
N) {
405 if (
User->getNumOperands() != 2)
418 if (
User->getOpcode() == X86ISD::ADD ||
420 User->getOpcode() == X86ISD::SUB ||
424 SDValue OtherOp =
User->getOperand(0);
426 OtherOp =
User->getOperand(1);
429 RegisterSDNode *RegNode;
433 if ((RegNode->
getReg() == X86::ESP) ||
434 (RegNode->
getReg() == X86::RSP))
443 return (UseCount > 1);
447 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &
DL) {
448 return CurDAG->getTargetConstant(
Imm,
DL, MVT::i8);
452 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &
DL) {
453 return CurDAG->getTargetConstant(
Imm,
DL, MVT::i32);
458 return CurDAG->getTargetConstant(
Imm,
DL, MVT::i64);
461 SDValue getExtractVEXTRACTImmediate(SDNode *
N,
unsigned VecWidth,
463 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
465 MVT VecVT =
N->getOperand(0).getSimpleValueType();
469 SDValue getInsertVINSERTImmediate(SDNode *
N,
unsigned VecWidth,
471 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
473 MVT VecVT =
N->getSimpleValueType(0);
477 SDValue getPermuteVINSERTCommutedImmediate(SDNode *
N,
unsigned VecWidth,
479 assert(VecWidth == 128 &&
"Unexpected vector width");
481 MVT VecVT =
N->getSimpleValueType(0);
483 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
486 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
489 SDValue getSBBZero(SDNode *
N) {
491 MVT VT =
N->getSimpleValueType(0);
494 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
496 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
497 if (VT == MVT::i64) {
499 CurDAG->getMachineNode(
500 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, Zero,
501 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
506 unsigned Opcode =
N->getOpcode();
507 assert((Opcode == X86ISD::SBB || Opcode == X86ISD::SETCC_CARRY) &&
508 "Unexpected opcode for SBB materialization");
509 unsigned FlagOpIndex = Opcode == X86ISD::SBB ? 2 : 1;
511 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
512 N->getOperand(FlagOpIndex), SDValue());
516 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
517 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
518 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
520 CurDAG->getMachineNode(
Opc, dl, VTs,
521 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
527 bool isUnneededShiftMask(SDNode *
N,
unsigned Width)
const {
529 const APInt &Val =
N->getConstantOperandAPInt(1);
534 APInt
Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
535 return Mask.countr_one() >= Width;
544 bool isDef32(SDNode *
N)
const {
545 unsigned Opc =
N->getOpcode();
550 !((
Opc == X86ISD::BSF ||
Opc == X86ISD::BSR) &&
558 SDNode *getGlobalBaseReg();
562 const X86TargetMachine &getTargetMachine()
const {
563 return static_cast<const X86TargetMachine &
>(TM);
568 const X86InstrInfo *getInstrInfo()
const {
569 return Subtarget->getInstrInfo();
578 bool ComplexPatternFuncMutatesDAG()
const override {
582 bool isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const;
585 bool useNonTemporalLoad(LoadSDNode *
N)
const {
586 if (!
N->isNonTemporal())
589 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
591 if (
N->getAlign().value() < StoreSize)
600 return Subtarget->hasSSE41();
602 return Subtarget->hasAVX2();
604 return Subtarget->hasAVX512();
608 bool foldLoadStoreIntoMemOperand(SDNode *Node);
609 MachineSDNode *matchBEXTRFromAndImm(SDNode *Node);
610 bool matchBitExtract(SDNode *Node);
611 bool shrinkAndImmediate(SDNode *
N);
612 bool isMaskZeroExtended(SDNode *
N)
const;
613 bool tryShiftAmountMod(SDNode *
N);
614 bool tryShrinkShlLogicImm(SDNode *
N);
615 bool tryVPTERNLOG(SDNode *
N);
616 bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentB,
617 SDNode *ParentC, SDValue
A, SDValue
B, SDValue
C,
619 bool tryVPTESTM(SDNode *Root, SDValue Setcc, SDValue Mask);
620 bool tryMatchBitSelect(SDNode *
N);
622 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
623 const SDLoc &dl, MVT VT, SDNode *Node);
624 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
625 const SDLoc &dl, MVT VT, SDNode *Node,
628 bool tryOptimizeRem8Extend(SDNode *
N);
630 bool onlyUsesZeroFlag(SDValue Flags)
const;
631 bool hasNoSignFlagUses(SDValue Flags)
const;
632 bool hasNoCarryFlagUses(SDValue Flags)
const;
633 bool checkTCRetEnoughRegs(SDNode *
N)
const;
639 explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm,
641 : SelectionDAGISelLegacy(
642 ID, std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
646char X86DAGToDAGISelLegacy::ID = 0;
653 unsigned Opcode =
N->getOpcode();
654 if (Opcode == X86ISD::CMPM || Opcode == X86ISD::CMPMM ||
655 Opcode == X86ISD::STRICT_CMPM || Opcode ==
ISD::SETCC ||
656 Opcode == X86ISD::CMPMM_SAE || Opcode == X86ISD::VFPCLASS) {
660 EVT OpVT =
N->getOperand(0).getValueType();
663 if (Opcode == X86ISD::STRICT_CMPM)
664 OpVT =
N->getOperand(1).getValueType();
666 return Subtarget->hasVLX();
671 if (Opcode == X86ISD::VFPCLASSS || Opcode == X86ISD::FSETCCM ||
672 Opcode == X86ISD::FSETCCM_SAE)
680bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
692X86DAGToDAGISel::IsProfitableToFold(SDValue
N, SDNode *U, SDNode *Root)
const {
693 if (OptLevel == CodeGenOptLevel::None)
708 switch (
U->getOpcode()) {
722 SDValue Op1 =
U->getOperand(1);
735 if (
Imm->getAPIntValue().isSignedIntN(8))
744 Imm->getAPIntValue().getBitWidth() == 64 &&
745 Imm->getAPIntValue().isIntN(32))
752 (
Imm->getAPIntValue() == UINT8_MAX ||
753 Imm->getAPIntValue() == UINT16_MAX ||
754 Imm->getAPIntValue() == UINT32_MAX))
760 (-
Imm->getAPIntValue()).isSignedIntN(8))
763 if ((
U->getOpcode() == X86ISD::ADD ||
U->getOpcode() == X86ISD::SUB) &&
764 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
765 hasNoCarryFlagUses(SDValue(U, 1)))
779 if (Op1.
getOpcode() == X86ISD::Wrapper) {
790 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
794 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
799 SDValue U0 =
U->getOperand(0);
800 SDValue U1 =
U->getOperand(1);
803 if (
C &&
C->getSExtValue() == -2)
809 if (
C &&
C->getSExtValue() == -2)
844bool X86DAGToDAGISel::isProfitableToFormMaskedOp(SDNode *
N)
const {
846 (
N->getOpcode() ==
ISD::VSELECT ||
N->getOpcode() == X86ISD::SELECTS) &&
847 "Unexpected opcode!");
852 return N->getOperand(1).hasOneUse();
862 Ops.push_back(
Load.getOperand(0));
865 "Unexpected chain operand");
868 Ops.push_back(
Load.getOperand(0));
874 Ops.push_back(NewChain);
879 Load.getOperand(1),
Load.getOperand(2));
897 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
909 if (!Callee.getValue(1).hasOneUse())
940 Callee.getValue(1).hasOneUse())
958 const unsigned NumBytes =
BitWidth / 8;
962 const uint8_t OptionalPrefixBytes[] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
963 0x65, 0x66, 0x67, 0xf0, 0xf2};
965 for (
unsigned I = 0;
I != NumBytes; ++
I)
966 Bytes[
I] = (
Imm >> (
I * 8)) & 0xFF;
968 for (
unsigned I = 0;
I + 3 < NumBytes; ++
I) {
969 if (Bytes[
I] != 0xf3)
976 if (J + 2 < NumBytes && Bytes[J] == 0x0f && Bytes[J + 1] == 0x1e &&
977 (Bytes[J + 2] == 0xfa || Bytes[J + 2] == 0xfb))
985 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
988void X86DAGToDAGISel::PreprocessISelDAG() {
989 bool MadeChange =
false;
991 E = CurDAG->allnodes_end();
I !=
E; ) {
1009 MVT VT =
N->getSimpleValueType(0);
1011 "ISD::Constant must have a scalar integer type");
1020 "cf-protection-branch");
1025 SDValue Complement =
1026 CurDAG->getConstant(ComplementImm, dl, VT,
false,
true);
1027 Complement = CurDAG->getNOT(dl, Complement, VT);
1029 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Complement);
1039 if (
N->getOpcode() == X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
1040 SDValue Res = CurDAG->getNode(
ISD::AND, SDLoc(
N),
N->getValueType(0),
1041 N->getOperand(0),
N->getOperand(1));
1043 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1067 auto mayPreventLoadFold = [&]() {
1069 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1070 !
N->getOperand(1).hasOneUse();
1073 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1081 MVT VT =
N->getSimpleValueType(0);
1089 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1091 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1098 switch (
N->getOpcode()) {
1099 case X86ISD::VBROADCAST: {
1100 MVT VT =
N->getSimpleValueType(0);
1102 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1105 SDValue NarrowBCast =
1106 CurDAG->getNode(X86ISD::VBROADCAST, dl, NarrowVT,
N->getOperand(0));
1109 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1112 CurDAG->getIntPtrConstant(Index, dl));
1115 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1123 case X86ISD::VBROADCAST_LOAD: {
1124 MVT VT =
N->getSimpleValueType(0);
1126 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1130 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1131 SDValue
Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1132 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1133 X86ISD::VBROADCAST_LOAD, dl, VTs,
Ops, MemNode->getMemoryVT(),
1134 MemNode->getMemOperand());
1137 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1140 CurDAG->getIntPtrConstant(Index, dl));
1143 SDValue To[] = {Res, NarrowBCast.
getValue(1)};
1144 CurDAG->ReplaceAllUsesWith(
N, To);
1156 MVT VT =
N->getSimpleValueType(0);
1162 SDNode *MaxLd =
nullptr;
1163 SDValue Ptr = Ld->getBasePtr();
1164 SDValue Chain = Ld->getChain();
1165 for (SDNode *User : Ptr->
users()) {
1167 MVT UserVT =
User->getSimpleValueType(0);
1169 UserLd->getBasePtr() == Ptr && UserLd->getChain() == Chain &&
1170 !
User->hasAnyUseOfValue(1) &&
1184 CurDAG->getIntPtrConstant(0, dl));
1185 SDValue Res = CurDAG->getBitcast(VT, Extract);
1188 SDValue To[] = {Res, SDValue(MaxLd, 1)};
1189 CurDAG->ReplaceAllUsesWith(
N, To);
1198 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1199 if (EleVT == MVT::i1)
1202 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1203 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1204 "We can't replace VSELECT with BLENDV in vXi16!");
1206 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1208 R = CurDAG->getNode(X86ISD::VPTERNLOG, SDLoc(
N),
N->getValueType(0),
1209 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1210 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1212 R = CurDAG->getNode(X86ISD::BLENDV, SDLoc(
N),
N->getValueType(0),
1213 N->getOperand(0),
N->getOperand(1),
1217 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1230 if (!
N->getSimpleValueType(0).isVector())
1234 switch (
N->getOpcode()) {
1244 if (
N->isStrictFPOpcode())
1246 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1247 {
N->getOperand(0),
N->getOperand(1)});
1250 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1253 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1263 if (!
N->getValueType(0).isVector())
1267 switch (
N->getOpcode()) {
1269 case ISD::SHL: NewOpc = X86ISD::VSHLV;
break;
1270 case ISD::SRA: NewOpc = X86ISD::VSRAV;
break;
1271 case ISD::SRL: NewOpc = X86ISD::VSRLV;
break;
1273 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1274 N->getOperand(0),
N->getOperand(1));
1276 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1285 if (!
N->getValueType(0).isVector())
1289 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1291 "Unexpected opcode for mask vector!");
1299 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1302 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1322 switch (
N->getOpcode()) {
1338 bool IsStrict =
N->isStrictFPOpcode();
1341 Res = CurDAG->getNode(X86ISD::STRICT_VRNDSCALE, dl,
1342 {
N->getValueType(0), MVT::Other},
1343 {
N->getOperand(0),
N->getOperand(1),
1344 CurDAG->getTargetConstant(
Imm, dl, MVT::i32)});
1346 Res = CurDAG->getNode(X86ISD::VRNDSCALE, dl,
N->getValueType(0),
1348 CurDAG->getTargetConstant(
Imm, dl, MVT::i32));
1350 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1358 case X86ISD::FXOR: {
1361 MVT VT =
N->getSimpleValueType(0);
1362 if (VT.
isVector() || VT == MVT::f128)
1365 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1366 : VT == MVT::f32 ? MVT::v4f32
1376 if (Subtarget->hasSSE2()) {
1377 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1381 switch (
N->getOpcode()) {
1383 case X86ISD::FANDN:
Opc = X86ISD::ANDNP;
break;
1388 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1391 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1394 CurDAG->getIntPtrConstant(0, dl));
1396 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1403 if (OptLevel != CodeGenOptLevel::None &&
1406 !Subtarget->useIndirectThunkCalls() &&
1407 ((
N->getOpcode() == X86ISD::CALL && !Subtarget->slowTwoMemOps() &&
1408 !Subtarget->slowIndirectCall()) ||
1409 (
N->getOpcode() == X86ISD::TC_RETURN &&
1410 (Subtarget->is64Bit() ||
1411 !getTargetMachine().isPositionIndependent())))) {
1431 bool HasCallSeq =
N->getOpcode() == X86ISD::CALL;
1436 if (
N->getOpcode() == X86ISD::TC_RETURN && !checkTCRetEnoughRegs(
N))
1452 switch (
N->getOpcode()) {
1457 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1458 MVT DstVT =
N->getSimpleValueType(0);
1466 const X86TargetLowering *X86Lowering =
1467 static_cast<const X86TargetLowering *
>(TLI);
1470 if (SrcIsSSE && DstIsSSE)
1473 if (!SrcIsSSE && !DstIsSSE) {
1478 if (
N->getConstantOperandVal(1))
1486 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1488 MachinePointerInfo MPI =
1494 SDValue
Store = CurDAG->getTruncStore(
1495 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1497 MemTmp, MPI, MemVT);
1504 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Result);
1513 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1514 MVT DstVT =
N->getSimpleValueType(0);
1522 const X86TargetLowering *X86Lowering =
1523 static_cast<const X86TargetLowering *
>(TLI);
1526 if (SrcIsSSE && DstIsSSE)
1529 if (!SrcIsSSE && !DstIsSSE) {
1534 if (
N->getConstantOperandVal(2))
1542 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1544 MachinePointerInfo MPI =
1553 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1554 SDValue
Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1555 Store = CurDAG->getMemIntrinsicNode(X86ISD::FST, dl, VTs,
Ops, MemVT,
1558 if (
N->getFlags().hasNoFPExcept()) {
1560 Flags.setNoFPExcept(
true);
1561 Store->setFlags(Flags);
1564 assert(SrcVT == MemVT &&
"Unexpected VT!");
1565 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1570 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1572 Result = CurDAG->getMemIntrinsicNode(
1573 X86ISD::FLD, dl, VTs,
Ops, MemVT, MPI,
1575 if (
N->getFlags().hasNoFPExcept()) {
1577 Flags.setNoFPExcept(
true);
1581 assert(DstVT == MemVT &&
"Unexpected VT!");
1582 Result = CurDAG->getLoad(DstVT, dl,
Store, MemTmp, MPI);
1590 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1604 CurDAG->RemoveDeadNodes();
1608bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1609 unsigned Opc =
N->getMachineOpcode();
1610 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1611 Opc != X86::MOVSX64rr8)
1614 SDValue N0 =
N->getOperand(0);
1623 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1624 : X86::MOVSX32rr8_NOREX;
1629 if (
Opc == X86::MOVSX64rr8) {
1632 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1634 ReplaceUses(
N, Extend);
1643void X86DAGToDAGISel::PostprocessISelDAG() {
1645 if (TM.getOptLevel() == CodeGenOptLevel::None)
1650 bool MadeChange =
false;
1651 while (Position != CurDAG->allnodes_begin()) {
1652 SDNode *
N = &*--Position;
1654 if (
N->use_empty() || !
N->isMachineOpcode())
1657 if (tryOptimizeRem8Extend(
N)) {
1662 unsigned Opc =
N->getMachineOpcode();
1673 case X86::CTEST16rr:
1674 case X86::CTEST32rr:
1675 case X86::CTEST64rr: {
1681#define CASE_ND(OP) \
1684 switch (
And.getMachineOpcode()) {
1691 if (
And->hasAnyUseOfValue(1))
1694 Ops[0] =
And.getOperand(0);
1695 Ops[1] =
And.getOperand(1);
1696 MachineSDNode *
Test =
1697 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1698 ReplaceUses(
N,
Test);
1706 if (
And->hasAnyUseOfValue(1))
1709 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1710#define FROM_TO(A, B) \
1711 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1713 switch (
And.getMachineOpcode()) {
1723 And.getOperand(3),
And.getOperand(4),
1724 And.getOperand(5),
And.getOperand(0)};
1727 Ops.push_back(
N->getOperand(2));
1728 Ops.push_back(
N->getOperand(3));
1731 Ops.push_back(
And.getOperand(6));
1734 Ops.push_back(
N->getOperand(4));
1736 MachineSDNode *
Test = CurDAG->getMachineNode(
1737 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1738 CurDAG->setNodeMemRefs(
1740 ReplaceUses(
And.getValue(2), SDValue(
Test, 1));
1741 ReplaceUses(SDValue(
N, 0), SDValue(
Test, 0));
1751 case X86::KORTESTBkk:
1752 case X86::KORTESTWkk:
1753 case X86::KORTESTDkk:
1754 case X86::KORTESTQkk: {
1756 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1771#define FROM_TO(A, B) \
1783 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1786 MachineSDNode *KTest = CurDAG->getMachineNode(
1788 ReplaceUses(
N, KTest);
1793 case TargetOpcode::SUBREG_TO_REG: {
1794 unsigned SubRegIdx =
N->getConstantOperandVal(1);
1795 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1798 SDValue Move =
N->getOperand(0);
1812 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1813 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1814 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1815 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1816 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1817 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1818 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1819 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1824 if (!
In.isMachineOpcode() ||
1825 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1830 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1838 CurDAG->UpdateNodeOperands(
N, In,
N->getOperand(1));
1845 CurDAG->RemoveDeadNodes();
1850void X86DAGToDAGISel::emitSpecialCodeForMain() {
1851 if (Subtarget->isTargetCygMing()) {
1852 TargetLowering::ArgListTy
Args;
1853 auto &
DL = CurDAG->getDataLayout();
1855 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1856 CLI.setChain(CurDAG->getRoot())
1857 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1858 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1860 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1862 CurDAG->setRoot(
Result.second);
1866void X86DAGToDAGISel::emitFunctionEntryCode() {
1869 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1870 emitSpecialCodeForMain();
1884 X86ISelAddressMode &AM) {
1889 int64_t Val = AM.Disp +
Offset;
1892 if (Val != 0 && (AM.ES || AM.MCSym))
1896 if (Subtarget->is64Bit()) {
1899 AM.hasSymbolicDisplacement()))
1903 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1922 if (Subtarget->isTarget64BitILP32() &&
1924 !AM.hasBaseOrIndexReg())
1926 }
else if (Subtarget->is16Bit()) {
1929 if (Val < -(int64_t)UINT16_MAX || Val > (int64_t)UINT16_MAX)
1939bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1940 bool AllowSegmentRegForX32) {
1941 SDValue
Address =
N->getOperand(1);
1953 !IndirectTlsSegRefs &&
1954 (Subtarget->isTargetGlibc() || Subtarget->isTargetMusl() ||
1955 Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())) {
1956 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1958 switch (
N->getPointerInfo().getAddrSpace()) {
1960 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1963 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1976bool X86DAGToDAGISel::matchWrapper(SDValue
N, X86ISelAddressMode &AM) {
1979 if (AM.hasSymbolicDisplacement())
1982 bool IsRIPRelTLS =
false;
1983 bool IsRIPRel =
N.getOpcode() == X86ISD::WrapperRIP;
1985 SDValue Val =
N.getOperand(0);
2000 if (IsRIPRel && AM.hasBaseOrIndexReg())
2004 X86ISelAddressMode Backup = AM;
2009 AM.GV =
G->getGlobal();
2010 AM.SymbolFlags =
G->getTargetFlags();
2013 AM.CP = CP->getConstVal();
2014 AM.Alignment = CP->getAlign();
2015 AM.SymbolFlags = CP->getTargetFlags();
2016 Offset = CP->getOffset();
2018 AM.ES = S->getSymbol();
2019 AM.SymbolFlags = S->getTargetFlags();
2021 AM.MCSym = S->getMCSymbol();
2023 AM.JT = J->getIndex();
2024 AM.SymbolFlags = J->getTargetFlags();
2026 AM.BlockAddr = BA->getBlockAddress();
2027 AM.SymbolFlags = BA->getTargetFlags();
2028 Offset = BA->getOffset();
2033 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
2034 TM.isLargeGlobalValue(AM.GV)) {
2039 if (foldOffsetIntoAddress(
Offset, AM)) {
2045 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
2053bool X86DAGToDAGISel::matchAddress(SDValue
N, X86ISelAddressMode &AM) {
2054 if (matchAddressRecursively(
N, AM, 0))
2061 if (Subtarget->isTarget64BitILP32() &&
2062 AM.BaseType == X86ISelAddressMode::RegBase &&
2063 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
2064 SDValue Save_Base_Reg = AM.Base_Reg;
2066 AM.Base_Reg = SDValue();
2067 if (matchLoadInAddress(LoadN, AM,
true))
2068 AM.Base_Reg = Save_Base_Reg;
2077 if (AM.Scale == 2 && !AM.NegateIndex &&
2078 AM.BaseType == X86ISelAddressMode::RegBase &&
2079 AM.Base_Reg.
getNode() ==
nullptr) {
2080 AM.Base_Reg = AM.IndexReg;
2087 (!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2088 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2089 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2101 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2114bool X86DAGToDAGISel::hasMaterializingUse(SDValue V)
const {
2115 const TargetInstrInfo *
TII = Subtarget->getInstrInfo();
2116 for (SDUse &U :
V->uses()) {
2117 if (
U.getResNo() !=
V.getResNo())
2119 SDNode *
User =
U.getUser();
2125 if (St->getValue() == V)
2136 if (!
User->isMachineOpcode())
2138 const MCInstrDesc &
Desc =
TII->get(
User->getMachineOpcode());
2139 if (!
Desc.mayStore())
2142 if (MemRefBegin < 0)
2145 for (
unsigned I = 0,
E =
User->getNumOperands();
I !=
E; ++
I) {
2146 if (
I >=
static_cast<unsigned>(MemRefBegin) &&
I < MemRefEnd)
2148 SDValue Opnd =
User->getOperand(
I);
2158bool X86DAGToDAGISel::matchAdd(SDValue &
N, X86ISelAddressMode &AM,
2162 HandleSDNode Handle(
N);
2164 auto IsAddOrAddLike = [&](SDValue
V) {
2165 return V.getOpcode() ==
ISD::ADD || CurDAG->isADDLike(V);
2174 auto SplitsMaterializedValue = [&](SDValue
Op) {
2175 if (!AM.IsForLEA || !hasMaterializingUse(
Op))
2179 if (IsAddOrAddLike(
Op))
2180 return IsAddOrAddLike(
Op.getOperand(0)) ||
2181 IsAddOrAddLike(
Op.getOperand(1));
2186 return C->getZExtValue() >= 1 &&
C->getZExtValue() <= 3 &&
2187 IsAddOrAddLike(
Op.getOperand(0));
2197 auto MatchOperand = [&](SDValue
Op) {
2207 if (SplitsMaterializedValue(
Op) && !AM.isRIPRelative())
2208 return matchAddressBase(
Op, AM);
2209 return matchAddressRecursively(
Op, AM,
Depth + 1);
2212 X86ISelAddressMode Backup = AM;
2213 if (!MatchOperand(
N.getOperand(0)) &&
2214 !MatchOperand(Handle.getValue().getOperand(1)))
2219 if (!MatchOperand(Handle.getValue().getOperand(1)) &&
2220 !MatchOperand(Handle.getValue().getOperand(0)))
2227 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2230 N = Handle.getValue();
2236 N = Handle.getValue();
2246 if (
N->getNodeId() == -1 ||
2266 X86ISelAddressMode &AM) {
2273 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2274 Mask != (0xffu << ScaleLog))
2277 MVT XVT =
X.getSimpleValueType();
2278 MVT VT =
N.getSimpleValueType();
2303 AM.Scale = (1 << ScaleLog);
2311 X86ISelAddressMode &AM) {
2322 bool FoundAnyExtend =
false;
2326 FoundAnyExtend =
true;
2344 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2347 MVT VT =
N.getSimpleValueType();
2349 if (FoundAnyExtend) {
2370 AM.Scale = 1 << ShiftAmt;
2371 AM.IndexReg = NewAnd;
2405 X86ISelAddressMode &AM) {
2411 unsigned MaskIdx, MaskLen;
2414 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2420 unsigned AMShiftAmt = MaskIdx;
2424 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2428 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2429 if (MaskLZ < ScaleDown)
2431 MaskLZ -= ScaleDown;
2439 bool ReplacingAnyExtend =
false;
2441 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2442 X.getOperand(0).getSimpleValueType().getSizeInBits();
2445 X =
X.getOperand(0);
2446 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2447 ReplacingAnyExtend =
true;
2449 APInt MaskedHighBits =
2456 MVT VT =
N.getSimpleValueType();
2457 if (ReplacingAnyExtend) {
2458 assert(
X.getValueType() != VT);
2465 MVT XVT =
X.getSimpleValueType();
2486 AM.Scale = 1 << AMShiftAmt;
2487 AM.IndexReg = NewExt;
2497 X86ISelAddressMode &AM,
2505 if (!Subtarget.hasTBM() &&
2506 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2510 unsigned MaskIdx, MaskLen;
2518 unsigned AMShiftAmt = MaskIdx;
2522 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2524 MVT XVT =
X.getSimpleValueType();
2525 MVT VT =
N.getSimpleValueType();
2550 AM.Scale = 1 << AMShiftAmt;
2551 AM.IndexReg = NewExt;
2557SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue
N,
2558 X86ISelAddressMode &AM,
2560 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2561 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2562 "Illegal index scale");
2568 EVT VT =
N.getValueType();
2569 unsigned Opc =
N.getOpcode();
2572 if (CurDAG->isBaseWithConstantOffset(
N)) {
2575 if (!foldOffsetIntoAddress(
Offset, AM))
2576 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2580 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2581 if (AM.Scale <= 4) {
2583 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2588 if (
Opc == X86ISD::VSHLI) {
2589 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2590 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2591 if ((AM.Scale * ScaleAmt) <= 8) {
2592 AM.Scale *= ScaleAmt;
2593 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2600 SDValue Src =
N.getOperand(0);
2601 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2603 if (CurDAG->isBaseWithConstantOffset(Src)) {
2604 SDValue AddSrc = Src.getOperand(0);
2606 int64_t
Offset = AddVal->getSExtValue();
2609 SDValue ExtSrc = CurDAG->getNode(
Opc,
DL, VT, AddSrc);
2610 SDValue ExtVal = CurDAG->getSignedConstant(
Offset,
DL, VT);
2611 SDValue ExtAdd = CurDAG->getNode(
ISD::ADD,
DL, VT, ExtSrc, ExtVal);
2615 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2616 CurDAG->RemoveDeadNode(
N.getNode());
2627 SDValue Src =
N.getOperand(0);
2628 unsigned SrcOpc = Src.getOpcode();
2629 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2630 CurDAG->isADDLike(Src,
true)) &&
2632 if (CurDAG->isBaseWithConstantOffset(Src)) {
2633 SDValue AddSrc = Src.getOperand(0);
2635 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2646 if ((AM.Scale * ScaleAmt) <= 8 &&
2648 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2649 AM.Scale *= ScaleAmt;
2650 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2651 SDValue ExtShift = CurDAG->getNode(
ISD::SHL,
DL, VT, ExtShVal,
2659 SDValue ExtSrc = CurDAG->getNode(
Opc,
DL, VT, AddSrc);
2660 SDValue ExtVal = CurDAG->getConstant(
Offset,
DL, VT);
2661 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2665 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2666 CurDAG->RemoveDeadNode(
N.getNode());
2667 return Res ? Res : ExtSrc;
2677bool X86DAGToDAGISel::matchAddressRecursively(SDValue
N, X86ISelAddressMode &AM,
2680 dbgs() <<
"MatchAddress: ";
2685 return matchAddressBase(
N, AM);
2690 if (AM.isRIPRelative()) {
2694 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2698 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2703 switch (
N.getOpcode()) {
2706 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2709 AM.MCSym = ESNode->getMCSymbol();
2716 if (!foldOffsetIntoAddress(Val, AM))
2721 case X86ISD::Wrapper:
2722 case X86ISD::WrapperRIP:
2723 if (!matchWrapper(
N, AM))
2733 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2734 AM.Base_Reg.
getNode() ==
nullptr &&
2736 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2743 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2747 unsigned Val = CN->getZExtValue();
2752 if (Val == 1 || Val == 2 || Val == 3) {
2754 AM.Scale = 1 << Val;
2755 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2763 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2767 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2768 "Unexpected value size!");
2770 SDValue
And =
N.getOperand(0);
2772 SDValue
X =
And.getOperand(0);
2780 uint64_t Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2792 if (
N.getResNo() != 0)
break;
2795 case X86ISD::MUL_IMM:
2797 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2798 AM.Base_Reg.
getNode() ==
nullptr &&
2799 AM.IndexReg.
getNode() ==
nullptr) {
2801 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2802 CN->getZExtValue() == 9) {
2803 AM.Scale = unsigned(CN->getZExtValue())-1;
2805 SDValue MulVal =
N.getOperand(0);
2815 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2816 if (foldOffsetIntoAddress(Disp, AM))
2817 Reg =
N.getOperand(0);
2819 Reg =
N.getOperand(0);
2822 AM.IndexReg = AM.Base_Reg =
Reg;
2840 HandleSDNode Handle(
N);
2843 X86ISelAddressMode Backup = AM;
2844 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2845 N = Handle.getValue();
2849 N = Handle.getValue();
2851 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2857 SDValue
RHS =
N.getOperand(1);
2870 std::optional<unsigned> NegScale;
2873 uint64_t ShVal = ShAmt->getZExtValue();
2874 if (ShVal >= 1 && ShVal <= 3) {
2875 NegScale = 1u << ShVal;
2893 RHS.getOperand(0).getValueType() == MVT::i32))
2896 bool BaseIsNegatedValue = NegScale &&
2897 AM.BaseType == X86ISelAddressMode::RegBase &&
2904 if (((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2906 AM.BaseType == X86ISelAddressMode::FrameIndexBase) &&
2907 !BaseIsNegatedValue)
2911 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2912 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2925 AM.NegateIndex =
true;
2926 AM.Scale = NegScale.value_or(1);
2933 if (!CurDAG->isADDLike(
N))
2937 if (!matchAdd(
N, AM,
Depth))
2946 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2950 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2951 "Unexpected value size!");
2956 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2957 SDValue Shift =
N.getOperand(0);
2985 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2988 SDValue Src =
N.getOperand(0);
2993 if (SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2995 AM.IndexReg =
Index;
3001 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
3003 Mask = MaskC->getAPIntValue();
3004 Src = Src.getOperand(0);
3007 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
3009 SDValue ShlSrc = Src.getOperand(0);
3010 SDValue ShlAmt = Src.getOperand(1);
3014 unsigned ShAmtV = ShAmtC->getZExtValue();
3022 if (!Src->getFlags().hasNoUnsignedWrap() &&
3023 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
3031 MVT VT =
N.getSimpleValueType();
3034 SDValue Res = ShlSrc;
3035 if (!
Mask.isAllOnes()) {
3036 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
3038 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
3043 SDValue NewShl = CurDAG->getNode(
ISD::SHL,
DL, VT, Zext, ShlAmt);
3045 CurDAG->ReplaceAllUsesWith(
N, NewShl);
3046 CurDAG->RemoveDeadNode(
N.getNode());
3049 AM.Scale = 1 << ShAmtV;
3053 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
3057 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
3060 Src.getOperand(0), AM))
3065 Src.getOperand(0), AM))
3070 Src.getOperand(0), AM, *Subtarget))
3078 return matchAddressBase(
N, AM);
3083bool X86DAGToDAGISel::matchAddressBase(SDValue
N, X86ISelAddressMode &AM) {
3085 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
3098 AM.BaseType = X86ISelAddressMode::RegBase;
3103bool X86DAGToDAGISel::matchVectorAddressRecursively(SDValue
N,
3104 X86ISelAddressMode &AM,
3107 dbgs() <<
"MatchVectorAddress: ";
3112 return matchAddressBase(
N, AM);
3115 switch (
N.getOpcode()) {
3118 if (!foldOffsetIntoAddress(Val, AM))
3122 case X86ISD::Wrapper:
3123 if (!matchWrapper(
N, AM))
3129 HandleSDNode Handle(
N);
3131 X86ISelAddressMode Backup = AM;
3132 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
3133 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
3139 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
3141 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
3146 N = Handle.getValue();
3151 return matchAddressBase(
N, AM);
3157bool X86DAGToDAGISel::matchVectorAddress(SDValue
N, X86ISelAddressMode &AM) {
3158 return matchVectorAddressRecursively(
N, AM, 0);
3161bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent, SDValue BasePtr,
3162 SDValue IndexOp, SDValue ScaleOp,
3163 SDValue &
Base, SDValue &Scale,
3164 SDValue &Index, SDValue &Disp,
3166 X86ISelAddressMode AM;
3172 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
3174 AM.IndexReg = IndexOp;
3178 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3180 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3182 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3185 MVT VT =
BasePtr.getSimpleValueType();
3188 if (matchVectorAddress(BasePtr, AM))
3191 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3202bool X86DAGToDAGISel::selectAddr(SDNode *Parent, SDValue
N, SDValue &
Base,
3203 SDValue &Scale, SDValue &Index, SDValue &Disp,
3204 SDValue &Segment,
bool HasNDDM) {
3205 X86ISelAddressMode AM;
3212 Parent->
getOpcode() != X86ISD::TLSCALL &&
3213 Parent->
getOpcode() != X86ISD::ENQCMD &&
3214 Parent->
getOpcode() != X86ISD::ENQCMDS &&
3215 Parent->
getOpcode() != X86ISD::EH_SJLJ_SETJMP &&
3216 Parent->
getOpcode() != X86ISD::EH_SJLJ_LONGJMP) {
3217 unsigned AddrSpace =
3220 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3222 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3224 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3229 MVT VT =
N.getSimpleValueType();
3231 if (matchAddress(
N, AM))
3234 if (!HasNDDM && !AM.isRIPRelative())
3237 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3241bool X86DAGToDAGISel::selectNDDAddr(SDNode *Parent, SDValue
N, SDValue &
Base,
3242 SDValue &Scale, SDValue &Index,
3243 SDValue &Disp, SDValue &Segment) {
3244 return selectAddr(Parent,
N,
Base, Scale, Index, Disp, Segment,
3245 Subtarget->hasNDDM());
3248bool X86DAGToDAGISel::selectMOV64Imm32(SDValue
N, SDValue &
Imm) {
3257 if (
N->getOpcode() != X86ISD::Wrapper)
3260 N =
N.getOperand(0);
3277 return CR->getUnsignedMax().ult(1ull << 32);
3279 return !TM.isLargeGlobalValue(GV);
3282bool X86DAGToDAGISel::selectLEA64_Addr(SDValue
N, SDValue &
Base, SDValue &Scale,
3283 SDValue &Index, SDValue &Disp,
3288 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3294 SubReg = X86::sub_8bit;
3296 SubReg = X86::sub_16bit;
3298 SubReg = X86::sub_32bit;
3301 if (RN &&
RN->getReg() == 0)
3302 Base = CurDAG->getRegister(0, MVT::i64);
3307 SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF,
DL,
3309 Base = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef,
Base);
3312 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3314 if (RN &&
RN->getReg() == 0)
3315 Index = CurDAG->getRegister(0, MVT::i64);
3318 "Expect to be extending 8/16/32-bit registers for use in LEA");
3319 SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF,
DL,
3321 Index = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef, Index);
3329bool X86DAGToDAGISel::selectLEAAddr(SDValue
N,
3330 SDValue &
Base, SDValue &Scale,
3331 SDValue &Index, SDValue &Disp,
3333 X86ISelAddressMode AM;
3338 MVT VT =
N.getSimpleValueType();
3342 SDValue
Copy = AM.Segment;
3343 SDValue
T = CurDAG->getRegister(0, MVT::i32);
3345 if (matchAddress(
N, AM))
3350 unsigned Complexity = 0;
3351 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3353 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3369 if (AM.hasSymbolicDisplacement()) {
3371 if (Subtarget->is64Bit())
3381 auto isMathWithFlags = [](SDValue
V) {
3382 switch (
V.getOpcode()) {
3396 return !SDValue(
V.getNode(), 1).use_empty();
3403 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3411 if (Complexity <= 2)
3414 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3419bool X86DAGToDAGISel::selectTLSADDRAddr(SDValue
N, SDValue &
Base,
3420 SDValue &Scale, SDValue &Index,
3421 SDValue &Disp, SDValue &Segment) {
3425 X86ISelAddressMode AM;
3427 AM.GV = GA->getGlobal();
3428 AM.Disp += GA->getOffset();
3429 AM.SymbolFlags = GA->getTargetFlags();
3432 AM.ES = SA->getSymbol();
3433 AM.SymbolFlags = SA->getTargetFlags();
3436 if (Subtarget->is32Bit()) {
3438 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3441 MVT VT =
N.getSimpleValueType();
3442 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3446bool X86DAGToDAGISel::selectRelocImm(SDValue
N, SDValue &
Op) {
3450 EVT VT =
N.getValueType();
3451 bool WasTruncated =
false;
3453 WasTruncated =
true;
3454 N =
N.getOperand(0);
3457 if (
N.getOpcode() != X86ISD::Wrapper)
3463 unsigned Opc =
N.getOperand(0)->getOpcode();
3465 Op =
N.getOperand(0);
3468 return !WasTruncated;
3473 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3474 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3478 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3479 GA->getOffset(), GA->getTargetFlags());
3483bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P, SDValue
N,
3484 SDValue &
Base, SDValue &Scale,
3485 SDValue &Index, SDValue &Disp,
3487 assert(Root &&
P &&
"Unknown root/parent nodes");
3489 !IsProfitableToFold(
N,
P, Root) ||
3490 !IsLegalToFold(
N,
P, Root, OptLevel))
3493 return selectAddr(
N.getNode(),
3494 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3497bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P, SDValue
N,
3498 SDValue &
Base, SDValue &Scale,
3499 SDValue &Index, SDValue &Disp,
3501 assert(Root &&
P &&
"Unknown root/parent nodes");
3502 if (
N->getOpcode() != X86ISD::VBROADCAST_LOAD ||
3503 !IsProfitableToFold(
N,
P, Root) ||
3504 !IsLegalToFold(
N,
P, Root, OptLevel))
3507 return selectAddr(
N.getNode(),
3508 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3514SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3517 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3520bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3522 N =
N->getOperand(0).getNode();
3523 if (
N->getOpcode() != X86ISD::Wrapper)
3530 auto *GV = GA->getGlobal();
3533 return CR->getSignedMin().sge(-1ull << Width) &&
3534 CR->getSignedMax().slt(1ull << Width);
3540 !TM.isLargeGlobalValue(GV);
3544 assert(
N->isMachineOpcode() &&
"Unexpected node");
3545 unsigned Opc =
N->getMachineOpcode();
3546 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3551 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3556bool X86DAGToDAGISel::onlyUsesZeroFlag(SDValue Flags)
const {
3558 for (SDUse &Use :
Flags->uses()) {
3560 if (
Use.getResNo() !=
Flags.getResNo())
3568 for (SDUse &FlagUse :
User->uses()) {
3570 if (FlagUse.getResNo() != 1)
3573 if (!FlagUse.getUser()->isMachineOpcode())
3593bool X86DAGToDAGISel::hasNoSignFlagUses(SDValue Flags)
const {
3595 for (SDUse &Use :
Flags->uses()) {
3597 if (
Use.getResNo() !=
Flags.getResNo())
3605 for (SDUse &FlagUse :
User->uses()) {
3607 if (FlagUse.getResNo() != 1)
3610 if (!FlagUse.getUser()->isMachineOpcode())
3650 bool X86DAGToDAGISel::hasNoCarryFlagUses(SDValue Flags)
const {
3652 for (SDUse &Use :
Flags->uses()) {
3654 if (
Use.getResNo() !=
Flags.getResNo())
3658 unsigned UserOpc =
User->getOpcode();
3665 for (SDUse &FlagUse :
User->uses()) {
3667 if (FlagUse.getResNo() != 1)
3670 if (!FlagUse.getUser()->isMachineOpcode())
3690 case X86ISD::SETCC: CCOpNo = 0;
break;
3691 case X86ISD::SETCC_CARRY: CCOpNo = 0;
break;
3692 case X86ISD::CMOV: CCOpNo = 2;
break;
3693 case X86ISD::BRCOND: CCOpNo = 2;
break;
3706 unsigned Depth = 0) {
3727bool X86DAGToDAGISel::checkTCRetEnoughRegs(SDNode *
N)
const {
3728 assert(
N->getOpcode() == X86ISD::TC_RETURN);
3739 const X86RegisterInfo *RI = Subtarget->getRegisterInfo();
3743 if (Subtarget->is64Bit()) {
3746 ? &X86::GR64_TCW64RegClass
3747 : &X86::GR64_TCRegClass;
3755 ? &X86::GR32RegClass
3756 : &X86::GR32_TCRegClass;
3763 unsigned LoadGPRs = 2;
3765 if (Subtarget->is32Bit()) {
3770 }
else if (
BasePtr.getOpcode() == X86ISD::Wrapper &&
3772 if (getTargetMachine().isPositionIndependent())
3780 for (
unsigned I = 3,
E =
N->getNumOperands();
I !=
E; ++
I) {
3782 if (!RI->isGeneralPurposeRegister(*MF,
RN->getReg()))
3784 if (++
ArgGPRs + LoadGPRs > AvailGPRs)
3800 if (StoredVal.
getResNo() != 0)
return false;
3817 if (!
Load.hasOneUse())
3825 bool FoundLoad =
false;
3829 const unsigned int Max = 1024;
3871 if (Chain ==
Load.getValue(1)) {
3877 if (
Op ==
Load.getValue(1)) {
3893 if (
Op.getNode() != LoadNode)
3925bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3927 SDValue StoredVal = StoreNode->getOperand(1);
3933 EVT MemVT = StoreNode->getMemoryVT();
3934 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3938 bool IsCommutable =
false;
3939 bool IsNegate =
false;
3953 IsCommutable =
true;
3957 unsigned LoadOpNo = IsNegate ? 1 : 0;
3958 LoadSDNode *LoadNode =
nullptr;
3961 LoadNode, InputChain)) {
3968 LoadNode, InputChain))
3972 SDValue
Base, Scale,
Index, Disp, Segment;
3973 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3977 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3998 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
4000 const SDValue
Ops[] = {
Base, Scale,
Index, Disp, Segment, InputChain};
4001 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
4008 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
4012 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
4014 ((
Opc == X86ISD::ADD) == IsOne)
4015 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
4016 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
4017 const SDValue
Ops[] = {
Base, Scale,
Index, Disp, Segment, InputChain};
4018 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
4029 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
4032 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
4035 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
4038 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
4041 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
4044 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
4047 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
4049 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
4055 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
4058 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
4061 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
4064 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
4067 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
4070 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
4073 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
4076 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
4083 unsigned NewOpc = SelectRegOpcode(
Opc);
4084 SDValue Operand = StoredVal->
getOperand(1-LoadOpNo);
4089 int64_t OperandV = OperandC->getSExtValue();
4094 if ((
Opc == X86ISD::ADD ||
Opc == X86ISD::SUB) &&
4096 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
4098 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
4099 OperandV = -OperandV;
4100 Opc =
Opc == X86ISD::ADD ? X86ISD::SUB : X86ISD::ADD;
4103 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
4104 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
4105 NewOpc = SelectImmOpcode(
Opc);
4109 if (
Opc == X86ISD::ADC ||
Opc == X86ISD::SBB) {
4111 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
4115 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
4116 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
4120 Segment, Operand, InputChain};
4121 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
4130 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
4132 CurDAG->setNodeMemRefs(Result, MemOps);
4135 ReplaceUses(SDValue(LoadNode, 1), SDValue(Result, 1));
4136 ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));
4137 ReplaceUses(SDValue(StoredVal.
getNode(), 1), SDValue(Result, 0));
4138 CurDAG->RemoveDeadNode(Node);
4149bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
4153 "Should be either an and-mask, or right-shift after clearing high bits.");
4156 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
4159 MVT NVT =
Node->getSimpleValueType(0);
4162 if (NVT != MVT::i32 && NVT != MVT::i64)
4170 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
4171 auto checkUses = [AllowExtraUsesByDefault](
4172 SDValue
Op,
unsigned NUses,
4173 std::optional<bool> AllowExtraUses) {
4174 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
4175 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
4177 auto checkOneUse = [checkUses](SDValue
Op,
4178 std::optional<bool> AllowExtraUses =
4180 return checkUses(
Op, 1, AllowExtraUses);
4182 auto checkTwoUse = [checkUses](SDValue
Op,
4183 std::optional<bool> AllowExtraUses =
4185 return checkUses(
Op, 2, AllowExtraUses);
4188 auto peekThroughOneUseTruncation = [checkOneUse](SDValue
V) {
4190 assert(
V.getSimpleValueType() == MVT::i32 &&
4191 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
4192 "Expected i64 -> i32 truncation");
4193 V =
V.getOperand(0);
4199 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
4200 &NegateNBits](SDValue
Mask) ->
bool {
4202 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
4208 SDValue
M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4213 NBits =
M0->getOperand(1);
4214 NegateNBits =
false;
4218 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](SDValue
V) {
4219 V = peekThroughOneUseTruncation(V);
4220 return CurDAG->MaskedValueIsAllOnes(
4226 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
4227 &NBits, &NegateNBits](SDValue
Mask) ->
bool {
4229 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
4232 if (!isAllOnes(
Mask->getOperand(1)))
4235 SDValue
M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4239 if (!isAllOnes(
M0->getOperand(0)))
4241 NBits =
M0->getOperand(1);
4242 NegateNBits =
false;
4248 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](SDValue ShiftAmt,
4249 unsigned Bitwidth) {
4254 NBits = NBits.getOperand(0);
4260 if (!V0 ||
V0->getZExtValue() != Bitwidth)
4262 NBits = NBits.getOperand(1);
4263 NegateNBits =
false;
4269 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
4270 canonicalizeShiftAmt](SDValue
Mask) ->
bool {
4272 Mask = peekThroughOneUseTruncation(Mask);
4273 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
4275 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
4280 SDValue
M1 =
Mask.getOperand(1);
4282 if (!checkOneUse(
M1))
4284 canonicalizeShiftAmt(
M1, Bitwidth);
4289 return !NegateNBits;
4297 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
4298 AllowExtraUsesByDefault, &NegateNBits,
4299 &
X](SDNode *
Node) ->
bool {
4302 SDValue N0 =
Node->getOperand(0);
4306 SDValue N1 =
Node->getOperand(1);
4311 canonicalizeShiftAmt(N1, Bitwidth);
4315 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
4316 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4322 auto matchLowBitMask = [matchPatternA, matchPatternB,
4323 matchPatternC](SDValue
Mask) ->
bool {
4324 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4328 X =
Node->getOperand(0);
4329 SDValue
Mask =
Node->getOperand(1);
4331 if (matchLowBitMask(Mask)) {
4335 if (!matchLowBitMask(Mask))
4338 }
else if (matchLowBitMask(SDValue(Node, 0))) {
4339 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4340 }
else if (!matchPatternD(Node))
4345 if (NegateNBits && !Subtarget->hasBMI2())
4350 if (NBits.getSimpleValueType() != MVT::i8) {
4357 ConstantSDNode *
Imm =
nullptr;
4358 if (NBits->getOpcode() ==
ISD::AND)
4360 NBits = NBits->getOperand(0);
4364 SDValue ImplDef = SDValue(
4365 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4368 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4370 NBits = SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4371 MVT::i32, ImplDef, NBits, SRIdxVal),
4377 CurDAG->getNode(
ISD::AND,
DL, MVT::i32, NBits,
4378 CurDAG->getConstant(
Imm->getZExtValue(),
DL, MVT::i32));
4385 SDValue BitWidthC = CurDAG->getConstant(NVT.
getSizeInBits(),
DL, MVT::i32);
4388 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4392 if (Subtarget->hasBMI2()) {
4394 if (NVT != MVT::i32) {
4400 SDValue Extract = CurDAG->getNode(X86ISD::BZHI,
DL, NVT,
X, NBits);
4401 ReplaceNode(Node, Extract.
getNode());
4402 SelectCode(Extract.
getNode());
4411 SDValue RealX = peekThroughOneUseTruncation(
X);
4417 MVT XVT =
X.getSimpleValueType();
4427 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4429 SDValue Control = CurDAG->getNode(
ISD::SHL,
DL, MVT::i32, NBits, C8);
4435 SDValue ShiftAmt =
X.getOperand(1);
4436 X =
X.getOperand(0);
4439 "Expected shift amount to be i8");
4443 SDValue OrigShiftAmt = ShiftAmt;
4448 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4453 if (XVT != MVT::i32) {
4459 SDValue Extract = CurDAG->getNode(X86ISD::BEXTR,
DL, XVT,
X, Control);
4467 ReplaceNode(Node, Extract.
getNode());
4468 SelectCode(Extract.
getNode());
4474MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4475 MVT NVT =
Node->getSimpleValueType(0);
4478 SDValue N0 =
Node->getOperand(0);
4479 SDValue N1 =
Node->getOperand(1);
4488 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4489 if (!PreferBEXTR && !Subtarget->hasBMI2())
4501 if (NVT != MVT::i32 && NVT != MVT::i64)
4507 if (!MaskCst || !ShiftCst)
4515 uint64_t Shift = ShiftCst->getZExtValue();
4520 if (Shift == 8 && MaskSize == 8)
4531 if (!PreferBEXTR && MaskSize <= 32)
4535 unsigned ROpc, MOpc;
4537#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4539 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4543 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4548 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4549 Control = SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4555 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4556 if (Subtarget->hasTBM()) {
4557 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4558 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4560 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4566 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4567 Control = SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4571 MachineSDNode *NewNode;
4573 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4574 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4576 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4577 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4578 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4580 ReplaceUses(Input.
getValue(1), SDValue(NewNode, 2));
4582 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4584 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4589 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4593 CurDAG->getMachineNode(NewOpc, dl, NVT, SDValue(NewNode, 0), ShAmt);
4600MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4601 bool MayFoldLoad,
const SDLoc &dl,
4602 MVT VT, SDNode *Node) {
4603 SDValue N0 =
Node->getOperand(0);
4604 SDValue N1 =
Node->getOperand(1);
4605 SDValue
Imm =
Node->getOperand(2);
4607 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4610 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4611 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4612 SDValue
Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4614 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4615 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4617 ReplaceUses(N1.
getValue(1), SDValue(CNode, 2));
4623 SDValue
Ops[] = { N0, N1,
Imm };
4624 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4625 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4632MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4633 bool MayFoldLoad,
const SDLoc &dl,
4634 MVT VT, SDNode *Node,
4636 SDValue N0 =
Node->getOperand(0);
4637 SDValue N2 =
Node->getOperand(2);
4638 SDValue
Imm =
Node->getOperand(4);
4640 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4643 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4644 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4645 SDValue
Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4647 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4648 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4649 InGlue = SDValue(CNode, 3);
4651 ReplaceUses(N2.
getValue(1), SDValue(CNode, 2));
4657 SDValue
Ops[] = { N0, N2,
Imm, InGlue };
4658 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4659 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4660 InGlue = SDValue(CNode, 2);
4664bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4665 EVT VT =
N->getValueType(0);
4672 unsigned Size = VT == MVT::i64 ? 64 : 32;
4675 SDValue ShiftAmt = OrigShiftAmt;
4685 SDValue NewShiftAmt;
4694 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4698 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4699 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4703 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4711 SDValue
AllOnes = CurDAG->getAllOnesConstant(
DL, OpVT);
4712 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4713 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4719 Add0C->getZExtValue() != 0) {
4722 if (Add0C->getZExtValue() %
Size == 0)
4725 Add0C->getZExtValue() % 32 == 0) {
4733 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4737 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4744 SDValue
Zero = CurDAG->getConstant(0,
DL, SubVT);
4745 SDValue Neg = CurDAG->getNode(
ISD::SUB,
DL, SubVT, Zero,
X);
4759 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4766 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4767 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4771 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4773 if (UpdatedNode !=
N) {
4776 ReplaceNode(
N, UpdatedNode);
4783 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4791bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4792 MVT NVT =
N->getSimpleValueType(0);
4793 unsigned Opcode =
N->getOpcode();
4798 SDValue Shift =
N->getOperand(0);
4805 int64_t Val = Cst->getSExtValue();
4810 bool FoundAnyExtend =
false;
4814 FoundAnyExtend =
true;
4822 if (NVT != MVT::i32 && NVT != MVT::i64)
4829 uint64_t ShAmt = ShlCst->getZExtValue();
4833 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4834 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4839 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4843 ShiftedVal = (
uint64_t)Val >> ShAmt;
4847 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4850 ShiftedVal = Val >> ShAmt;
4856 ShiftedVal = (
uint64_t)Val >> ShAmt;
4864 if (!CanShrinkImmediate(ShiftedVal))
4874 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4880 NeededMask &= ~Cst->getAPIntValue();
4882 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4887 if (FoundAnyExtend) {
4893 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4895 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4897 SDValue NewSHL = CurDAG->getNode(
ISD::SHL, dl, NVT, NewBinOp,
4904bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4905 SDNode *ParentB, SDNode *ParentC,
4906 SDValue
A, SDValue
B, SDValue
C,
4908 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4909 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4911 auto tryFoldLoadOrBCast =
4912 [
this](SDNode *Root, SDNode *
P, SDValue &
L, SDValue &
Base, SDValue &Scale,
4913 SDValue &
Index, SDValue &Disp, SDValue &Segment) {
4914 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4920 L =
L.getOperand(0);
4923 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
4928 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4932 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4935 bool FoldedLoad =
false;
4936 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4937 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4939 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4944 uint8_t OldImm =
Imm;
4945 Imm = OldImm & 0xa5;
4946 if (OldImm & 0x02)
Imm |= 0x10;
4947 if (OldImm & 0x10)
Imm |= 0x02;
4948 if (OldImm & 0x08)
Imm |= 0x40;
4949 if (OldImm & 0x40)
Imm |= 0x08;
4950 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4955 uint8_t OldImm =
Imm;
4956 Imm = OldImm & 0x99;
4957 if (OldImm & 0x02)
Imm |= 0x04;
4958 if (OldImm & 0x04)
Imm |= 0x02;
4959 if (OldImm & 0x20)
Imm |= 0x40;
4960 if (OldImm & 0x40)
Imm |= 0x20;
4965 SDValue TImm = CurDAG->getTargetConstant(
Imm,
DL, MVT::i8);
4969 MachineSDNode *MNode;
4971 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4974 if (
C.getOpcode() == X86ISD::VBROADCAST_LOAD) {
4976 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4977 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4979 bool UseD = EltSize == 32;
4981 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4983 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4985 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4991 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4993 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4995 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
5000 SDValue
Ops[] = {
A,
B, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, TImm,
C.
getOperand(0)};
5001 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
5004 ReplaceUses(
C.getValue(1), SDValue(MNode, 1));
5011 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
5013 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
5015 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
5019 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
5022 ReplaceUses(SDValue(Root, 0), SDValue(MNode, 0));
5023 CurDAG->RemoveDeadNode(Root);
5029bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
5030 MVT NVT =
N->getSimpleValueType(0);
5033 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
5041 auto getFoldableLogicOp = [](SDValue
Op) {
5044 Op =
Op.getOperand(0);
5046 if (!
Op.hasOneUse())
5049 unsigned Opc =
Op.getOpcode();
5051 Opc == X86ISD::ANDNP)
5057 SDValue N0, N1,
A, FoldableOp;
5060 auto tryPeelOuterNotWrappingLogic = [&](SDNode *
Op) {
5063 SDValue InnerOp = getFoldableLogicOp(
Op->getOperand(0));
5070 if ((FoldableOp = getFoldableLogicOp(N1))) {
5074 if ((FoldableOp = getFoldableLogicOp(N0))) {
5082 bool PeeledOuterNot =
false;
5084 if (SDValue InnerOp = tryPeelOuterNotWrappingLogic(
N)) {
5085 PeeledOuterNot =
true;
5091 if ((FoldableOp = getFoldableLogicOp(N1)))
5093 else if ((FoldableOp = getFoldableLogicOp(N0)))
5101 SDNode *ParentA =
N;
5102 SDNode *ParentB = FoldableOp.
getNode();
5103 SDNode *ParentC = FoldableOp.
getNode();
5107 uint8_t TernlogMagicA = 0xf0;
5108 uint8_t TernlogMagicB = 0xcc;
5109 uint8_t TernlogMagicC = 0xaa;
5114 auto PeekThroughNot = [](SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
5118 Parent =
Op.getNode();
5119 Op =
Op.getOperand(0);
5123 PeekThroughNot(
A, ParentA, TernlogMagicA);
5124 PeekThroughNot(
B, ParentB, TernlogMagicB);
5125 PeekThroughNot(
C, ParentC, TernlogMagicC);
5130 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
5131 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
5132 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
5133 case X86ISD::ANDNP:
Imm = ~(TernlogMagicB) & TernlogMagicC;
break;
5136 switch (
N->getOpcode()) {
5140 Imm &= ~TernlogMagicA;
5142 Imm = ~(
Imm) & TernlogMagicA;
5152 return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC,
A,
B,
C,
Imm);
5162bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
5165 MVT VT =
And->getSimpleValueType(0);
5166 if (VT != MVT::i32 && VT != MVT::i64)
5178 APInt MaskVal = And1C->getAPIntValue();
5180 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
5184 if (VT == MVT::i64 && MaskLZ >= 32) {
5186 MaskVal = MaskVal.
trunc(32);
5189 SDValue And0 =
And->getOperand(0);
5191 APInt NegMaskVal = MaskVal | HighZeros;
5200 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
5201 NegMaskVal = NegMaskVal.
zext(64);
5202 HighZeros = HighZeros.
zext(64);
5208 KnownBits Known0 = CurDAG->computeKnownBits(And0);
5217 if (VT == MVT::i32 && !isDef32(And0.
getNode()))
5224 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
5226 SDValue NewAnd = CurDAG->getNode(
ISD::AND, SDLoc(
And), VT, And0, NewMask);
5233 bool FoldedBCast,
bool Masked) {
5234#define VPTESTM_CASE(VT, SUFFIX) \
5237 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
5238 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
5241#define VPTESTM_BROADCAST_CASES(SUFFIX) \
5242default: llvm_unreachable("Unexpected VT!"); \
5243VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
5244VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
5245VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
5246VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
5247VPTESTM_CASE(v16i32, DZ##SUFFIX) \
5248VPTESTM_CASE(v8i64, QZ##SUFFIX)
5250#define VPTESTM_FULL_CASES(SUFFIX) \
5251VPTESTM_BROADCAST_CASES(SUFFIX) \
5252VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
5253VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
5254VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
5255VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
5256VPTESTM_CASE(v64i8, BZ##SUFFIX) \
5257VPTESTM_CASE(v32i16, WZ##SUFFIX)
5275#undef VPTESTM_FULL_CASES
5276#undef VPTESTM_BROADCAST_CASES
5286 if (
Reg.isVirtual())
5291 if (GetPhysReg(N1) == LoReg && GetPhysReg(N0) != LoReg)
5297bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root, SDValue Setcc,
5299 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
5319 SDValue N0 = SetccOp0;
5330 SDValue N0Temp = N0;
5344 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P, SDValue &
L,
5345 SDValue &
Base, SDValue &Scale, SDValue &
Index,
5346 SDValue &Disp, SDValue &Segment) {
5349 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
5354 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
5360 L =
L.getOperand(0);
5363 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
5367 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5370 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5374 bool CanFoldLoads = Src0 != Src1;
5376 bool FoldedLoad =
false;
5377 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5379 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5383 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5390 bool FoldedBCast = FoldedLoad && Src1.
getOpcode() == X86ISD::VBROADCAST_LOAD;
5392 bool IsMasked = InMask.
getNode() !=
nullptr;
5401 unsigned SubReg = CmpVT.
is128BitVector() ? X86::sub_xmm : X86::sub_ymm;
5405 SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5407 Src0 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src0);
5410 Src1 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src1);
5415 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5416 InMask = SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5417 dl, MaskVT, InMask, RC), 0);
5425 MachineSDNode *CNode;
5427 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5430 SDValue
Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5432 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5434 SDValue
Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5436 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5440 ReplaceUses(Src1.
getValue(1), SDValue(CNode, 1));
5442 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5445 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5447 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5453 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5454 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5455 dl, ResVT, SDValue(CNode, 0), RC);
5458 ReplaceUses(SDValue(Root, 0), SDValue(CNode, 0));
5459 CurDAG->RemoveDeadNode(Root);
5465bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5468 MVT NVT =
N->getSimpleValueType(0);
5471 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5505 SDValue
Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5506 SDValue Ternlog = CurDAG->getNode(X86ISD::VPTERNLOG, dl, NVT,
A,
B,
C,
Imm);
5513void X86DAGToDAGISel::Select(SDNode *Node) {
5514 MVT NVT =
Node->getSimpleValueType(0);
5515 unsigned Opcode =
Node->getOpcode();
5518 if (
Node->isMachineOpcode()) {
5520 Node->setNodeId(-1);
5527 unsigned IntNo =
Node->getConstantOperandVal(1);
5530 case Intrinsic::x86_encodekey128:
5531 case Intrinsic::x86_encodekey256: {
5532 if (!Subtarget->hasKL())
5538 case Intrinsic::x86_encodekey128:
5539 Opcode = X86::ENCODEKEY128;
5541 case Intrinsic::x86_encodekey256:
5542 Opcode = X86::ENCODEKEY256;
5546 SDValue Chain =
Node->getOperand(0);
5547 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5549 if (Opcode == X86::ENCODEKEY256)
5550 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5553 MachineSDNode *Res = CurDAG->getMachineNode(
5554 Opcode, dl,
Node->getVTList(),
5555 {Node->getOperand(2), Chain, Chain.getValue(1)});
5556 ReplaceNode(Node, Res);
5559 case Intrinsic::x86_tileloaddrs64_internal:
5560 case Intrinsic::x86_tileloaddrst164_internal:
5561 if (!Subtarget->hasAMXMOVRS())
5564 case Intrinsic::x86_tileloadd64_internal:
5565 case Intrinsic::x86_tileloaddt164_internal: {
5566 if (!Subtarget->hasAMXTILE())
5569 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5570 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5575 case Intrinsic::x86_tileloaddrs64_internal:
5576 Opc = X86::PTILELOADDRSV;
5578 case Intrinsic::x86_tileloaddrst164_internal:
5579 Opc = X86::PTILELOADDRST1V;
5581 case Intrinsic::x86_tileloadd64_internal:
5582 Opc = X86::PTILELOADDV;
5584 case Intrinsic::x86_tileloaddt164_internal:
5585 Opc = X86::PTILELOADDT1V;
5589 SDValue
Base =
Node->getOperand(4);
5590 SDValue Scale = getI8Imm(1, dl);
5592 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5593 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5594 SDValue Chain =
Node->getOperand(0);
5595 MachineSDNode *CNode;
5596 SDValue
Ops[] = {
Node->getOperand(2),
5597 Node->getOperand(3),
5604 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5605 ReplaceNode(Node, CNode);
5612 unsigned IntNo =
Node->getConstantOperandVal(1);
5615 case Intrinsic::x86_sse3_monitor:
5616 case Intrinsic::x86_monitorx:
5617 case Intrinsic::x86_clzero: {
5618 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5623 case Intrinsic::x86_sse3_monitor:
5624 if (!Subtarget->hasSSE3())
5626 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5628 case Intrinsic::x86_monitorx:
5629 if (!Subtarget->hasMWAITX())
5631 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5633 case Intrinsic::x86_clzero:
5634 if (!Subtarget->hasCLZERO())
5636 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5641 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5642 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5643 Node->getOperand(2), SDValue());
5644 SDValue InGlue = Chain.
getValue(1);
5646 if (IntNo == Intrinsic::x86_sse3_monitor ||
5647 IntNo == Intrinsic::x86_monitorx) {
5649 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5652 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5657 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5659 ReplaceNode(Node, CNode);
5665 case Intrinsic::x86_tilestored64_internal: {
5667 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5668 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5669 unsigned Opc = X86::PTILESTOREDV;
5671 SDValue
Base =
Node->getOperand(4);
5672 SDValue Scale = getI8Imm(1, dl);
5674 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5675 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5676 SDValue Chain =
Node->getOperand(0);
5677 MachineSDNode *CNode;
5678 SDValue
Ops[] = {
Node->getOperand(2),
5679 Node->getOperand(3),
5685 Node->getOperand(6),
5687 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5688 ReplaceNode(Node, CNode);
5691 case Intrinsic::x86_tileloaddrs64:
5692 case Intrinsic::x86_tileloaddrst164:
5693 if (!Subtarget->hasAMXMOVRS())
5696 case Intrinsic::x86_tileloadd64:
5697 case Intrinsic::x86_tileloaddt164:
5698 case Intrinsic::x86_tilestored64: {
5699 if (!Subtarget->hasAMXTILE())
5702 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5703 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5707 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5708 case Intrinsic::x86_tileloaddrs64:
5709 Opc = X86::PTILELOADDRS;
5711 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5712 case Intrinsic::x86_tileloaddrst164:
5713 Opc = X86::PTILELOADDRST1;
5715 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5718 unsigned TIndex =
Node->getConstantOperandVal(2);
5719 SDValue
TReg = getI8Imm(TIndex, dl);
5720 SDValue
Base =
Node->getOperand(3);
5721 SDValue Scale = getI8Imm(1, dl);
5723 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5724 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5725 SDValue Chain =
Node->getOperand(0);
5726 MachineSDNode *CNode;
5727 if (
Opc == X86::PTILESTORED) {
5729 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5732 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5734 ReplaceNode(Node, CNode);
5741 case X86ISD::NT_BRIND: {
5742 if (Subtarget->isTarget64BitILP32()) {
5747 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5748 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5749 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5750 Node->getOperand(0), ZextTarget);
5751 ReplaceNode(Node, Brind.
getNode());
5752 SelectCode(ZextTarget.
getNode());
5759 ReplaceNode(Node, getGlobalBaseReg());
5766 ReplaceUses(SDValue(Node, 0),
Node->getOperand(0));
5767 CurDAG->RemoveDeadNode(Node);
5773 if (matchBitExtract(Node))
5778 if (tryShiftAmountMod(Node))
5782 case X86ISD::VPTERNLOG: {
5783 uint8_t
Imm =
Node->getConstantOperandVal(3);
5784 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5791 if (tryVPTERNLOG(Node))
5798 SDValue N0 =
Node->getOperand(0);
5799 SDValue N1 =
Node->getOperand(1);
5801 tryVPTESTM(Node, N0, N1))
5804 tryVPTESTM(Node, N1, N0))
5808 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5809 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
5810 CurDAG->RemoveDeadNode(Node);
5813 if (matchBitExtract(Node))
5821 if (tryShrinkShlLogicImm(Node))
5823 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5825 if (tryVPTERNLOG(Node))
5830 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5840 if (!CurDAG->shouldOptForSize())
5844 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5847 SDValue N0 =
Node->getOperand(0);
5848 SDValue N1 =
Node->getOperand(1);
5854 int64_t Val = Cst->getSExtValue();
5862 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5866 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5870 unsigned ROpc, MOpc;
5979 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5980 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5981 SDValue
Ops[] = { N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N0.
getOperand(0) };
5982 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5983 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5985 ReplaceUses(N0.
getValue(1), SDValue(CNode, 2));
5988 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
5989 CurDAG->RemoveDeadNode(Node);
5994 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
6003 case X86ISD::UMUL: {
6004 SDValue N0 =
Node->getOperand(0);
6005 SDValue N1 =
Node->getOperand(1);
6007 unsigned LoReg, ROpc, MOpc;
6012 ROpc = Opcode == X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
6013 MOpc = Opcode == X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
6032 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6033 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6036 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6044 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
6046 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
6047 N0, SDValue()).getValue(1);
6049 MachineSDNode *CNode;
6055 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
6057 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
6059 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.
getOperand(0),
6061 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6064 ReplaceUses(N1.
getValue(1), SDValue(CNode, NVT == MVT::i8 ? 2 : 3));
6072 VTs = CurDAG->getVTList(NVT, MVT::i32);
6074 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
6076 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
6079 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6080 ReplaceUses(SDValue(Node, 1), SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
6081 CurDAG->RemoveDeadNode(Node);
6087 SDValue N0 =
Node->getOperand(0);
6088 SDValue N1 =
Node->getOperand(1);
6091 unsigned LoReg, HiReg;
6093 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
6094 bool UseMULXHi = UseMULX && SDValue(Node, 0).use_empty();
6098 Opc = UseMULXHi ? X86::MULX32Hrr
6100 : IsSigned ?
X86::IMUL32r
6102 MOpc = UseMULXHi ? X86::MULX32Hrm
6104 : IsSigned ?
X86::IMUL32m
6106 LoReg = UseMULX ? X86::EDX : X86::EAX;
6110 Opc = UseMULXHi ? X86::MULX64Hrr
6112 : IsSigned ?
X86::IMUL64r
6114 MOpc = UseMULXHi ? X86::MULX64Hrm
6116 : IsSigned ?
X86::IMUL64m
6118 LoReg = UseMULX ? X86::RDX : X86::RAX;
6123 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6124 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6127 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6135 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
6137 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
6138 N0, SDValue()).getValue(1);
6139 SDValue ResHi, ResLo;
6142 MachineSDNode *CNode =
nullptr;
6143 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.
getOperand(0),
6146 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
6147 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6148 ResHi = SDValue(CNode, 0);
6149 Chain = SDValue(CNode, 1);
6150 }
else if (UseMULX) {
6151 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
6152 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6153 ResHi = SDValue(CNode, 0);
6154 ResLo = SDValue(CNode, 1);
6155 Chain = SDValue(CNode, 2);
6157 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6158 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6159 Chain = SDValue(CNode, 0);
6160 InGlue = SDValue(CNode, 1);
6164 ReplaceUses(N1.
getValue(1), Chain);
6168 SDValue
Ops[] = { N1, InGlue };
6170 SDVTList VTs = CurDAG->getVTList(NVT);
6171 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
6172 ResHi = SDValue(CNode, 0);
6173 }
else if (UseMULX) {
6174 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
6175 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
6176 ResHi = SDValue(CNode, 0);
6177 ResLo = SDValue(CNode, 1);
6179 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
6180 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
6181 InGlue = SDValue(CNode, 0);
6186 if (!SDValue(Node, 0).use_empty()) {
6188 assert(LoReg &&
"Register for low half is not defined!");
6189 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
6193 ReplaceUses(SDValue(Node, 0), ResLo);
6198 if (!SDValue(Node, 1).use_empty()) {
6200 assert(HiReg &&
"Register for high half is not defined!");
6201 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
6205 ReplaceUses(SDValue(Node, 1), ResHi);
6210 CurDAG->RemoveDeadNode(Node);
6216 SDValue N0 =
Node->getOperand(0);
6217 SDValue N1 =
Node->getOperand(1);
6219 unsigned ROpc, MOpc;
6224 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
6225 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
6226 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
6227 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
6232 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
6233 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
6234 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
6235 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
6239 unsigned LoReg, HiReg, ClrReg;
6240 unsigned SExtOpcode;
6244 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
6248 LoReg = X86::AX; HiReg = X86::DX;
6250 SExtOpcode = X86::CWD;
6253 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
6254 SExtOpcode = X86::CDQ;
6257 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
6258 SExtOpcode = X86::CQO;
6262 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6263 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6264 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
6267 if (NVT == MVT::i8) {
6270 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
6271 MachineSDNode *Move;
6272 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6273 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N0.
getOperand(0) };
6274 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rm8
6276 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
6277 Chain = SDValue(Move, 1);
6278 ReplaceUses(N0.
getValue(1), Chain);
6282 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rr8
6284 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
6285 Chain = CurDAG->getEntryNode();
6287 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX, SDValue(Move, 0),
6292 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
6293 LoReg, N0, SDValue()).getValue(1);
6297 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
6300 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
6302 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
6306 SDValue(CurDAG->getMachineNode(
6307 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
6308 CurDAG->getTargetConstant(X86::sub_16bit, dl,
6316 CurDAG->getMachineNode(
6317 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, ClrNode,
6318 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
6325 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
6326 ClrNode, InGlue).getValue(1);
6331 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.
getOperand(0),
6333 MachineSDNode *CNode =
6334 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
6335 InGlue = SDValue(CNode, 1);
6337 ReplaceUses(N1.
getValue(1), SDValue(CNode, 0));
6342 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
6352 if (HiReg == X86::AH && !SDValue(Node, 1).use_empty()) {
6353 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
6354 unsigned AHExtOpcode =
6355 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6357 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6358 MVT::Glue, AHCopy, InGlue);
6359 SDValue
Result(RNode, 0);
6360 InGlue = SDValue(RNode, 1);
6363 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6365 ReplaceUses(SDValue(Node, 1), Result);
6370 if (!SDValue(Node, 0).use_empty()) {
6371 SDValue
Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6372 LoReg, NVT, InGlue);
6373 InGlue =
Result.getValue(2);
6374 ReplaceUses(SDValue(Node, 0), Result);
6379 if (!SDValue(Node, 1).use_empty()) {
6380 SDValue
Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6381 HiReg, NVT, InGlue);
6382 InGlue =
Result.getValue(2);
6383 ReplaceUses(SDValue(Node, 1), Result);
6387 CurDAG->RemoveDeadNode(Node);
6392 case X86ISD::STRICT_FCMP:
6393 case X86ISD::STRICT_FCMPS: {
6394 bool IsStrictCmp =
Node->getOpcode() == X86ISD::STRICT_FCMP ||
6395 Node->getOpcode() == X86ISD::STRICT_FCMPS;
6396 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6397 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6403 if (Subtarget->canUseCMOV())
6406 bool IsSignaling =
Node->getOpcode() == X86ISD::STRICT_FCMPS;
6412 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6415 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6418 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6423 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6426 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6427 Chain = SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6430 Glue = SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6435 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6439 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6443 assert(Subtarget->canUseLAHFSAHF() &&
6444 "Target doesn't support SAHF or FCOMI?");
6445 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract, SDValue());
6447 SDValue SAHF = SDValue(
6448 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6451 ReplaceUses(SDValue(Node, 1), Chain);
6453 ReplaceUses(SDValue(Node, 0), SAHF);
6454 CurDAG->RemoveDeadNode(Node);
6459 SDValue N0 =
Node->getOperand(0);
6460 SDValue N1 =
Node->getOperand(1);
6474 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6475 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6477 SDValue BEXTR = SDValue(NewNode, 0);
6478 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6479 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
6480 CurDAG->RemoveDeadNode(Node);
6507 onlyUsesZeroFlag(SDValue(Node, 0))) {
6512 unsigned TestOpcode;
6520 if (LeadingZeros == 0 && SavesBytes) {
6525 ShiftAmt = TrailingZeros;
6527 TestOpcode = X86::TEST64rr;
6528 }
else if (TrailingZeros == 0 && SavesBytes) {
6534 if (LeadingZeros == 1) {
6538 MachineSDNode *
Add = CurDAG->getMachineNode(
6541 MachineSDNode *
Test = CurDAG->getMachineNode(
6542 X86::TEST64rr, dl, MVT::i32, SDValue(
Add, 0), SDValue(
Add, 0));
6543 ReplaceNode(Node,
Test);
6547 ShiftAmt = LeadingZeros;
6549 TestOpcode = X86::TEST64rr;
6550 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6553 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6554 if (PopCount == 8) {
6556 ShiftAmt = TrailingZeros;
6557 SubRegIdx = X86::sub_8bit;
6559 TestOpcode = X86::TEST8rr;
6560 }
else if (PopCount == 16) {
6562 ShiftAmt = TrailingZeros;
6563 SubRegIdx = X86::sub_16bit;
6564 SubRegVT = MVT::i16;
6565 TestOpcode = X86::TEST16rr;
6566 }
else if (PopCount == 32) {
6568 ShiftAmt = TrailingZeros;
6569 SubRegIdx = X86::sub_32bit;
6570 SubRegVT = MVT::i32;
6571 TestOpcode = X86::TEST32rr;
6575 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6576 SDValue Shift = SDValue(
6577 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6580 if (SubRegIdx != 0) {
6582 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6584 MachineSDNode *
Test =
6585 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6586 ReplaceNode(Node,
Test);
6593 unsigned ROpc, MOpc;
6601 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6602 hasNoSignFlagUses(SDValue(Node, 0)))) {
6605 SubRegOp = X86::sub_8bit;
6606 ROpc = X86::TEST8ri;
6607 MOpc = X86::TEST8mi;
6608 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6609 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6610 hasNoSignFlagUses(SDValue(Node, 0)))) {
6616 SubRegOp = X86::sub_16bit;
6617 ROpc = X86::TEST16ri;
6618 MOpc = X86::TEST16mi;
6620 ((!(Mask & 0x80000000) &&
6623 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6624 CmpVT == MVT::i32 ||
6625 hasNoSignFlagUses(SDValue(Node, 0)))) {
6632 SubRegOp = X86::sub_32bit;
6633 ROpc = X86::TEST32ri;
6634 MOpc = X86::TEST32mi;
6640 SDValue
Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6644 MachineSDNode *NewNode;
6645 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6646 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6648 if (!LoadN->isSimple()) {
6649 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6650 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6651 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6652 (MOpc == X86::TEST32mi && NumVolBits != 32))
6656 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
6657 Reg.getOperand(0) };
6658 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6660 ReplaceUses(
Reg.getValue(1), SDValue(NewNode, 1));
6662 CurDAG->setNodeMemRefs(NewNode,
6667 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6669 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg,
Imm);
6672 ReplaceNode(Node, NewNode);
6678 if (!Subtarget->hasSSE42())
6681 bool NeedIndex = !SDValue(Node, 0).use_empty();
6682 bool NeedMask = !SDValue(Node, 1).use_empty();
6684 bool MayFoldLoad = !NeedIndex || !
NeedMask;
6686 MachineSDNode *CNode;
6689 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6691 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6692 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6693 ReplaceUses(SDValue(Node, 1), SDValue(CNode, 0));
6695 if (NeedIndex || !NeedMask) {
6697 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6699 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6700 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6701 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6705 ReplaceUses(SDValue(Node, 2), SDValue(CNode, 1));
6706 CurDAG->RemoveDeadNode(Node);
6710 if (!Subtarget->hasSSE42())
6714 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6715 Node->getOperand(1),
6716 SDValue()).getValue(1);
6717 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6718 Node->getOperand(3), InGlue).getValue(1);
6720 bool NeedIndex = !SDValue(Node, 0).use_empty();
6721 bool NeedMask = !SDValue(Node, 1).use_empty();
6723 bool MayFoldLoad = !NeedIndex || !
NeedMask;
6725 MachineSDNode *CNode;
6728 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6730 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6732 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6733 ReplaceUses(SDValue(Node, 1), SDValue(CNode, 0));
6735 if (NeedIndex || !NeedMask) {
6737 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6739 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6740 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6741 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6744 ReplaceUses(SDValue(Node, 2), SDValue(CNode, 1));
6745 CurDAG->RemoveDeadNode(Node);
6750 if (NVT.
isVector() && tryVPTESTM(Node, SDValue(Node, 0), SDValue()))
6757 if (foldLoadStoreIntoMemOperand(Node))
6761 case X86ISD::SETCC_CARRY: {
6762 MVT VT =
Node->getSimpleValueType(0);
6764 if (Subtarget->hasSBBDepBreaking()) {
6769 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6770 Node->getOperand(1), SDValue());
6774 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6775 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6777 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6782 Result = getSBBZero(Node);
6786 if (VT == MVT::i8 || VT == MVT::i16) {
6787 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6788 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6791 ReplaceUses(SDValue(Node, 0), Result);
6792 CurDAG->RemoveDeadNode(Node);
6798 SDValue
Result = getSBBZero(Node);
6801 ReplaceUses(SDValue(Node, 1),
Result.getValue(1));
6804 if (!SDValue(Node, 0).use_empty()) {
6806 MVT VT =
Node->getSimpleValueType(0);
6807 if (VT == MVT::i8 || VT == MVT::i16) {
6808 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6809 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6811 ReplaceUses(SDValue(Node, 0), Result);
6814 CurDAG->RemoveDeadNode(Node);
6821 SDValue IndexOp = Mgt->getIndex();
6822 SDValue
Mask = Mgt->getMask();
6824 MVT ValueVT =
Node->getSimpleValueType(0);
6825 MVT MaskVT =
Mask.getSimpleValueType();
6842 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6843 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6844 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6845 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6846 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6847 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6848 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6849 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6850 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6851 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6852 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6853 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6854 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6855 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6856 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6857 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6858 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6859 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6860 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6861 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6862 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6863 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6864 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6865 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6867 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6868 "Unexpected mask VT!");
6869 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6870 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6871 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6872 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6873 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6874 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6875 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6876 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6877 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6878 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6879 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6880 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6881 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6882 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6883 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6884 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6890 SDValue
Base, Scale,
Index, Disp, Segment;
6891 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6892 Base, Scale, Index, Disp, Segment))
6895 SDValue PassThru = Mgt->getPassThru();
6896 SDValue Chain = Mgt->getChain();
6898 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6900 MachineSDNode *NewNode;
6903 Index, Disp, Segment, Chain};
6904 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6907 Disp, Segment,
Mask, Chain};
6908 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6910 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6911 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
6912 ReplaceUses(SDValue(Node, 1), SDValue(NewNode, 2));
6913 CurDAG->RemoveDeadNode(Node);
6918 SDValue
Value = Sc->getValue();
6919 SDValue IndexOp = Sc->getIndex();
6921 MVT ValueVT =
Value.getSimpleValueType();
6936 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6937 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6938 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6939 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6940 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6941 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6942 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6943 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6944 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6945 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6946 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6947 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6948 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6949 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6950 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6951 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6952 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6953 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6954 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6955 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6956 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6957 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6958 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6959 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6963 SDValue
Base, Scale,
Index, Disp, Segment;
6964 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6965 Base, Scale, Index, Disp, Segment))
6968 SDValue
Mask = Sc->getMask();
6969 SDValue Chain = Sc->getChain();
6971 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6974 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6975 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6976 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 1));
6977 CurDAG->RemoveDeadNode(Node);
6981 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6982 auto CallId = MFI->getPreallocatedIdForCallSite(
6984 SDValue Chain =
Node->getOperand(0);
6985 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6986 MachineSDNode *
New = CurDAG->getMachineNode(
6987 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6988 ReplaceUses(SDValue(Node, 0), SDValue(New, 0));
6989 CurDAG->RemoveDeadNode(Node);
6993 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6996 SDValue Chain =
Node->getOperand(0);
6997 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6998 SDValue ArgIndex =
Node->getOperand(2);
7000 Ops[0] = CallIdValue;
7003 MachineSDNode *
New = CurDAG->getMachineNode(
7004 TargetOpcode::PREALLOCATED_ARG, dl,
7005 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
7008 ReplaceUses(SDValue(Node, 0), SDValue(New, 0));
7009 ReplaceUses(SDValue(Node, 1), SDValue(New, 1));
7010 CurDAG->RemoveDeadNode(Node);
7017 if (!Subtarget->hasWIDEKL())
7021 switch (
Node->getOpcode()) {
7025 Opcode = X86::AESENCWIDE128KL;
7028 Opcode = X86::AESDECWIDE128KL;
7031 Opcode = X86::AESENCWIDE256KL;
7034 Opcode = X86::AESDECWIDE256KL;
7038 SDValue Chain =
Node->getOperand(0);
7039 SDValue Addr =
Node->getOperand(1);
7041 SDValue
Base, Scale,
Index, Disp, Segment;
7042 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
7045 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
7047 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
7049 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
7051 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
7053 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
7055 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
7057 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
7059 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
7062 MachineSDNode *Res = CurDAG->getMachineNode(
7063 Opcode, dl,
Node->getVTList(),
7064 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
7066 ReplaceNode(Node, Res);
7070 SDValue Chain =
Node->getOperand(0);
7073 if (
Node->getNumValues() == 3)
7074 Glue =
Node->getOperand(2);
7076 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
7077 ReplaceNode(Node,
Copy.getNode());
7085bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
7087 std::vector<SDValue> &OutOps) {
7088 SDValue Op0, Op1, Op2, Op3, Op4;
7089 switch (ConstraintID) {
7092 case InlineAsm::ConstraintCode::o:
7093 case InlineAsm::ConstraintCode::v:
7094 case InlineAsm::ConstraintCode::m:
7095 case InlineAsm::ConstraintCode::X:
7096 case InlineAsm::ConstraintCode::p:
7097 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
7102 OutOps.push_back(Op0);
7103 OutOps.push_back(Op1);
7104 OutOps.push_back(Op2);
7105 OutOps.push_back(Op3);
7106 OutOps.push_back(Op4);
7112 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
7118 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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isSigned(unsigned Opcode)
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
const MCPhysReg ArgGPRs[]
static bool isUndef(const MachineInstr &MI)
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static bool isFusableLoadOpStorePattern(StoreSDNode *StoreNode, SDValue StoredVal, SelectionDAG *CurDAG, LoadSDNode *&LoadNode, SDValue &InputChain)
static void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N)
static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII)
Check if the instruction uses RIP relative addressing.
#define FROM_TO(FROM, TO)
#define GET_EGPR_IF_ENABLED(OPC)
static bool isLegalMaskCompare(SDNode *N, const X86Subtarget *Subtarget)
static bool foldMaskAndShiftToScale(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static bool foldMaskAndShiftToExtract(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static bool addrMayUseNonFixedFrameIndex(SDValue Addr, const MachineFrameInfo &MFI, unsigned Depth=0)
Return true if Addr may be matched with a non-fixed frame index as base.
static bool needBWI(MVT VT)
static unsigned getVPTESTMOpc(MVT TestVT, bool IsTestN, bool FoldedLoad, bool FoldedBCast, bool Masked)
#define GET_NDM_IF_ENABLED(OPC)
static bool foldMaskedShiftToBEXTR(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM, const X86Subtarget &Subtarget)
static bool mayUseCarryFlag(X86::CondCode CC)
static cl::opt< bool > EnablePromoteAnyextLoad("x86-promote-anyext-load", cl::init(true), cl::desc("Enable promoting aligned anyext load to wider load"), cl::Hidden)
static bool isEndbrImm(uint64_t Imm, unsigned BitWidth)
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 void orderRegForMul(SDValue &N0, SDValue &N1, const unsigned LoReg, const MachineRegisterInfo &MRI)
cl::opt< bool > IndirectBranchTracking("x86-indirect-branch-tracking", cl::init(false), cl::Hidden, cl::desc("Enable X86 indirect branch tracking pass."))
#define GET_ND_IF_ENABLED(OPC)
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countl_zero() const
The APInt version of std::countl_zero.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
bool isOne() const
Determine if this is a value of 1.
unsigned countr_one() const
Count the number of trailing one bits.
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI std::optional< ConstantRange > getAbsoluteSymbolRange() const
If this is an absolute symbol reference, returns the range of the symbol, otherwise returns std::null...
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
unsigned getID() const
getID() - Return the register class ID number.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
bool isVectorOf(MVT EltVT) const
Return true if this is a vector with matching element type.
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.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
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.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MCRegister getLiveInPhysReg(Register VReg) const
getLiveInPhysReg - If VReg is a live-in virtual register, return the corresponding live-in physical r...
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
bool isNonTemporal() const
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
int getNodeId() const
Return the unique node id.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
SDNodeFlags getFlags() const
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
iterator_range< user_iterator > users()
op_iterator op_end() const
op_iterator op_begin() const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
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.
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.
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.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ 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.
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ 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.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ 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.
int getMemoryOperandNo(uint64_t TSFlags)
@ GlobalBaseReg
On Darwin, this node represents the result of the popl at function entry, used for PIC code.
@ POP_FROM_X87_REG
The same as ISD::CopyFromReg except that this node makes it explicit that it may lower to an x87 FPU ...
int getCondSrcNoFromDesc(const MCInstrDesc &MCID)
Return the source operand # for condition code by MCID.
bool mayFoldLoad(SDValue Op, const X86Subtarget &Subtarget, bool AssumeSingleUse=false, bool IgnoreAlignment=false)
Check if Op is a load operation that could be folded into some other x86 instruction as a memory oper...
bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M, bool hasSymbolicDisplacement)
Returns true of the given offset can be fit into displacement field of the instruction.
bool isConstantSplat(SDValue Op, APInt &SplatVal, bool AllowPartialUndefs)
If Op is a constant whose elements are all the same constant or undefined, return true and return the...
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
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.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr 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)
constexpr unsigned BitWidth
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.
MCRegisterClass TargetRegisterClass
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