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");
51 struct X86ISelAddressMode {
59 int Base_FrameIndex = 0;
65 const GlobalValue *GV =
nullptr;
68 const char *ES =
nullptr;
73 bool NegateIndex =
false;
78 bool IsForLEA =
false;
80 X86ISelAddressMode() =
default;
82 bool hasSymbolicDisplacement()
const {
83 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr ||
84 MCSym !=
nullptr || JT != -1 || BlockAddr !=
nullptr;
87 bool hasBaseOrIndexReg()
const {
88 return BaseType == FrameIndexBase ||
89 IndexReg.getNode() !=
nullptr || Base_Reg.getNode() !=
nullptr;
94 if (BaseType != RegBase)
return false;
95 if (RegisterSDNode *RegNode =
97 return RegNode->getReg() == X86::RIP;
101 void setBaseReg(SDValue
Reg) {
106#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
107 void dump(SelectionDAG *DAG =
nullptr) {
108 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
109 dbgs() <<
"Base_Reg ";
110 if (Base_Reg.getNode())
111 Base_Reg.getNode()->dump(DAG);
114 if (BaseType == FrameIndexBase)
115 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
116 dbgs() <<
" Scale " << Scale <<
'\n'
120 if (IndexReg.getNode())
121 IndexReg.getNode()->dump(DAG);
124 dbgs() <<
" Disp " << Disp <<
'\n'
146 dbgs() <<
" JT" << JT <<
" Align" << Alignment.value() <<
'\n';
160 const X86Subtarget *Subtarget;
166 bool IndirectTlsSegRefs;
169 X86DAGToDAGISel() =
delete;
171 explicit X86DAGToDAGISel(X86TargetMachine &tm,
CodeGenOptLevel OptLevel)
172 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr),
173 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
179 "indirect-tls-seg-refs");
186 void emitFunctionEntryCode()
override;
188 bool IsProfitableToFold(SDValue
N, SDNode *U, SDNode *Root)
const override;
190 void PreprocessISelDAG()
override;
191 void PostprocessISelDAG()
override;
194#include "X86GenDAGISel.inc"
197 void Select(SDNode *
N)
override;
199 bool foldOffsetIntoAddress(
uint64_t Offset, X86ISelAddressMode &AM);
200 bool matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
201 bool AllowSegmentRegForX32 =
false);
202 bool matchWrapper(SDValue
N, X86ISelAddressMode &AM);
203 bool matchAddress(SDValue
N, X86ISelAddressMode &AM);
204 bool matchVectorAddress(SDValue
N, X86ISelAddressMode &AM);
205 bool matchAdd(SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
206 bool hasMaterializingUse(SDValue V)
const;
207 SDValue matchIndexRecursively(SDValue
N, X86ISelAddressMode &AM,
209 bool matchAddressRecursively(SDValue
N, X86ISelAddressMode &AM,
211 bool matchVectorAddressRecursively(SDValue
N, X86ISelAddressMode &AM,
213 bool matchAddressBase(SDValue
N, X86ISelAddressMode &AM);
214 bool selectAddr(SDNode *Parent, SDValue
N, SDValue &
Base, SDValue &Scale,
215 SDValue &Index, SDValue &Disp, SDValue &Segment,
216 bool HasNDDM =
true);
217 bool selectNDDAddr(SDNode *Parent, SDValue
N, SDValue &
Base, SDValue &Scale,
218 SDValue &Index, SDValue &Disp, SDValue &Segment);
219 bool selectVectorAddr(MemSDNode *Parent, SDValue BasePtr, SDValue IndexOp,
220 SDValue ScaleOp, SDValue &
Base, SDValue &Scale,
221 SDValue &Index, SDValue &Disp, SDValue &Segment);
222 bool selectMOV64Imm32(SDValue
N, SDValue &
Imm);
223 bool selectLEAAddr(SDValue
N, SDValue &
Base,
224 SDValue &Scale, SDValue &Index, SDValue &Disp,
226 bool selectLEA64_Addr(SDValue
N, SDValue &
Base, SDValue &Scale,
227 SDValue &Index, SDValue &Disp, SDValue &Segment);
228 bool selectTLSADDRAddr(SDValue
N, SDValue &
Base,
229 SDValue &Scale, SDValue &Index, SDValue &Disp,
231 bool selectRelocImm(SDValue
N, SDValue &
Op);
233 bool tryFoldLoad(SDNode *Root, SDNode *
P, SDValue
N,
234 SDValue &
Base, SDValue &Scale,
235 SDValue &Index, SDValue &Disp,
239 bool tryFoldLoad(SDNode *
P, SDValue
N,
240 SDValue &
Base, SDValue &Scale,
241 SDValue &Index, SDValue &Disp,
243 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
246 bool tryFoldBroadcast(SDNode *Root, SDNode *
P, SDValue
N,
247 SDValue &
Base, SDValue &Scale,
248 SDValue &Index, SDValue &Disp,
251 bool isProfitableToFormMaskedOp(SDNode *
N)
const;
254 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
256 std::vector<SDValue> &OutOps)
override;
258 void emitSpecialCodeForMain();
260 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
261 MVT VT, SDValue &
Base, SDValue &Scale,
262 SDValue &Index, SDValue &Disp,
264 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
265 Base = CurDAG->getTargetFrameIndex(
266 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
267 else if (AM.Base_Reg.
getNode())
270 Base = CurDAG->getRegister(0, VT);
272 Scale = getI8Imm(AM.Scale,
DL);
274#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
275#define GET_NDM_IF_ENABLED(OPC) \
276 (Subtarget->hasNDD() && Subtarget->hasNDDM() ? OPC##_ND : OPC)
278 if (AM.NegateIndex) {
296 SDValue Neg = SDValue(CurDAG->getMachineNode(NegOpc,
DL, VT, MVT::i32,
304 Index = CurDAG->getRegister(0, VT);
309 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(),
313 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
314 AM.Disp, AM.SymbolFlags);
316 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
317 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
318 }
else if (AM.MCSym) {
319 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
320 assert(AM.SymbolFlags == 0 &&
"oo");
321 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
322 }
else if (AM.JT != -1) {
323 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
324 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
325 }
else if (AM.BlockAddr)
326 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
329 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
332 Segment = AM.Segment;
334 Segment = CurDAG->getRegister(0, MVT::i16);
339 bool isAMXSDNode(SDNode *
N)
const {
343 for (
unsigned Idx = 0,
E =
N->getNumValues(); Idx !=
E; ++Idx) {
344 if (
N->getValueType(Idx) == MVT::x86amx)
347 for (
unsigned Idx = 0,
E =
N->getNumOperands(); Idx !=
E; ++Idx) {
348 SDValue
Op =
N->getOperand(Idx);
349 if (
Op.getValueType() == MVT::x86amx)
361 bool shouldAvoidImmediateInstFormsForSize(SDNode *
N)
const {
362 uint32_t UseCount = 0;
367 if (!CurDAG->shouldOptForSize())
371 for (
const SDNode *User :
N->users()) {
377 if (
User->isMachineOpcode()) {
384 User->getOperand(1).getNode() ==
N) {
395 if (
User->getNumOperands() != 2)
408 if (
User->getOpcode() == X86ISD::ADD ||
410 User->getOpcode() == X86ISD::SUB ||
414 SDValue OtherOp =
User->getOperand(0);
416 OtherOp =
User->getOperand(1);
419 RegisterSDNode *RegNode;
423 if ((RegNode->
getReg() == X86::ESP) ||
424 (RegNode->
getReg() == X86::RSP))
433 return (UseCount > 1);
437 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &
DL) {
438 return CurDAG->getTargetConstant(
Imm,
DL, MVT::i8);
442 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &
DL) {
443 return CurDAG->getTargetConstant(
Imm,
DL, MVT::i32);
448 return CurDAG->getTargetConstant(
Imm,
DL, MVT::i64);
451 SDValue getExtractVEXTRACTImmediate(SDNode *
N,
unsigned VecWidth,
453 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
455 MVT VecVT =
N->getOperand(0).getSimpleValueType();
459 SDValue getInsertVINSERTImmediate(SDNode *
N,
unsigned VecWidth,
461 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
463 MVT VecVT =
N->getSimpleValueType(0);
467 SDValue getPermuteVINSERTCommutedImmediate(SDNode *
N,
unsigned VecWidth,
469 assert(VecWidth == 128 &&
"Unexpected vector width");
471 MVT VecVT =
N->getSimpleValueType(0);
473 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
476 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
479 SDValue getSBBZero(SDNode *
N) {
481 MVT VT =
N->getSimpleValueType(0);
484 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
486 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
487 if (VT == MVT::i64) {
489 CurDAG->getMachineNode(
490 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, Zero,
491 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
496 unsigned Opcode =
N->getOpcode();
497 assert((Opcode == X86ISD::SBB || Opcode == X86ISD::SETCC_CARRY) &&
498 "Unexpected opcode for SBB materialization");
499 unsigned FlagOpIndex = Opcode == X86ISD::SBB ? 2 : 1;
501 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
502 N->getOperand(FlagOpIndex), SDValue());
506 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
507 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
508 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
510 CurDAG->getMachineNode(
Opc, dl, VTs,
511 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
517 bool isUnneededShiftMask(SDNode *
N,
unsigned Width)
const {
519 const APInt &Val =
N->getConstantOperandAPInt(1);
524 APInt
Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
525 return Mask.countr_one() >= Width;
534 bool isDef32(SDNode *
N)
const {
535 unsigned Opc =
N->getOpcode();
540 !((
Opc == X86ISD::BSF ||
Opc == X86ISD::BSR) &&
548 SDNode *getGlobalBaseReg();
552 const X86TargetMachine &getTargetMachine()
const {
553 return static_cast<const X86TargetMachine &
>(TM);
558 const X86InstrInfo *getInstrInfo()
const {
559 return Subtarget->getInstrInfo();
568 bool ComplexPatternFuncMutatesDAG()
const override {
572 bool isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const;
575 bool useNonTemporalLoad(LoadSDNode *
N)
const {
576 if (!
N->isNonTemporal())
579 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
581 if (
N->getAlign().value() < StoreSize)
590 return Subtarget->hasSSE41();
592 return Subtarget->hasAVX2();
594 return Subtarget->hasAVX512();
598 bool foldLoadStoreIntoMemOperand(SDNode *Node);
599 MachineSDNode *matchBEXTRFromAndImm(SDNode *Node);
600 bool matchBitExtract(SDNode *Node);
601 bool shrinkAndImmediate(SDNode *
N);
602 bool isMaskZeroExtended(SDNode *
N)
const;
603 bool tryShiftAmountMod(SDNode *
N);
604 bool tryShrinkShlLogicImm(SDNode *
N);
605 bool tryVPTERNLOG(SDNode *
N);
606 bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentB,
607 SDNode *ParentC, SDValue
A, SDValue
B, SDValue
C,
609 bool tryVPTESTM(SDNode *Root, SDValue Setcc, SDValue Mask);
610 bool tryMatchBitSelect(SDNode *
N);
612 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
613 const SDLoc &dl, MVT VT, SDNode *Node);
614 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
615 const SDLoc &dl, MVT VT, SDNode *Node,
618 bool tryOptimizeRem8Extend(SDNode *
N);
620 bool onlyUsesZeroFlag(SDValue Flags)
const;
621 bool hasNoSignFlagUses(SDValue Flags)
const;
622 bool hasNoCarryFlagUses(SDValue Flags)
const;
623 bool checkTCRetEnoughRegs(SDNode *
N)
const;
629 explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm,
631 : SelectionDAGISelLegacy(
632 ID, std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
636char X86DAGToDAGISelLegacy::ID = 0;
643 unsigned Opcode =
N->getOpcode();
644 if (Opcode == X86ISD::CMPM || Opcode == X86ISD::CMPMM ||
645 Opcode == X86ISD::STRICT_CMPM || Opcode ==
ISD::SETCC ||
646 Opcode == X86ISD::CMPMM_SAE || Opcode == X86ISD::VFPCLASS) {
650 EVT OpVT =
N->getOperand(0).getValueType();
653 if (Opcode == X86ISD::STRICT_CMPM)
654 OpVT =
N->getOperand(1).getValueType();
656 return Subtarget->hasVLX();
661 if (Opcode == X86ISD::VFPCLASSS || Opcode == X86ISD::FSETCCM ||
662 Opcode == X86ISD::FSETCCM_SAE)
670bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
682X86DAGToDAGISel::IsProfitableToFold(SDValue
N, SDNode *U, SDNode *Root)
const {
683 if (OptLevel == CodeGenOptLevel::None)
698 switch (
U->getOpcode()) {
712 SDValue Op1 =
U->getOperand(1);
725 if (
Imm->getAPIntValue().isSignedIntN(8))
734 Imm->getAPIntValue().getBitWidth() == 64 &&
735 Imm->getAPIntValue().isIntN(32))
742 (
Imm->getAPIntValue() == UINT8_MAX ||
743 Imm->getAPIntValue() == UINT16_MAX ||
744 Imm->getAPIntValue() == UINT32_MAX))
750 (-
Imm->getAPIntValue()).isSignedIntN(8))
753 if ((
U->getOpcode() == X86ISD::ADD ||
U->getOpcode() == X86ISD::SUB) &&
754 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
755 hasNoCarryFlagUses(SDValue(U, 1)))
769 if (Op1.
getOpcode() == X86ISD::Wrapper) {
780 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
784 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
789 SDValue U0 =
U->getOperand(0);
790 SDValue U1 =
U->getOperand(1);
793 if (
C &&
C->getSExtValue() == -2)
799 if (
C &&
C->getSExtValue() == -2)
834bool X86DAGToDAGISel::isProfitableToFormMaskedOp(SDNode *
N)
const {
836 (
N->getOpcode() ==
ISD::VSELECT ||
N->getOpcode() == X86ISD::SELECTS) &&
837 "Unexpected opcode!");
842 return N->getOperand(1).hasOneUse();
852 Ops.push_back(
Load.getOperand(0));
855 "Unexpected chain operand");
858 Ops.push_back(
Load.getOperand(0));
864 Ops.push_back(NewChain);
869 Load.getOperand(1),
Load.getOperand(2));
887 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
899 if (!Callee.getValue(1).hasOneUse())
930 Callee.getValue(1).hasOneUse())
948 const unsigned NumBytes =
BitWidth / 8;
952 const uint8_t OptionalPrefixBytes[] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
953 0x65, 0x66, 0x67, 0xf0, 0xf2};
955 for (
unsigned I = 0;
I != NumBytes; ++
I)
956 Bytes[
I] = (
Imm >> (
I * 8)) & 0xFF;
958 for (
unsigned I = 0;
I + 3 < NumBytes; ++
I) {
959 if (Bytes[
I] != 0xf3)
966 if (J + 2 < NumBytes && Bytes[J] == 0x0f && Bytes[J + 1] == 0x1e &&
967 (Bytes[J + 2] == 0xfa || Bytes[J + 2] == 0xfb))
975 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
978void X86DAGToDAGISel::PreprocessISelDAG() {
979 bool MadeChange =
false;
981 E = CurDAG->allnodes_end();
I !=
E; ) {
999 MVT VT =
N->getSimpleValueType(0);
1001 "ISD::Constant must have a scalar integer type");
1010 "cf-protection-branch");
1011 if (CFProtectionBranch ||
1012 Subtarget->getCLOpts().indirect_branch_tracking) {
1016 SDValue Complement =
1017 CurDAG->getConstant(ComplementImm, dl, VT,
false,
true);
1018 Complement = CurDAG->getNOT(dl, Complement, VT);
1020 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Complement);
1030 if (
N->getOpcode() == X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
1031 SDValue Res = CurDAG->getNode(
ISD::AND, SDLoc(
N),
N->getValueType(0),
1032 N->getOperand(0),
N->getOperand(1));
1034 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1058 auto mayPreventLoadFold = [&]() {
1060 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1061 !
N->getOperand(1).hasOneUse();
1064 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1072 MVT VT =
N->getSimpleValueType(0);
1080 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1082 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1089 switch (
N->getOpcode()) {
1090 case X86ISD::VBROADCAST: {
1091 MVT VT =
N->getSimpleValueType(0);
1093 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1096 SDValue NarrowBCast =
1097 CurDAG->getNode(X86ISD::VBROADCAST, dl, NarrowVT,
N->getOperand(0));
1100 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1103 CurDAG->getIntPtrConstant(Index, dl));
1106 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1114 case X86ISD::VBROADCAST_LOAD: {
1115 MVT VT =
N->getSimpleValueType(0);
1117 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1121 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1122 SDValue
Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1123 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1124 X86ISD::VBROADCAST_LOAD, dl, VTs,
Ops, MemNode->getMemoryVT(),
1125 MemNode->getMemOperand());
1128 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1131 CurDAG->getIntPtrConstant(Index, dl));
1134 SDValue To[] = {Res, NarrowBCast.
getValue(1)};
1135 CurDAG->ReplaceAllUsesWith(
N, To);
1147 MVT VT =
N->getSimpleValueType(0);
1153 SDNode *MaxLd =
nullptr;
1154 SDValue Ptr = Ld->getBasePtr();
1155 SDValue Chain = Ld->getChain();
1156 for (SDNode *User : Ptr->
users()) {
1158 MVT UserVT =
User->getSimpleValueType(0);
1160 UserLd->getBasePtr() == Ptr && UserLd->getChain() == Chain &&
1161 !
User->hasAnyUseOfValue(1) &&
1175 CurDAG->getIntPtrConstant(0, dl));
1176 SDValue Res = CurDAG->getBitcast(VT, Extract);
1179 SDValue To[] = {Res, SDValue(MaxLd, 1)};
1180 CurDAG->ReplaceAllUsesWith(
N, To);
1189 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1190 if (EleVT == MVT::i1)
1193 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1194 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1195 "We can't replace VSELECT with BLENDV in vXi16!");
1197 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1199 R = CurDAG->getNode(X86ISD::VPTERNLOG, SDLoc(
N),
N->getValueType(0),
1200 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1201 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1203 R = CurDAG->getNode(X86ISD::BLENDV, SDLoc(
N),
N->getValueType(0),
1204 N->getOperand(0),
N->getOperand(1),
1208 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1221 if (!
N->getSimpleValueType(0).isVector())
1225 switch (
N->getOpcode()) {
1235 if (
N->isStrictFPOpcode())
1237 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1238 {
N->getOperand(0),
N->getOperand(1)});
1241 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1244 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1254 if (!
N->getValueType(0).isVector())
1258 switch (
N->getOpcode()) {
1260 case ISD::SHL: NewOpc = X86ISD::VSHLV;
break;
1261 case ISD::SRA: NewOpc = X86ISD::VSRAV;
break;
1262 case ISD::SRL: NewOpc = X86ISD::VSRLV;
break;
1264 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1265 N->getOperand(0),
N->getOperand(1));
1267 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1276 if (!
N->getValueType(0).isVector())
1280 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1282 "Unexpected opcode for mask vector!");
1290 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1293 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1313 switch (
N->getOpcode()) {
1329 bool IsStrict =
N->isStrictFPOpcode();
1332 Res = CurDAG->getNode(X86ISD::STRICT_VRNDSCALE, dl,
1333 {
N->getValueType(0), MVT::Other},
1334 {
N->getOperand(0),
N->getOperand(1),
1335 CurDAG->getTargetConstant(
Imm, dl, MVT::i32)});
1337 Res = CurDAG->getNode(X86ISD::VRNDSCALE, dl,
N->getValueType(0),
1339 CurDAG->getTargetConstant(
Imm, dl, MVT::i32));
1341 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1349 case X86ISD::FXOR: {
1352 MVT VT =
N->getSimpleValueType(0);
1353 if (VT.
isVector() || VT == MVT::f128)
1356 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1357 : VT == MVT::f32 ? MVT::v4f32
1367 if (Subtarget->hasSSE2()) {
1368 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1372 switch (
N->getOpcode()) {
1374 case X86ISD::FANDN:
Opc = X86ISD::ANDNP;
break;
1379 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1382 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1385 CurDAG->getIntPtrConstant(0, dl));
1387 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
1394 if (OptLevel != CodeGenOptLevel::None &&
1397 !Subtarget->useIndirectThunkCalls() &&
1398 ((
N->getOpcode() == X86ISD::CALL && !Subtarget->slowTwoMemOps() &&
1399 !Subtarget->slowIndirectCall()) ||
1400 (
N->getOpcode() == X86ISD::TC_RETURN &&
1401 (Subtarget->is64Bit() ||
1402 !getTargetMachine().isPositionIndependent())))) {
1422 bool HasCallSeq =
N->getOpcode() == X86ISD::CALL;
1427 if (
N->getOpcode() == X86ISD::TC_RETURN && !checkTCRetEnoughRegs(
N))
1443 switch (
N->getOpcode()) {
1448 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1449 MVT DstVT =
N->getSimpleValueType(0);
1457 const X86TargetLowering *X86Lowering =
1458 static_cast<const X86TargetLowering *
>(TLI);
1461 if (SrcIsSSE && DstIsSSE)
1464 if (!SrcIsSSE && !DstIsSSE) {
1469 if (
N->getConstantOperandVal(1))
1477 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1479 MachinePointerInfo MPI =
1485 SDValue
Store = CurDAG->getTruncStore(
1486 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1488 MemTmp, MPI, MemVT);
1495 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Result);
1504 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1505 MVT DstVT =
N->getSimpleValueType(0);
1513 const X86TargetLowering *X86Lowering =
1514 static_cast<const X86TargetLowering *
>(TLI);
1517 if (SrcIsSSE && DstIsSSE)
1520 if (!SrcIsSSE && !DstIsSSE) {
1525 if (
N->getConstantOperandVal(2))
1533 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1535 MachinePointerInfo MPI =
1544 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1545 SDValue
Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1546 Store = CurDAG->getMemIntrinsicNode(X86ISD::FST, dl, VTs,
Ops, MemVT,
1549 if (
N->getFlags().hasNoFPExcept()) {
1551 Flags.setNoFPExcept(
true);
1552 Store->setFlags(Flags);
1555 assert(SrcVT == MemVT &&
"Unexpected VT!");
1556 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1561 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1563 Result = CurDAG->getMemIntrinsicNode(
1564 X86ISD::FLD, dl, VTs,
Ops, MemVT, MPI,
1566 if (
N->getFlags().hasNoFPExcept()) {
1568 Flags.setNoFPExcept(
true);
1572 assert(DstVT == MemVT &&
"Unexpected VT!");
1573 Result = CurDAG->getLoad(DstVT, dl,
Store, MemTmp, MPI);
1581 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1595 CurDAG->RemoveDeadNodes();
1599bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1600 unsigned Opc =
N->getMachineOpcode();
1601 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1602 Opc != X86::MOVSX64rr8)
1605 SDValue N0 =
N->getOperand(0);
1614 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1615 : X86::MOVSX32rr8_NOREX;
1620 if (
Opc == X86::MOVSX64rr8) {
1623 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1625 ReplaceUses(
N, Extend);
1634void X86DAGToDAGISel::PostprocessISelDAG() {
1636 if (TM.getOptLevel() == CodeGenOptLevel::None)
1641 bool MadeChange =
false;
1642 while (Position != CurDAG->allnodes_begin()) {
1643 SDNode *
N = &*--Position;
1645 if (
N->use_empty() || !
N->isMachineOpcode())
1648 if (tryOptimizeRem8Extend(
N)) {
1653 unsigned Opc =
N->getMachineOpcode();
1664 case X86::CTEST16rr:
1665 case X86::CTEST32rr:
1666 case X86::CTEST64rr: {
1672#define CASE_ND(OP) \
1675 switch (
And.getMachineOpcode()) {
1682 if (
And->hasAnyUseOfValue(1))
1685 Ops[0] =
And.getOperand(0);
1686 Ops[1] =
And.getOperand(1);
1687 MachineSDNode *
Test =
1688 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1689 ReplaceUses(
N,
Test);
1697 if (
And->hasAnyUseOfValue(1))
1700 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1701#define FROM_TO(A, B) \
1702 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1704 switch (
And.getMachineOpcode()) {
1714 And.getOperand(3),
And.getOperand(4),
1715 And.getOperand(5),
And.getOperand(0)};
1718 Ops.push_back(
N->getOperand(2));
1719 Ops.push_back(
N->getOperand(3));
1722 Ops.push_back(
And.getOperand(6));
1725 Ops.push_back(
N->getOperand(4));
1727 MachineSDNode *
Test = CurDAG->getMachineNode(
1728 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1729 CurDAG->setNodeMemRefs(
1731 ReplaceUses(
And.getValue(2), SDValue(
Test, 1));
1732 ReplaceUses(SDValue(
N, 0), SDValue(
Test, 0));
1742 case X86::KORTESTBkk:
1743 case X86::KORTESTWkk:
1744 case X86::KORTESTDkk:
1745 case X86::KORTESTQkk: {
1747 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1762#define FROM_TO(A, B) \
1774 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1777 MachineSDNode *KTest = CurDAG->getMachineNode(
1779 ReplaceUses(
N, KTest);
1784 case TargetOpcode::SUBREG_TO_REG: {
1785 unsigned SubRegIdx =
N->getConstantOperandVal(1);
1786 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1789 SDValue Move =
N->getOperand(0);
1803 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1804 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1805 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1806 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1807 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1808 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1809 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1810 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1815 if (!
In.isMachineOpcode() ||
1816 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1821 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1829 CurDAG->UpdateNodeOperands(
N, In,
N->getOperand(1));
1836 CurDAG->RemoveDeadNodes();
1841void X86DAGToDAGISel::emitSpecialCodeForMain() {
1842 if (Subtarget->isTargetCygMing()) {
1843 TargetLowering::ArgListTy
Args;
1844 auto &
DL = CurDAG->getDataLayout();
1846 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1847 CLI.setChain(CurDAG->getRoot())
1848 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1849 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1851 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1853 CurDAG->setRoot(
Result.second);
1857void X86DAGToDAGISel::emitFunctionEntryCode() {
1860 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1861 emitSpecialCodeForMain();
1875 X86ISelAddressMode &AM) {
1880 int64_t Val = AM.Disp +
Offset;
1883 if (Val != 0 && (AM.ES || AM.MCSym))
1887 if (Subtarget->is64Bit()) {
1890 AM.hasSymbolicDisplacement()))
1894 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1913 if (Subtarget->isTarget64BitILP32() &&
1915 !AM.hasBaseOrIndexReg())
1917 }
else if (Subtarget->is16Bit()) {
1920 if (Val < -(int64_t)UINT16_MAX || Val > (int64_t)UINT16_MAX)
1930bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1931 bool AllowSegmentRegForX32) {
1932 SDValue
Address =
N->getOperand(1);
1944 !IndirectTlsSegRefs &&
1945 (Subtarget->isTargetGlibc() || Subtarget->isTargetMusl() ||
1946 Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())) {
1947 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1949 switch (
N->getPointerInfo().getAddrSpace()) {
1951 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1954 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1967bool X86DAGToDAGISel::matchWrapper(SDValue
N, X86ISelAddressMode &AM) {
1970 if (AM.hasSymbolicDisplacement())
1973 bool IsRIPRelTLS =
false;
1974 bool IsRIPRel =
N.getOpcode() == X86ISD::WrapperRIP;
1976 SDValue Val =
N.getOperand(0);
1991 if (IsRIPRel && AM.hasBaseOrIndexReg())
1995 X86ISelAddressMode Backup = AM;
2000 AM.GV =
G->getGlobal();
2001 AM.SymbolFlags =
G->getTargetFlags();
2004 AM.CP = CP->getConstVal();
2005 AM.Alignment = CP->getAlign();
2006 AM.SymbolFlags = CP->getTargetFlags();
2007 Offset = CP->getOffset();
2009 AM.ES = S->getSymbol();
2010 AM.SymbolFlags = S->getTargetFlags();
2012 AM.MCSym = S->getMCSymbol();
2014 AM.JT = J->getIndex();
2015 AM.SymbolFlags = J->getTargetFlags();
2017 AM.BlockAddr = BA->getBlockAddress();
2018 AM.SymbolFlags = BA->getTargetFlags();
2019 Offset = BA->getOffset();
2024 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
2025 TM.isLargeGlobalValue(AM.GV)) {
2030 if (foldOffsetIntoAddress(
Offset, AM)) {
2036 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
2044bool X86DAGToDAGISel::matchAddress(SDValue
N, X86ISelAddressMode &AM) {
2045 if (matchAddressRecursively(
N, AM, 0))
2052 if (Subtarget->isTarget64BitILP32() &&
2053 AM.BaseType == X86ISelAddressMode::RegBase &&
2054 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
2055 SDValue Save_Base_Reg = AM.Base_Reg;
2057 AM.Base_Reg = SDValue();
2058 if (matchLoadInAddress(LoadN, AM,
true))
2059 AM.Base_Reg = Save_Base_Reg;
2068 if (AM.Scale == 2 && !AM.NegateIndex &&
2069 AM.BaseType == X86ISelAddressMode::RegBase &&
2070 AM.Base_Reg.
getNode() ==
nullptr) {
2071 AM.Base_Reg = AM.IndexReg;
2078 (!AM.GV || !TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2079 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2080 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2092 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2105bool X86DAGToDAGISel::hasMaterializingUse(SDValue V)
const {
2106 const TargetInstrInfo *
TII = Subtarget->getInstrInfo();
2107 for (SDUse &U :
V->uses()) {
2108 if (
U.getResNo() !=
V.getResNo())
2110 SDNode *
User =
U.getUser();
2116 if (St->getValue() == V)
2127 if (!
User->isMachineOpcode())
2129 const MCInstrDesc &
Desc =
TII->get(
User->getMachineOpcode());
2130 if (!
Desc.mayStore())
2133 if (MemRefBegin < 0)
2136 for (
unsigned I = 0,
E =
User->getNumOperands();
I !=
E; ++
I) {
2137 if (
I >=
static_cast<unsigned>(MemRefBegin) &&
I < MemRefEnd)
2139 SDValue Opnd =
User->getOperand(
I);
2149bool X86DAGToDAGISel::matchAdd(SDValue &
N, X86ISelAddressMode &AM,
2153 HandleSDNode Handle(
N);
2155 auto IsAddOrAddLike = [&](SDValue
V) {
2156 return V.getOpcode() ==
ISD::ADD || CurDAG->isADDLike(V);
2165 auto SplitsMaterializedValue = [&](SDValue
Op) {
2166 if (!AM.IsForLEA || !hasMaterializingUse(
Op))
2170 if (IsAddOrAddLike(
Op))
2171 return IsAddOrAddLike(
Op.getOperand(0)) ||
2172 IsAddOrAddLike(
Op.getOperand(1));
2177 return C->getZExtValue() >= 1 &&
C->getZExtValue() <= 3 &&
2178 IsAddOrAddLike(
Op.getOperand(0));
2188 auto MatchOperand = [&](SDValue
Op) {
2198 if (SplitsMaterializedValue(
Op) && !AM.isRIPRelative())
2199 return matchAddressBase(
Op, AM);
2200 return matchAddressRecursively(
Op, AM,
Depth + 1);
2203 X86ISelAddressMode Backup = AM;
2204 if (!MatchOperand(
N.getOperand(0)) &&
2205 !MatchOperand(Handle.getValue().getOperand(1)))
2210 if (!MatchOperand(Handle.getValue().getOperand(1)) &&
2211 !MatchOperand(Handle.getValue().getOperand(0)))
2218 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2221 N = Handle.getValue();
2227 N = Handle.getValue();
2237 if (
N->getNodeId() == -1 ||
2257 X86ISelAddressMode &AM) {
2264 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2265 Mask != (0xffu << ScaleLog))
2268 MVT XVT =
X.getSimpleValueType();
2269 MVT VT =
N.getSimpleValueType();
2294 AM.Scale = (1 << ScaleLog);
2302 X86ISelAddressMode &AM) {
2313 bool FoundAnyExtend =
false;
2317 FoundAnyExtend =
true;
2335 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2338 MVT VT =
N.getSimpleValueType();
2340 if (FoundAnyExtend) {
2361 AM.Scale = 1 << ShiftAmt;
2362 AM.IndexReg = NewAnd;
2396 X86ISelAddressMode &AM) {
2402 unsigned MaskIdx, MaskLen;
2405 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2411 unsigned AMShiftAmt = MaskIdx;
2415 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2419 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2420 if (MaskLZ < ScaleDown)
2422 MaskLZ -= ScaleDown;
2430 bool ReplacingAnyExtend =
false;
2432 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2433 X.getOperand(0).getSimpleValueType().getSizeInBits();
2436 X =
X.getOperand(0);
2437 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2438 ReplacingAnyExtend =
true;
2440 APInt MaskedHighBits =
2447 MVT VT =
N.getSimpleValueType();
2448 if (ReplacingAnyExtend) {
2449 assert(
X.getValueType() != VT);
2456 MVT XVT =
X.getSimpleValueType();
2477 AM.Scale = 1 << AMShiftAmt;
2478 AM.IndexReg = NewExt;
2488 X86ISelAddressMode &AM,
2496 if (!Subtarget.hasTBM() &&
2497 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2501 unsigned MaskIdx, MaskLen;
2509 unsigned AMShiftAmt = MaskIdx;
2513 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2515 MVT XVT =
X.getSimpleValueType();
2516 MVT VT =
N.getSimpleValueType();
2541 AM.Scale = 1 << AMShiftAmt;
2542 AM.IndexReg = NewExt;
2548SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue
N,
2549 X86ISelAddressMode &AM,
2551 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2552 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2553 "Illegal index scale");
2559 EVT VT =
N.getValueType();
2560 unsigned Opc =
N.getOpcode();
2563 if (CurDAG->isBaseWithConstantOffset(
N)) {
2566 if (!foldOffsetIntoAddress(
Offset, AM))
2567 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2571 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2572 if (AM.Scale <= 4) {
2574 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2579 if (
Opc == X86ISD::VSHLI) {
2580 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2581 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2582 if ((AM.Scale * ScaleAmt) <= 8) {
2583 AM.Scale *= ScaleAmt;
2584 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2591 SDValue Src =
N.getOperand(0);
2592 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2594 if (CurDAG->isBaseWithConstantOffset(Src)) {
2595 SDValue AddSrc = Src.getOperand(0);
2597 int64_t
Offset = AddVal->getSExtValue();
2600 SDValue ExtSrc = CurDAG->getNode(
Opc,
DL, VT, AddSrc);
2601 SDValue ExtVal = CurDAG->getSignedConstant(
Offset,
DL, VT);
2602 SDValue ExtAdd = CurDAG->getNode(
ISD::ADD,
DL, VT, ExtSrc, ExtVal);
2606 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2607 CurDAG->RemoveDeadNode(
N.getNode());
2618 SDValue Src =
N.getOperand(0);
2619 unsigned SrcOpc = Src.getOpcode();
2620 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2621 CurDAG->isADDLike(Src,
true)) &&
2623 if (CurDAG->isBaseWithConstantOffset(Src)) {
2624 SDValue AddSrc = Src.getOperand(0);
2626 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2637 if ((AM.Scale * ScaleAmt) <= 8 &&
2639 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2640 AM.Scale *= ScaleAmt;
2641 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2642 SDValue ExtShift = CurDAG->getNode(
ISD::SHL,
DL, VT, ExtShVal,
2650 SDValue ExtSrc = CurDAG->getNode(
Opc,
DL, VT, AddSrc);
2651 SDValue ExtVal = CurDAG->getConstant(
Offset,
DL, VT);
2652 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2656 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2657 CurDAG->RemoveDeadNode(
N.getNode());
2658 return Res ? Res : ExtSrc;
2668bool X86DAGToDAGISel::matchAddressRecursively(SDValue
N, X86ISelAddressMode &AM,
2671 dbgs() <<
"MatchAddress: ";
2676 return matchAddressBase(
N, AM);
2681 if (AM.isRIPRelative()) {
2685 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2689 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2694 switch (
N.getOpcode()) {
2697 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2700 AM.MCSym = ESNode->getMCSymbol();
2707 if (!foldOffsetIntoAddress(Val, AM))
2712 case X86ISD::Wrapper:
2713 case X86ISD::WrapperRIP:
2714 if (!matchWrapper(
N, AM))
2724 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2725 AM.Base_Reg.
getNode() ==
nullptr &&
2727 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2734 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2738 unsigned Val = CN->getZExtValue();
2743 if (Val == 1 || Val == 2 || Val == 3) {
2745 AM.Scale = 1 << Val;
2746 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2754 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2758 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2759 "Unexpected value size!");
2761 SDValue
And =
N.getOperand(0);
2763 SDValue
X =
And.getOperand(0);
2771 uint64_t Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2783 if (
N.getResNo() != 0)
break;
2786 case X86ISD::MUL_IMM:
2788 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2789 AM.Base_Reg.
getNode() ==
nullptr &&
2790 AM.IndexReg.
getNode() ==
nullptr) {
2792 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2793 CN->getZExtValue() == 9) {
2794 AM.Scale = unsigned(CN->getZExtValue())-1;
2796 SDValue MulVal =
N.getOperand(0);
2806 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2807 if (foldOffsetIntoAddress(Disp, AM))
2808 Reg =
N.getOperand(0);
2810 Reg =
N.getOperand(0);
2813 AM.IndexReg = AM.Base_Reg =
Reg;
2831 HandleSDNode Handle(
N);
2834 X86ISelAddressMode Backup = AM;
2835 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2836 N = Handle.getValue();
2840 N = Handle.getValue();
2842 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2848 SDValue
RHS =
N.getOperand(1);
2861 std::optional<unsigned> NegScale;
2864 uint64_t ShVal = ShAmt->getZExtValue();
2865 if (ShVal >= 1 && ShVal <= 3) {
2866 NegScale = 1u << ShVal;
2884 RHS.getOperand(0).getValueType() == MVT::i32))
2887 bool BaseIsNegatedValue = NegScale &&
2888 AM.BaseType == X86ISelAddressMode::RegBase &&
2895 if (((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2897 AM.BaseType == X86ISelAddressMode::FrameIndexBase) &&
2898 !BaseIsNegatedValue)
2902 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2903 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2916 AM.NegateIndex =
true;
2917 AM.Scale = NegScale.value_or(1);
2924 if (!CurDAG->isADDLike(
N))
2928 if (!matchAdd(
N, AM,
Depth))
2937 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2941 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2942 "Unexpected value size!");
2947 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2948 SDValue Shift =
N.getOperand(0);
2976 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2979 SDValue Src =
N.getOperand(0);
2984 if (SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2986 AM.IndexReg =
Index;
2992 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2994 Mask = MaskC->getAPIntValue();
2995 Src = Src.getOperand(0);
2998 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
3000 SDValue ShlSrc = Src.getOperand(0);
3001 SDValue ShlAmt = Src.getOperand(1);
3005 unsigned ShAmtV = ShAmtC->getZExtValue();
3013 if (!Src->getFlags().hasNoUnsignedWrap() &&
3014 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
3022 MVT VT =
N.getSimpleValueType();
3025 SDValue Res = ShlSrc;
3026 if (!
Mask.isAllOnes()) {
3027 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
3029 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
3034 SDValue NewShl = CurDAG->getNode(
ISD::SHL,
DL, VT, Zext, ShlAmt);
3036 CurDAG->ReplaceAllUsesWith(
N, NewShl);
3037 CurDAG->RemoveDeadNode(
N.getNode());
3040 AM.Scale = 1 << ShAmtV;
3044 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
3048 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
3051 Src.getOperand(0), AM))
3056 Src.getOperand(0), AM))
3061 Src.getOperand(0), AM, *Subtarget))
3069 return matchAddressBase(
N, AM);
3074bool X86DAGToDAGISel::matchAddressBase(SDValue
N, X86ISelAddressMode &AM) {
3076 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
3089 AM.BaseType = X86ISelAddressMode::RegBase;
3094bool X86DAGToDAGISel::matchVectorAddressRecursively(SDValue
N,
3095 X86ISelAddressMode &AM,
3098 dbgs() <<
"MatchVectorAddress: ";
3103 return matchAddressBase(
N, AM);
3106 switch (
N.getOpcode()) {
3109 if (!foldOffsetIntoAddress(Val, AM))
3113 case X86ISD::Wrapper:
3114 if (!matchWrapper(
N, AM))
3120 HandleSDNode Handle(
N);
3122 X86ISelAddressMode Backup = AM;
3123 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
3124 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
3130 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
3132 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
3137 N = Handle.getValue();
3142 return matchAddressBase(
N, AM);
3148bool X86DAGToDAGISel::matchVectorAddress(SDValue
N, X86ISelAddressMode &AM) {
3149 return matchVectorAddressRecursively(
N, AM, 0);
3152bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent, SDValue BasePtr,
3153 SDValue IndexOp, SDValue ScaleOp,
3154 SDValue &
Base, SDValue &Scale,
3155 SDValue &Index, SDValue &Disp,
3157 X86ISelAddressMode AM;
3163 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
3165 AM.IndexReg = IndexOp;
3169 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3171 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3173 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3176 MVT VT =
BasePtr.getSimpleValueType();
3179 if (matchVectorAddress(BasePtr, AM))
3182 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3193bool X86DAGToDAGISel::selectAddr(SDNode *Parent, SDValue
N, SDValue &
Base,
3194 SDValue &Scale, SDValue &Index, SDValue &Disp,
3195 SDValue &Segment,
bool HasNDDM) {
3196 X86ISelAddressMode AM;
3203 Parent->
getOpcode() != X86ISD::TLSCALL &&
3204 Parent->
getOpcode() != X86ISD::ENQCMD &&
3205 Parent->
getOpcode() != X86ISD::ENQCMDS &&
3206 Parent->
getOpcode() != X86ISD::EH_SJLJ_SETJMP &&
3207 Parent->
getOpcode() != X86ISD::EH_SJLJ_LONGJMP) {
3208 unsigned AddrSpace =
3211 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3213 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3215 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3220 MVT VT =
N.getSimpleValueType();
3222 if (matchAddress(
N, AM))
3225 if (!HasNDDM && !AM.isRIPRelative())
3228 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3232bool X86DAGToDAGISel::selectNDDAddr(SDNode *Parent, SDValue
N, SDValue &
Base,
3233 SDValue &Scale, SDValue &Index,
3234 SDValue &Disp, SDValue &Segment) {
3235 return selectAddr(Parent,
N,
Base, Scale, Index, Disp, Segment,
3236 Subtarget->hasNDDM());
3239bool X86DAGToDAGISel::selectMOV64Imm32(SDValue
N, SDValue &
Imm) {
3248 if (
N->getOpcode() != X86ISD::Wrapper)
3251 N =
N.getOperand(0);
3268 return CR->getUnsignedMax().ult(1ull << 32);
3270 return !TM.isLargeGlobalValue(GV);
3273bool X86DAGToDAGISel::selectLEA64_Addr(SDValue
N, SDValue &
Base, SDValue &Scale,
3274 SDValue &Index, SDValue &Disp,
3279 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3285 SubReg = X86::sub_8bit;
3287 SubReg = X86::sub_16bit;
3289 SubReg = X86::sub_32bit;
3292 if (RN &&
RN->getReg() == 0)
3293 Base = CurDAG->getRegister(0, MVT::i64);
3298 SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF,
DL,
3300 Base = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef,
Base);
3303 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3305 if (RN &&
RN->getReg() == 0)
3306 Index = CurDAG->getRegister(0, MVT::i64);
3309 "Expect to be extending 8/16/32-bit registers for use in LEA");
3310 SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF,
DL,
3312 Index = CurDAG->getTargetInsertSubreg(SubReg,
DL, MVT::i64, ImplDef, Index);
3320bool X86DAGToDAGISel::selectLEAAddr(SDValue
N,
3321 SDValue &
Base, SDValue &Scale,
3322 SDValue &Index, SDValue &Disp,
3324 X86ISelAddressMode AM;
3329 MVT VT =
N.getSimpleValueType();
3333 SDValue
Copy = AM.Segment;
3334 SDValue
T = CurDAG->getRegister(0, MVT::i32);
3336 if (matchAddress(
N, AM))
3341 unsigned Complexity = 0;
3342 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3344 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3360 if (AM.hasSymbolicDisplacement()) {
3362 if (Subtarget->is64Bit())
3372 auto isMathWithFlags = [](SDValue
V) {
3373 switch (
V.getOpcode()) {
3387 return !SDValue(
V.getNode(), 1).use_empty();
3394 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3402 if (Complexity <= 2)
3405 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3410bool X86DAGToDAGISel::selectTLSADDRAddr(SDValue
N, SDValue &
Base,
3411 SDValue &Scale, SDValue &Index,
3412 SDValue &Disp, SDValue &Segment) {
3416 X86ISelAddressMode AM;
3418 AM.GV = GA->getGlobal();
3419 AM.Disp += GA->getOffset();
3420 AM.SymbolFlags = GA->getTargetFlags();
3423 AM.ES = SA->getSymbol();
3424 AM.SymbolFlags = SA->getTargetFlags();
3427 if (Subtarget->is32Bit()) {
3429 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3432 MVT VT =
N.getSimpleValueType();
3433 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3437bool X86DAGToDAGISel::selectRelocImm(SDValue
N, SDValue &
Op) {
3441 EVT VT =
N.getValueType();
3442 bool WasTruncated =
false;
3444 WasTruncated =
true;
3445 N =
N.getOperand(0);
3448 if (
N.getOpcode() != X86ISD::Wrapper)
3454 unsigned Opc =
N.getOperand(0)->getOpcode();
3456 Op =
N.getOperand(0);
3459 return !WasTruncated;
3464 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3465 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3469 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3470 GA->getOffset(), GA->getTargetFlags());
3474bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P, SDValue
N,
3475 SDValue &
Base, SDValue &Scale,
3476 SDValue &Index, SDValue &Disp,
3478 assert(Root &&
P &&
"Unknown root/parent nodes");
3480 !IsProfitableToFold(
N,
P, Root) ||
3481 !IsLegalToFold(
N,
P, Root, OptLevel))
3484 return selectAddr(
N.getNode(),
3485 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3488bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P, SDValue
N,
3489 SDValue &
Base, SDValue &Scale,
3490 SDValue &Index, SDValue &Disp,
3492 assert(Root &&
P &&
"Unknown root/parent nodes");
3493 if (
N->getOpcode() != X86ISD::VBROADCAST_LOAD ||
3494 !IsProfitableToFold(
N,
P, Root) ||
3495 !IsLegalToFold(
N,
P, Root, OptLevel))
3498 return selectAddr(
N.getNode(),
3499 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3505SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3508 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3511bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3513 N =
N->getOperand(0).getNode();
3514 if (
N->getOpcode() != X86ISD::Wrapper)
3521 auto *GV = GA->getGlobal();
3524 return CR->getSignedMin().sge(-1ull << Width) &&
3525 CR->getSignedMax().slt(1ull << Width);
3531 !TM.isLargeGlobalValue(GV);
3535 assert(
N->isMachineOpcode() &&
"Unexpected node");
3536 unsigned Opc =
N->getMachineOpcode();
3537 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3542 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3547bool X86DAGToDAGISel::onlyUsesZeroFlag(SDValue Flags)
const {
3549 for (SDUse &Use :
Flags->uses()) {
3551 if (
Use.getResNo() !=
Flags.getResNo())
3559 for (SDUse &FlagUse :
User->uses()) {
3561 if (FlagUse.getResNo() != 1)
3564 if (!FlagUse.getUser()->isMachineOpcode())
3584bool X86DAGToDAGISel::hasNoSignFlagUses(SDValue Flags)
const {
3586 for (SDUse &Use :
Flags->uses()) {
3588 if (
Use.getResNo() !=
Flags.getResNo())
3596 for (SDUse &FlagUse :
User->uses()) {
3598 if (FlagUse.getResNo() != 1)
3601 if (!FlagUse.getUser()->isMachineOpcode())
3641 bool X86DAGToDAGISel::hasNoCarryFlagUses(SDValue Flags)
const {
3643 for (SDUse &Use :
Flags->uses()) {
3645 if (
Use.getResNo() !=
Flags.getResNo())
3649 unsigned UserOpc =
User->getOpcode();
3656 for (SDUse &FlagUse :
User->uses()) {
3658 if (FlagUse.getResNo() != 1)
3661 if (!FlagUse.getUser()->isMachineOpcode())
3681 case X86ISD::SETCC: CCOpNo = 0;
break;
3682 case X86ISD::SETCC_CARRY: CCOpNo = 0;
break;
3683 case X86ISD::CMOV: CCOpNo = 2;
break;
3684 case X86ISD::BRCOND: CCOpNo = 2;
break;
3697 unsigned Depth = 0) {
3718bool X86DAGToDAGISel::checkTCRetEnoughRegs(SDNode *
N)
const {
3719 assert(
N->getOpcode() == X86ISD::TC_RETURN);
3730 const X86RegisterInfo *RI = Subtarget->getRegisterInfo();
3734 if (Subtarget->is64Bit()) {
3737 ? &X86::GR64_TCW64RegClass
3738 : &X86::GR64_TCRegClass;
3746 ? &X86::GR32RegClass
3747 : &X86::GR32_TCRegClass;
3754 unsigned LoadGPRs = 2;
3756 if (Subtarget->is32Bit()) {
3761 }
else if (
BasePtr.getOpcode() == X86ISD::Wrapper &&
3763 if (getTargetMachine().isPositionIndependent())
3771 for (
unsigned I = 3,
E =
N->getNumOperands();
I !=
E; ++
I) {
3773 if (!RI->isGeneralPurposeRegister(*MF,
RN->getReg()))
3775 if (++
ArgGPRs + LoadGPRs > AvailGPRs)
3791 if (StoredVal.
getResNo() != 0)
return false;
3808 if (!
Load.hasOneUse())
3816 bool FoundLoad =
false;
3820 const unsigned int Max = 1024;
3862 if (Chain ==
Load.getValue(1)) {
3868 if (
Op ==
Load.getValue(1)) {
3884 if (
Op.getNode() != LoadNode)
3916bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3918 SDValue StoredVal = StoreNode->getOperand(1);
3924 EVT MemVT = StoreNode->getMemoryVT();
3925 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3929 bool IsCommutable =
false;
3930 bool IsNegate =
false;
3944 IsCommutable =
true;
3948 unsigned LoadOpNo = IsNegate ? 1 : 0;
3949 LoadSDNode *LoadNode =
nullptr;
3952 LoadNode, InputChain)) {
3959 LoadNode, InputChain))
3963 SDValue
Base, Scale,
Index, Disp, Segment;
3964 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3968 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3989 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3991 const SDValue
Ops[] = {
Base, Scale,
Index, Disp, Segment, InputChain};
3992 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3999 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
4003 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
4005 ((
Opc == X86ISD::ADD) == IsOne)
4006 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
4007 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
4008 const SDValue
Ops[] = {
Base, Scale,
Index, Disp, Segment, InputChain};
4009 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
4020 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
4023 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
4026 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
4029 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
4032 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
4035 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
4038 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
4040 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
4046 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
4049 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
4052 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
4055 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
4058 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
4061 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
4064 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
4067 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
4074 unsigned NewOpc = SelectRegOpcode(
Opc);
4075 SDValue Operand = StoredVal->
getOperand(1-LoadOpNo);
4080 int64_t OperandV = OperandC->getSExtValue();
4085 if ((
Opc == X86ISD::ADD ||
Opc == X86ISD::SUB) &&
4087 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
4089 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
4090 OperandV = -OperandV;
4091 Opc =
Opc == X86ISD::ADD ? X86ISD::SUB : X86ISD::ADD;
4094 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
4095 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
4096 NewOpc = SelectImmOpcode(
Opc);
4100 if (
Opc == X86ISD::ADC ||
Opc == X86ISD::SBB) {
4102 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
4106 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
4107 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
4111 Segment, Operand, InputChain};
4112 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
4121 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
4123 CurDAG->setNodeMemRefs(Result, MemOps);
4126 ReplaceUses(SDValue(LoadNode, 1), SDValue(Result, 1));
4127 ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));
4128 ReplaceUses(SDValue(StoredVal.
getNode(), 1), SDValue(Result, 0));
4129 CurDAG->RemoveDeadNode(Node);
4141bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
4144 "Should be either an and-mask, a standalone low-bits mask, or "
4145 "right-shift after clearing high bits.");
4148 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
4151 MVT NVT =
Node->getSimpleValueType(0);
4154 if (NVT != MVT::i32 && NVT != MVT::i64)
4162 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
4163 auto checkUses = [AllowExtraUsesByDefault](
4164 SDValue
Op,
unsigned NUses,
4165 std::optional<bool> AllowExtraUses) {
4166 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
4167 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
4169 auto checkOneUse = [checkUses](SDValue
Op,
4170 std::optional<bool> AllowExtraUses =
4172 return checkUses(
Op, 1, AllowExtraUses);
4174 auto checkTwoUse = [checkUses](SDValue
Op,
4175 std::optional<bool> AllowExtraUses =
4177 return checkUses(
Op, 2, AllowExtraUses);
4180 auto peekThroughOneUseTruncation = [checkOneUse](SDValue
V) {
4182 assert(
V.getSimpleValueType() == MVT::i32 &&
4183 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
4184 "Expected i64 -> i32 truncation");
4185 V =
V.getOperand(0);
4191 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
4192 &NegateNBits](SDValue
Mask) ->
bool {
4194 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
4200 SDValue
M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4205 NBits =
M0->getOperand(1);
4206 NegateNBits =
false;
4210 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](SDValue
V) {
4211 V = peekThroughOneUseTruncation(V);
4212 return CurDAG->MaskedValueIsAllOnes(
4218 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
4219 &NBits, &NegateNBits](SDValue
Mask) ->
bool {
4221 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
4224 if (!isAllOnes(
Mask->getOperand(1)))
4227 SDValue
M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
4231 if (!isAllOnes(
M0->getOperand(0)))
4233 NBits =
M0->getOperand(1);
4234 NegateNBits =
false;
4240 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](SDValue ShiftAmt,
4241 unsigned Bitwidth) {
4246 NBits = NBits.getOperand(0);
4252 if (!V0 ||
V0->getZExtValue() != Bitwidth)
4254 NBits = NBits.getOperand(1);
4255 NegateNBits =
false;
4261 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
4262 canonicalizeShiftAmt](SDValue
Mask) ->
bool {
4264 Mask = peekThroughOneUseTruncation(Mask);
4265 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
4267 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
4272 SDValue
M1 =
Mask.getOperand(1);
4274 if (!checkOneUse(
M1))
4276 canonicalizeShiftAmt(
M1, Bitwidth);
4281 return !NegateNBits;
4289 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
4290 AllowExtraUsesByDefault, &NegateNBits,
4291 &
X](SDNode *
Node) ->
bool {
4294 SDValue N0 =
Node->getOperand(0);
4298 SDValue N1 =
Node->getOperand(1);
4303 canonicalizeShiftAmt(N1, Bitwidth);
4307 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
4308 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4314 auto matchLowBitMask = [matchPatternA, matchPatternB,
4315 matchPatternC](SDValue
Mask) ->
bool {
4316 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4320 X =
Node->getOperand(0);
4321 SDValue
Mask =
Node->getOperand(1);
4323 if (matchLowBitMask(Mask)) {
4327 if (!matchLowBitMask(Mask))
4330 }
else if (matchLowBitMask(SDValue(Node, 0))) {
4331 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4332 }
else if (!matchPatternD(Node))
4337 if (NegateNBits && !Subtarget->hasBMI2())
4342 if (NBits.getSimpleValueType() != MVT::i8) {
4349 ConstantSDNode *
Imm =
nullptr;
4350 if (NBits->getOpcode() ==
ISD::AND)
4352 NBits = NBits->getOperand(0);
4356 SDValue ImplDef = SDValue(
4357 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4360 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4362 NBits = SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4363 MVT::i32, ImplDef, NBits, SRIdxVal),
4369 CurDAG->getNode(
ISD::AND,
DL, MVT::i32, NBits,
4370 CurDAG->getConstant(
Imm->getZExtValue(),
DL, MVT::i32));
4377 SDValue BitWidthC = CurDAG->getConstant(NVT.
getSizeInBits(),
DL, MVT::i32);
4380 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4384 if (Subtarget->hasBMI2()) {
4386 if (NVT != MVT::i32) {
4392 SDValue Extract = CurDAG->getNode(X86ISD::BZHI,
DL, NVT,
X, NBits);
4393 ReplaceNode(Node, Extract.
getNode());
4394 SelectCode(Extract.
getNode());
4403 SDValue RealX = peekThroughOneUseTruncation(
X);
4409 MVT XVT =
X.getSimpleValueType();
4419 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4421 SDValue Control = CurDAG->getNode(
ISD::SHL,
DL, MVT::i32, NBits, C8);
4427 SDValue ShiftAmt =
X.getOperand(1);
4428 X =
X.getOperand(0);
4431 "Expected shift amount to be i8");
4435 SDValue OrigShiftAmt = ShiftAmt;
4440 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4445 if (XVT != MVT::i32) {
4451 SDValue Extract = CurDAG->getNode(X86ISD::BEXTR,
DL, XVT,
X, Control);
4459 ReplaceNode(Node, Extract.
getNode());
4460 SelectCode(Extract.
getNode());
4466MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4467 MVT NVT =
Node->getSimpleValueType(0);
4470 SDValue N0 =
Node->getOperand(0);
4471 SDValue N1 =
Node->getOperand(1);
4480 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4481 if (!PreferBEXTR && !Subtarget->hasBMI2())
4493 if (NVT != MVT::i32 && NVT != MVT::i64)
4499 if (!MaskCst || !ShiftCst)
4507 uint64_t Shift = ShiftCst->getZExtValue();
4512 if (Shift == 8 && MaskSize == 8)
4523 if (!PreferBEXTR && MaskSize <= 32)
4527 unsigned ROpc, MOpc;
4529#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4531 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4535 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4540 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4541 Control = SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4547 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4548 if (Subtarget->hasTBM()) {
4549 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4550 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4552 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4558 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4559 Control = SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4563 MachineSDNode *NewNode;
4565 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4566 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4568 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4569 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4570 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4572 ReplaceUses(Input.
getValue(1), SDValue(NewNode, 2));
4574 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4576 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4581 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4585 CurDAG->getMachineNode(NewOpc, dl, NVT, SDValue(NewNode, 0), ShAmt);
4592MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4593 bool MayFoldLoad,
const SDLoc &dl,
4594 MVT VT, SDNode *Node) {
4595 SDValue N0 =
Node->getOperand(0);
4596 SDValue N1 =
Node->getOperand(1);
4597 SDValue
Imm =
Node->getOperand(2);
4599 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4602 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4603 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4604 SDValue
Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4606 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4607 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4609 ReplaceUses(N1.
getValue(1), SDValue(CNode, 2));
4615 SDValue
Ops[] = { N0, N1,
Imm };
4616 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4617 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4624MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4625 bool MayFoldLoad,
const SDLoc &dl,
4626 MVT VT, SDNode *Node,
4628 SDValue N0 =
Node->getOperand(0);
4629 SDValue N2 =
Node->getOperand(2);
4630 SDValue
Imm =
Node->getOperand(4);
4632 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4635 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4636 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4637 SDValue
Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4639 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4640 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4641 InGlue = SDValue(CNode, 3);
4643 ReplaceUses(N2.
getValue(1), SDValue(CNode, 2));
4649 SDValue
Ops[] = { N0, N2,
Imm, InGlue };
4650 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4651 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4652 InGlue = SDValue(CNode, 2);
4656bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4657 EVT VT =
N->getValueType(0);
4664 unsigned Size = VT == MVT::i64 ? 64 : 32;
4667 SDValue ShiftAmt = OrigShiftAmt;
4677 SDValue NewShiftAmt;
4686 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4690 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4691 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4695 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4703 SDValue
AllOnes = CurDAG->getAllOnesConstant(
DL, OpVT);
4704 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4705 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4711 Add0C->getZExtValue() != 0) {
4714 if (Add0C->getZExtValue() %
Size == 0)
4717 Add0C->getZExtValue() % 32 == 0) {
4725 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4729 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4736 SDValue
Zero = CurDAG->getConstant(0,
DL, SubVT);
4737 SDValue Neg = CurDAG->getNode(
ISD::SUB,
DL, SubVT, Zero,
X);
4751 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4758 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4759 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4763 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4765 if (UpdatedNode !=
N) {
4768 ReplaceNode(
N, UpdatedNode);
4775 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4783bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4784 MVT NVT =
N->getSimpleValueType(0);
4785 unsigned Opcode =
N->getOpcode();
4790 SDValue Shift =
N->getOperand(0);
4797 int64_t Val = Cst->getSExtValue();
4802 bool FoundAnyExtend =
false;
4806 FoundAnyExtend =
true;
4814 if (NVT != MVT::i32 && NVT != MVT::i64)
4821 uint64_t ShAmt = ShlCst->getZExtValue();
4825 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4826 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4831 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4835 ShiftedVal = (
uint64_t)Val >> ShAmt;
4839 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4842 ShiftedVal = Val >> ShAmt;
4848 ShiftedVal = (
uint64_t)Val >> ShAmt;
4856 if (!CanShrinkImmediate(ShiftedVal))
4866 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4872 NeededMask &= ~Cst->getAPIntValue();
4874 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4879 if (FoundAnyExtend) {
4885 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4887 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4889 SDValue NewSHL = CurDAG->getNode(
ISD::SHL, dl, NVT, NewBinOp,
4896bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4897 SDNode *ParentB, SDNode *ParentC,
4898 SDValue
A, SDValue
B, SDValue
C,
4900 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4901 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4903 auto tryFoldLoadOrBCast =
4904 [
this](SDNode *Root, SDNode *
P, SDValue &
L, SDValue &
Base, SDValue &Scale,
4905 SDValue &
Index, SDValue &Disp, SDValue &Segment) {
4906 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4912 L =
L.getOperand(0);
4915 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
4920 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4924 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4927 bool FoldedLoad =
false;
4928 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4929 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4931 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4936 uint8_t OldImm =
Imm;
4937 Imm = OldImm & 0xa5;
4938 if (OldImm & 0x02)
Imm |= 0x10;
4939 if (OldImm & 0x10)
Imm |= 0x02;
4940 if (OldImm & 0x08)
Imm |= 0x40;
4941 if (OldImm & 0x40)
Imm |= 0x08;
4942 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4947 uint8_t OldImm =
Imm;
4948 Imm = OldImm & 0x99;
4949 if (OldImm & 0x02)
Imm |= 0x04;
4950 if (OldImm & 0x04)
Imm |= 0x02;
4951 if (OldImm & 0x20)
Imm |= 0x40;
4952 if (OldImm & 0x40)
Imm |= 0x20;
4957 SDValue TImm = CurDAG->getTargetConstant(
Imm,
DL, MVT::i8);
4961 MachineSDNode *MNode;
4963 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4966 if (
C.getOpcode() == X86ISD::VBROADCAST_LOAD) {
4968 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4969 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4971 bool UseD = EltSize == 32;
4973 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4975 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4977 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4983 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4985 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4987 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4992 SDValue
Ops[] = {
A,
B, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, TImm,
C.
getOperand(0)};
4993 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
4996 ReplaceUses(
C.getValue(1), SDValue(MNode, 1));
5003 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
5005 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
5007 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
5011 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
5014 ReplaceUses(SDValue(Root, 0), SDValue(MNode, 0));
5015 CurDAG->RemoveDeadNode(Root);
5021bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
5022 MVT NVT =
N->getSimpleValueType(0);
5025 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
5033 auto getFoldableLogicOp = [](SDValue
Op) {
5036 Op =
Op.getOperand(0);
5038 if (!
Op.hasOneUse())
5041 unsigned Opc =
Op.getOpcode();
5043 Opc == X86ISD::ANDNP)
5049 SDValue N0, N1,
A, FoldableOp;
5052 auto tryPeelOuterNotWrappingLogic = [&](SDNode *
Op) {
5055 SDValue InnerOp = getFoldableLogicOp(
Op->getOperand(0));
5062 if ((FoldableOp = getFoldableLogicOp(N1))) {
5066 if ((FoldableOp = getFoldableLogicOp(N0))) {
5074 bool PeeledOuterNot =
false;
5076 if (SDValue InnerOp = tryPeelOuterNotWrappingLogic(
N)) {
5077 PeeledOuterNot =
true;
5083 if ((FoldableOp = getFoldableLogicOp(N1)))
5085 else if ((FoldableOp = getFoldableLogicOp(N0)))
5093 SDNode *ParentA =
N;
5094 SDNode *ParentB = FoldableOp.
getNode();
5095 SDNode *ParentC = FoldableOp.
getNode();
5099 uint8_t TernlogMagicA = 0xf0;
5100 uint8_t TernlogMagicB = 0xcc;
5101 uint8_t TernlogMagicC = 0xaa;
5106 auto PeekThroughNot = [](SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
5110 Parent =
Op.getNode();
5111 Op =
Op.getOperand(0);
5115 PeekThroughNot(
A, ParentA, TernlogMagicA);
5116 PeekThroughNot(
B, ParentB, TernlogMagicB);
5117 PeekThroughNot(
C, ParentC, TernlogMagicC);
5122 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
5123 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
5124 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
5125 case X86ISD::ANDNP:
Imm = ~(TernlogMagicB) & TernlogMagicC;
break;
5128 switch (
N->getOpcode()) {
5132 Imm &= ~TernlogMagicA;
5134 Imm = ~(
Imm) & TernlogMagicA;
5144 return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC,
A,
B,
C,
Imm);
5154bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
5157 MVT VT =
And->getSimpleValueType(0);
5158 if (VT != MVT::i32 && VT != MVT::i64)
5170 APInt MaskVal = And1C->getAPIntValue();
5172 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
5176 if (VT == MVT::i64 && MaskLZ >= 32) {
5178 MaskVal = MaskVal.
trunc(32);
5181 SDValue And0 =
And->getOperand(0);
5183 APInt NegMaskVal = MaskVal | HighZeros;
5192 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
5193 NegMaskVal = NegMaskVal.
zext(64);
5194 HighZeros = HighZeros.
zext(64);
5200 KnownBits Known0 = CurDAG->computeKnownBits(And0);
5209 if (VT == MVT::i32 && !isDef32(And0.
getNode()))
5216 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
5218 SDValue NewAnd = CurDAG->getNode(
ISD::AND, SDLoc(
And), VT, And0, NewMask);
5225 bool FoldedBCast,
bool Masked) {
5226#define VPTESTM_CASE(VT, SUFFIX) \
5229 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
5230 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
5233#define VPTESTM_BROADCAST_CASES(SUFFIX) \
5234default: llvm_unreachable("Unexpected VT!"); \
5235VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
5236VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
5237VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
5238VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
5239VPTESTM_CASE(v16i32, DZ##SUFFIX) \
5240VPTESTM_CASE(v8i64, QZ##SUFFIX)
5242#define VPTESTM_FULL_CASES(SUFFIX) \
5243VPTESTM_BROADCAST_CASES(SUFFIX) \
5244VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
5245VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
5246VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
5247VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
5248VPTESTM_CASE(v64i8, BZ##SUFFIX) \
5249VPTESTM_CASE(v32i16, WZ##SUFFIX)
5267#undef VPTESTM_FULL_CASES
5268#undef VPTESTM_BROADCAST_CASES
5278 if (
Reg.isVirtual())
5283 if (GetPhysReg(N1) == LoReg && GetPhysReg(N0) != LoReg)
5289bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root, SDValue Setcc,
5291 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
5311 SDValue N0 = SetccOp0;
5322 SDValue N0Temp = N0;
5336 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P, SDValue &
L,
5337 SDValue &
Base, SDValue &Scale, SDValue &
Index,
5338 SDValue &Disp, SDValue &Segment) {
5341 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
5346 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
5352 L =
L.getOperand(0);
5355 if (
L.getOpcode() != X86ISD::VBROADCAST_LOAD)
5359 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5362 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5368 bool FoldedLoad =
false;
5369 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5371 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5375 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5382 bool FoldedBCast = FoldedLoad &&
Src1.getOpcode() == X86ISD::VBROADCAST_LOAD;
5384 bool IsMasked = InMask.
getNode() !=
nullptr;
5393 unsigned SubReg = CmpVT.
is128BitVector() ? X86::sub_xmm : X86::sub_ymm;
5397 SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5399 Src0 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src0);
5402 Src1 = CurDAG->getTargetInsertSubreg(SubReg, dl, CmpVT, ImplDef, Src1);
5407 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5408 InMask = SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5409 dl, MaskVT, InMask, RC), 0);
5417 MachineSDNode *CNode;
5419 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5422 SDValue
Ops[] = { InMask,
Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5423 Src1.getOperand(0) };
5424 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5426 SDValue
Ops[] = {
Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5427 Src1.getOperand(0) };
5428 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5432 ReplaceUses(
Src1.getValue(1), SDValue(CNode, 1));
5434 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5437 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5439 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5445 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5446 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5447 dl, ResVT, SDValue(CNode, 0), RC);
5450 ReplaceUses(SDValue(Root, 0), SDValue(CNode, 0));
5451 CurDAG->RemoveDeadNode(Root);
5457bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5460 MVT NVT =
N->getSimpleValueType(0);
5463 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5497 SDValue
Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5498 SDValue Ternlog = CurDAG->getNode(X86ISD::VPTERNLOG, dl, NVT,
A,
B,
C,
Imm);
5505void X86DAGToDAGISel::Select(SDNode *Node) {
5506 MVT NVT =
Node->getSimpleValueType(0);
5507 unsigned Opcode =
Node->getOpcode();
5510 if (
Node->isMachineOpcode()) {
5512 Node->setNodeId(-1);
5519 unsigned IntNo =
Node->getConstantOperandVal(1);
5522 case Intrinsic::x86_encodekey128:
5523 case Intrinsic::x86_encodekey256: {
5524 if (!Subtarget->hasKL())
5530 case Intrinsic::x86_encodekey128:
5531 Opcode = X86::ENCODEKEY128;
5533 case Intrinsic::x86_encodekey256:
5534 Opcode = X86::ENCODEKEY256;
5538 SDValue Chain =
Node->getOperand(0);
5539 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5541 if (Opcode == X86::ENCODEKEY256)
5542 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5545 MachineSDNode *Res = CurDAG->getMachineNode(
5546 Opcode, dl,
Node->getVTList(),
5547 {Node->getOperand(2), Chain, Chain.getValue(1)});
5548 ReplaceNode(Node, Res);
5551 case Intrinsic::x86_tileloaddrs64_internal:
5552 case Intrinsic::x86_tileloaddrst164_internal:
5553 if (!Subtarget->hasAMXMOVRS())
5556 case Intrinsic::x86_tileloadd64_internal:
5557 case Intrinsic::x86_tileloaddt164_internal: {
5558 if (!Subtarget->hasAMXTILE())
5561 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5562 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5567 case Intrinsic::x86_tileloaddrs64_internal:
5568 Opc = X86::PTILELOADDRSV;
5570 case Intrinsic::x86_tileloaddrst164_internal:
5571 Opc = X86::PTILELOADDRST1V;
5573 case Intrinsic::x86_tileloadd64_internal:
5574 Opc = X86::PTILELOADDV;
5576 case Intrinsic::x86_tileloaddt164_internal:
5577 Opc = X86::PTILELOADDT1V;
5581 SDValue
Base =
Node->getOperand(4);
5582 SDValue Scale = getI8Imm(1, dl);
5584 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5585 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5586 SDValue Chain =
Node->getOperand(0);
5587 MachineSDNode *CNode;
5588 SDValue
Ops[] = {
Node->getOperand(2),
5589 Node->getOperand(3),
5596 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5597 ReplaceNode(Node, CNode);
5604 unsigned IntNo =
Node->getConstantOperandVal(1);
5607 case Intrinsic::x86_sse3_monitor:
5608 case Intrinsic::x86_monitorx:
5609 case Intrinsic::x86_clzero: {
5610 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5615 case Intrinsic::x86_sse3_monitor:
5616 if (!Subtarget->hasSSE3())
5618 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5620 case Intrinsic::x86_monitorx:
5621 if (!Subtarget->hasMWAITX())
5623 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5625 case Intrinsic::x86_clzero:
5626 if (!Subtarget->hasCLZERO())
5628 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5633 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5634 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5635 Node->getOperand(2), SDValue());
5636 SDValue InGlue = Chain.
getValue(1);
5638 if (IntNo == Intrinsic::x86_sse3_monitor ||
5639 IntNo == Intrinsic::x86_monitorx) {
5641 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5644 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5649 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5651 ReplaceNode(Node, CNode);
5657 case Intrinsic::x86_tilestored64_internal: {
5659 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5660 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5661 unsigned Opc = X86::PTILESTOREDV;
5663 SDValue
Base =
Node->getOperand(4);
5664 SDValue Scale = getI8Imm(1, dl);
5666 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5667 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5668 SDValue Chain =
Node->getOperand(0);
5669 MachineSDNode *CNode;
5670 SDValue
Ops[] = {
Node->getOperand(2),
5671 Node->getOperand(3),
5677 Node->getOperand(6),
5679 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5680 ReplaceNode(Node, CNode);
5683 case Intrinsic::x86_tileloaddrs64:
5684 case Intrinsic::x86_tileloaddrst164:
5685 if (!Subtarget->hasAMXMOVRS())
5688 case Intrinsic::x86_tileloadd64:
5689 case Intrinsic::x86_tileloaddt164:
5690 case Intrinsic::x86_tilestored64: {
5691 if (!Subtarget->hasAMXTILE())
5694 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5695 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5699 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5700 case Intrinsic::x86_tileloaddrs64:
5701 Opc = X86::PTILELOADDRS;
5703 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5704 case Intrinsic::x86_tileloaddrst164:
5705 Opc = X86::PTILELOADDRST1;
5707 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5710 unsigned TIndex =
Node->getConstantOperandVal(2);
5711 SDValue
TReg = getI8Imm(TIndex, dl);
5712 SDValue
Base =
Node->getOperand(3);
5713 SDValue Scale = getI8Imm(1, dl);
5715 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5716 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5717 SDValue Chain =
Node->getOperand(0);
5718 MachineSDNode *CNode;
5719 if (
Opc == X86::PTILESTORED) {
5721 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5724 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5726 ReplaceNode(Node, CNode);
5733 case X86ISD::NT_BRIND: {
5734 if (Subtarget->isTarget64BitILP32()) {
5739 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5740 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5743 unsigned Opc = Opcode == X86ISD::NT_BRIND ? X86::JMP64r_NT : X86::JMP64r;
5744 SDNode *Res = CurDAG->getMachineNode(
Opc, dl, MVT::Other, ZextTarget,
5745 Node->getOperand(0));
5746 ReplaceNode(Node, Res);
5752 ReplaceNode(Node, getGlobalBaseReg());
5759 ReplaceUses(SDValue(Node, 0),
Node->getOperand(0));
5760 CurDAG->RemoveDeadNode(Node);
5766 if (matchBitExtract(Node))
5771 if (tryShiftAmountMod(Node))
5775 case X86ISD::VPTERNLOG: {
5776 uint8_t
Imm =
Node->getConstantOperandVal(3);
5777 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5784 if (tryVPTERNLOG(Node))
5791 SDValue N0 =
Node->getOperand(0);
5792 SDValue N1 =
Node->getOperand(1);
5794 tryVPTESTM(Node, N0, N1))
5797 tryVPTESTM(Node, N1, N0))
5801 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5802 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
5803 CurDAG->RemoveDeadNode(Node);
5806 if (matchBitExtract(Node))
5808 if (Subtarget->getCLOpts().and_imm_shrink && shrinkAndImmediate(Node))
5815 if (Opcode ==
ISD::XOR && Subtarget->hasBMI2() && matchBitExtract(Node))
5819 if (tryShrinkShlLogicImm(Node))
5821 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5823 if (tryVPTERNLOG(Node))
5828 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5838 if (!CurDAG->shouldOptForSize())
5842 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5845 SDValue N0 =
Node->getOperand(0);
5846 SDValue N1 =
Node->getOperand(1);
5852 int64_t Val = Cst->getSExtValue();
5860 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5864 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5868 unsigned ROpc, MOpc;
5977 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5978 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5979 SDValue
Ops[] = { N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N0.
getOperand(0) };
5980 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5981 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5983 ReplaceUses(N0.
getValue(1), SDValue(CNode, 2));
5986 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
5987 CurDAG->RemoveDeadNode(Node);
5992 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
6001 case X86ISD::UMUL: {
6002 SDValue N0 =
Node->getOperand(0);
6003 SDValue N1 =
Node->getOperand(1);
6005 unsigned LoReg, ROpc, MOpc;
6010 ROpc = Opcode == X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
6011 MOpc = Opcode == X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
6030 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6031 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6034 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6042 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
6044 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
6045 N0, SDValue()).getValue(1);
6047 MachineSDNode *CNode;
6053 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
6055 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
6057 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.
getOperand(0),
6059 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6062 ReplaceUses(N1.
getValue(1), SDValue(CNode, NVT == MVT::i8 ? 2 : 3));
6070 VTs = CurDAG->getVTList(NVT, MVT::i32);
6072 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
6074 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
6077 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6078 ReplaceUses(SDValue(Node, 1), SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
6079 CurDAG->RemoveDeadNode(Node);
6085 SDValue N0 =
Node->getOperand(0);
6086 SDValue N1 =
Node->getOperand(1);
6089 unsigned LoReg, HiReg;
6091 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
6092 bool UseMULXHi = UseMULX && SDValue(Node, 0).use_empty();
6096 Opc = UseMULXHi ? X86::MULX32Hrr
6098 : IsSigned ?
X86::IMUL32r
6100 MOpc = UseMULXHi ? X86::MULX32Hrm
6102 : IsSigned ?
X86::IMUL32m
6104 LoReg = UseMULX ? X86::EDX : X86::EAX;
6108 Opc = UseMULXHi ? X86::MULX64Hrr
6110 : IsSigned ?
X86::IMUL64r
6112 MOpc = UseMULXHi ? X86::MULX64Hrm
6114 : IsSigned ?
X86::IMUL64m
6116 LoReg = UseMULX ? X86::RDX : X86::RAX;
6121 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6122 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6125 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6133 orderRegForMul(N0, N1, LoReg, CurDAG->getMachineFunction().getRegInfo());
6135 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
6136 N0, SDValue()).getValue(1);
6137 SDValue ResHi, ResLo;
6140 MachineSDNode *CNode =
nullptr;
6141 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.
getOperand(0),
6144 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
6145 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6146 ResHi = SDValue(CNode, 0);
6147 Chain = SDValue(CNode, 1);
6148 }
else if (UseMULX) {
6149 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
6150 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6151 ResHi = SDValue(CNode, 0);
6152 ResLo = SDValue(CNode, 1);
6153 Chain = SDValue(CNode, 2);
6155 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6156 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
6157 Chain = SDValue(CNode, 0);
6158 InGlue = SDValue(CNode, 1);
6162 ReplaceUses(N1.
getValue(1), Chain);
6166 SDValue
Ops[] = { N1, InGlue };
6168 SDVTList VTs = CurDAG->getVTList(NVT);
6169 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
6170 ResHi = SDValue(CNode, 0);
6171 }
else if (UseMULX) {
6172 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
6173 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
6174 ResHi = SDValue(CNode, 0);
6175 ResLo = SDValue(CNode, 1);
6177 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
6178 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
6179 InGlue = SDValue(CNode, 0);
6184 if (!SDValue(Node, 0).use_empty()) {
6186 assert(LoReg &&
"Register for low half is not defined!");
6187 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
6191 ReplaceUses(SDValue(Node, 0), ResLo);
6196 if (!SDValue(Node, 1).use_empty()) {
6198 assert(HiReg &&
"Register for high half is not defined!");
6199 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
6203 ReplaceUses(SDValue(Node, 1), ResHi);
6208 CurDAG->RemoveDeadNode(Node);
6214 SDValue N0 =
Node->getOperand(0);
6215 SDValue N1 =
Node->getOperand(1);
6217 unsigned ROpc, MOpc;
6222 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
6223 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
6224 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
6225 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
6230 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
6231 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
6232 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
6233 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
6237 unsigned LoReg, HiReg, ClrReg;
6238 unsigned SExtOpcode;
6242 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
6246 LoReg = X86::AX; HiReg = X86::DX;
6248 SExtOpcode = X86::CWD;
6251 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
6252 SExtOpcode = X86::CDQ;
6255 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
6256 SExtOpcode = X86::CQO;
6260 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6261 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
6262 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
6265 if (NVT == MVT::i8) {
6268 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
6269 MachineSDNode *Move;
6270 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6271 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N0.
getOperand(0) };
6272 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rm8
6274 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
6275 Chain = SDValue(Move, 1);
6276 ReplaceUses(N0.
getValue(1), Chain);
6280 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rr8
6282 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
6283 Chain = CurDAG->getEntryNode();
6285 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX, SDValue(Move, 0),
6290 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
6291 LoReg, N0, SDValue()).getValue(1);
6295 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
6298 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
6300 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
6304 SDValue(CurDAG->getMachineNode(
6305 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
6306 CurDAG->getTargetConstant(X86::sub_16bit, dl,
6314 CurDAG->getMachineNode(
6315 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, ClrNode,
6316 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
6323 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
6324 ClrNode, InGlue).getValue(1);
6329 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N1.
getOperand(0),
6331 MachineSDNode *CNode =
6332 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
6333 InGlue = SDValue(CNode, 1);
6335 ReplaceUses(N1.
getValue(1), SDValue(CNode, 0));
6340 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
6350 if (HiReg == X86::AH && !SDValue(Node, 1).use_empty()) {
6351 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
6352 unsigned AHExtOpcode =
6353 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6355 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6356 MVT::Glue, AHCopy, InGlue);
6357 SDValue
Result(RNode, 0);
6358 InGlue = SDValue(RNode, 1);
6361 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6363 ReplaceUses(SDValue(Node, 1), Result);
6368 if (!SDValue(Node, 0).use_empty()) {
6369 SDValue
Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6370 LoReg, NVT, InGlue);
6371 InGlue =
Result.getValue(2);
6372 ReplaceUses(SDValue(Node, 0), Result);
6377 if (!SDValue(Node, 1).use_empty()) {
6378 SDValue
Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6379 HiReg, NVT, InGlue);
6380 InGlue =
Result.getValue(2);
6381 ReplaceUses(SDValue(Node, 1), Result);
6385 CurDAG->RemoveDeadNode(Node);
6390 case X86ISD::STRICT_FCMP:
6391 case X86ISD::STRICT_FCMPS: {
6392 bool IsStrictCmp =
Node->getOpcode() == X86ISD::STRICT_FCMP ||
6393 Node->getOpcode() == X86ISD::STRICT_FCMPS;
6394 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6395 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6401 if (Subtarget->canUseCMOV())
6404 bool IsSignaling =
Node->getOpcode() == X86ISD::STRICT_FCMPS;
6410 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6413 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6416 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6421 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6424 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6425 Chain = SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6428 Glue = SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6433 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6437 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6441 assert(Subtarget->canUseLAHFSAHF() &&
6442 "Target doesn't support SAHF or FCOMI?");
6443 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract, SDValue());
6445 SDValue SAHF = SDValue(
6446 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6449 ReplaceUses(SDValue(Node, 1), Chain);
6451 ReplaceUses(SDValue(Node, 0), SAHF);
6452 CurDAG->RemoveDeadNode(Node);
6457 SDValue N0 =
Node->getOperand(0);
6458 SDValue N1 =
Node->getOperand(1);
6472 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6473 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6475 SDValue BEXTR = SDValue(NewNode, 0);
6476 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6477 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
6478 CurDAG->RemoveDeadNode(Node);
6505 onlyUsesZeroFlag(SDValue(Node, 0))) {
6510 unsigned TestOpcode;
6518 if (LeadingZeros == 0 && SavesBytes) {
6523 ShiftAmt = TrailingZeros;
6525 TestOpcode = X86::TEST64rr;
6526 }
else if (TrailingZeros == 0 && SavesBytes) {
6532 if (LeadingZeros == 1) {
6536 MachineSDNode *
Add = CurDAG->getMachineNode(
6539 MachineSDNode *
Test = CurDAG->getMachineNode(
6540 X86::TEST64rr, dl, MVT::i32, SDValue(
Add, 0), SDValue(
Add, 0));
6541 ReplaceNode(Node,
Test);
6545 ShiftAmt = LeadingZeros;
6547 TestOpcode = X86::TEST64rr;
6548 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6551 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6552 if (PopCount == 8) {
6554 ShiftAmt = TrailingZeros;
6555 SubRegIdx = X86::sub_8bit;
6557 TestOpcode = X86::TEST8rr;
6558 }
else if (PopCount == 16) {
6560 ShiftAmt = TrailingZeros;
6561 SubRegIdx = X86::sub_16bit;
6562 SubRegVT = MVT::i16;
6563 TestOpcode = X86::TEST16rr;
6564 }
else if (PopCount == 32) {
6566 ShiftAmt = TrailingZeros;
6567 SubRegIdx = X86::sub_32bit;
6568 SubRegVT = MVT::i32;
6569 TestOpcode = X86::TEST32rr;
6573 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6574 SDValue Shift = SDValue(
6575 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6578 if (SubRegIdx != 0) {
6580 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6582 MachineSDNode *
Test =
6583 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6584 ReplaceNode(Node,
Test);
6591 unsigned ROpc, MOpc;
6599 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6600 hasNoSignFlagUses(SDValue(Node, 0)))) {
6603 SubRegOp = X86::sub_8bit;
6604 ROpc = X86::TEST8ri;
6605 MOpc = X86::TEST8mi;
6606 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6607 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6608 hasNoSignFlagUses(SDValue(Node, 0)))) {
6614 SubRegOp = X86::sub_16bit;
6615 ROpc = X86::TEST16ri;
6616 MOpc = X86::TEST16mi;
6618 ((!(Mask & 0x80000000) &&
6621 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6622 CmpVT == MVT::i32 ||
6623 hasNoSignFlagUses(SDValue(Node, 0)))) {
6630 SubRegOp = X86::sub_32bit;
6631 ROpc = X86::TEST32ri;
6632 MOpc = X86::TEST32mi;
6638 SDValue
Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6642 MachineSDNode *NewNode;
6643 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6644 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6646 if (!LoadN->isSimple()) {
6647 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6648 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6649 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6650 (MOpc == X86::TEST32mi && NumVolBits != 32))
6654 SDValue
Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
6655 Reg.getOperand(0) };
6656 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6658 ReplaceUses(
Reg.getValue(1), SDValue(NewNode, 1));
6660 CurDAG->setNodeMemRefs(NewNode,
6665 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6667 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg,
Imm);
6670 ReplaceNode(Node, NewNode);
6676 if (!Subtarget->hasSSE42())
6679 bool NeedIndex = !SDValue(Node, 0).use_empty();
6680 bool NeedMask = !SDValue(Node, 1).use_empty();
6682 bool MayFoldLoad = !NeedIndex || !
NeedMask;
6684 MachineSDNode *CNode;
6687 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6689 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6690 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6691 ReplaceUses(SDValue(Node, 1), SDValue(CNode, 0));
6693 if (NeedIndex || !NeedMask) {
6695 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6697 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6698 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6699 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6703 ReplaceUses(SDValue(Node, 2), SDValue(CNode, 1));
6704 CurDAG->RemoveDeadNode(Node);
6708 if (!Subtarget->hasSSE42())
6712 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6713 Node->getOperand(1),
6714 SDValue()).getValue(1);
6715 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6716 Node->getOperand(3), InGlue).getValue(1);
6718 bool NeedIndex = !SDValue(Node, 0).use_empty();
6719 bool NeedMask = !SDValue(Node, 1).use_empty();
6721 bool MayFoldLoad = !NeedIndex || !
NeedMask;
6723 MachineSDNode *CNode;
6726 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6728 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6730 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6731 ReplaceUses(SDValue(Node, 1), SDValue(CNode, 0));
6733 if (NeedIndex || !NeedMask) {
6735 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6737 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6738 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6739 ReplaceUses(SDValue(Node, 0), SDValue(CNode, 0));
6742 ReplaceUses(SDValue(Node, 2), SDValue(CNode, 1));
6743 CurDAG->RemoveDeadNode(Node);
6748 if (NVT.
isVector() && tryVPTESTM(Node, SDValue(Node, 0), SDValue()))
6755 if (foldLoadStoreIntoMemOperand(Node))
6759 case X86ISD::SETCC_CARRY: {
6760 MVT VT =
Node->getSimpleValueType(0);
6762 if (Subtarget->hasSBBDepBreaking()) {
6767 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6768 Node->getOperand(1), SDValue());
6772 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6773 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6775 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6780 Result = getSBBZero(Node);
6784 if (VT == MVT::i8 || VT == MVT::i16) {
6785 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6786 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6789 ReplaceUses(SDValue(Node, 0), Result);
6790 CurDAG->RemoveDeadNode(Node);
6796 SDValue
Result = getSBBZero(Node);
6799 ReplaceUses(SDValue(Node, 1),
Result.getValue(1));
6802 if (!SDValue(Node, 0).use_empty()) {
6804 MVT VT =
Node->getSimpleValueType(0);
6805 if (VT == MVT::i8 || VT == MVT::i16) {
6806 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6807 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6809 ReplaceUses(SDValue(Node, 0), Result);
6812 CurDAG->RemoveDeadNode(Node);
6819 SDValue IndexOp = Mgt->getIndex();
6820 SDValue
Mask = Mgt->getMask();
6822 MVT ValueVT =
Node->getSimpleValueType(0);
6823 MVT MaskVT =
Mask.getSimpleValueType();
6840 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6841 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6842 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6843 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6844 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6845 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6846 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6847 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6848 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6849 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6850 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6851 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6852 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6853 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6854 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6855 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6856 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6857 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6858 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6859 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6860 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6861 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6862 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6863 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6865 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6866 "Unexpected mask VT!");
6867 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6868 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6869 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6870 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6871 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6872 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6873 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6874 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6875 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6876 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6877 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6878 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6879 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6880 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6881 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6882 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6888 SDValue
Base, Scale,
Index, Disp, Segment;
6889 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6890 Base, Scale, Index, Disp, Segment))
6893 SDValue PassThru = Mgt->getPassThru();
6894 SDValue Chain = Mgt->getChain();
6896 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6898 MachineSDNode *NewNode;
6901 Index, Disp, Segment, Chain};
6902 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6905 Disp, Segment,
Mask, Chain};
6906 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6908 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6909 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 0));
6910 ReplaceUses(SDValue(Node, 1), SDValue(NewNode, 2));
6911 CurDAG->RemoveDeadNode(Node);
6916 SDValue
Value = Sc->getValue();
6917 SDValue IndexOp = Sc->getIndex();
6919 MVT ValueVT =
Value.getSimpleValueType();
6934 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6935 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6936 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6937 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6938 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6939 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6940 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6941 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6942 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6943 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6944 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6945 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6946 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6947 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6948 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6949 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6950 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6951 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6952 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6953 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6954 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6955 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6956 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6957 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6961 SDValue
Base, Scale,
Index, Disp, Segment;
6962 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6963 Base, Scale, Index, Disp, Segment))
6966 SDValue
Mask = Sc->getMask();
6967 SDValue Chain = Sc->getChain();
6969 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6972 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6973 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6974 ReplaceUses(SDValue(Node, 0), SDValue(NewNode, 1));
6975 CurDAG->RemoveDeadNode(Node);
6979 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6980 auto CallId = MFI->getPreallocatedIdForCallSite(
6982 SDValue Chain =
Node->getOperand(0);
6983 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6984 MachineSDNode *
New = CurDAG->getMachineNode(
6985 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6986 ReplaceUses(SDValue(Node, 0), SDValue(New, 0));
6987 CurDAG->RemoveDeadNode(Node);
6991 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6994 SDValue Chain =
Node->getOperand(0);
6995 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6996 SDValue ArgIndex =
Node->getOperand(2);
6998 Ops[0] = CallIdValue;
7001 MachineSDNode *
New = CurDAG->getMachineNode(
7002 TargetOpcode::PREALLOCATED_ARG, dl,
7003 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
7006 ReplaceUses(SDValue(Node, 0), SDValue(New, 0));
7007 ReplaceUses(SDValue(Node, 1), SDValue(New, 1));
7008 CurDAG->RemoveDeadNode(Node);
7015 if (!Subtarget->hasWIDEKL())
7019 switch (
Node->getOpcode()) {
7023 Opcode = X86::AESENCWIDE128KL;
7026 Opcode = X86::AESDECWIDE128KL;
7029 Opcode = X86::AESENCWIDE256KL;
7032 Opcode = X86::AESDECWIDE256KL;
7036 SDValue Chain =
Node->getOperand(0);
7037 SDValue Addr =
Node->getOperand(1);
7039 SDValue
Base, Scale,
Index, Disp, Segment;
7040 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
7043 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
7045 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
7047 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
7049 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
7051 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
7053 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
7055 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
7057 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
7060 MachineSDNode *Res = CurDAG->getMachineNode(
7061 Opcode, dl,
Node->getVTList(),
7062 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
7064 ReplaceNode(Node, Res);
7068 SDValue Chain =
Node->getOperand(0);
7071 if (
Node->getNumValues() == 3)
7072 Glue =
Node->getOperand(2);
7074 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
7075 ReplaceNode(Node,
Copy.getNode());
7083bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
7085 std::vector<SDValue> &OutOps) {
7086 SDValue Op0, Op1, Op2, Op3, Op4;
7087 switch (ConstraintID) {
7090 case InlineAsm::ConstraintCode::o:
7091 case InlineAsm::ConstraintCode::v:
7092 case InlineAsm::ConstraintCode::m:
7093 case InlineAsm::ConstraintCode::X:
7094 case InlineAsm::ConstraintCode::p:
7095 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
7100 OutOps.push_back(Op0);
7101 OutOps.push_back(Op1);
7102 OutOps.push_back(Op2);
7103 OutOps.push_back(Op3);
7104 OutOps.push_back(Op4);
7110 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
7116 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 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 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)
#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...
@ 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