22#include "llvm/Config/llvm-config.h"
27#include "llvm/IR/IntrinsicsX86.h"
38#define DEBUG_TYPE "x86-isel"
39#define PASS_NAME "X86 DAG->DAG Instruction Selection"
41STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
44 cl::desc(
"Enable setting constant bits to reduce size of mask immediates"),
48 "x86-promote-anyext-load",
cl::init(
true),
60 struct X86ISelAddressMode {
68 int Base_FrameIndex = 0;
74 const GlobalValue *GV =
nullptr;
77 const char *ES =
nullptr;
82 bool NegateIndex =
false;
84 X86ISelAddressMode() =
default;
86 bool hasSymbolicDisplacement()
const {
87 return GV !=
nullptr || CP !=
nullptr || ES !=
nullptr ||
88 MCSym !=
nullptr || JT != -1 || BlockAddr !=
nullptr;
91 bool hasBaseOrIndexReg()
const {
92 return BaseType == FrameIndexBase ||
93 IndexReg.getNode() !=
nullptr || Base_Reg.getNode() !=
nullptr;
98 if (BaseType != RegBase)
return false;
99 if (RegisterSDNode *RegNode =
101 return RegNode->getReg() == X86::RIP;
110#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
111 void dump(SelectionDAG *DAG =
nullptr) {
112 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
113 dbgs() <<
"Base_Reg ";
114 if (Base_Reg.getNode())
115 Base_Reg.getNode()->dump(DAG);
118 if (BaseType == FrameIndexBase)
119 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
120 dbgs() <<
" Scale " << Scale <<
'\n'
124 if (IndexReg.getNode())
125 IndexReg.getNode()->dump(DAG);
128 dbgs() <<
" Disp " << Disp <<
'\n'
150 dbgs() <<
" JT" << JT <<
" Align" << Alignment.value() <<
'\n';
164 const X86Subtarget *Subtarget;
170 bool IndirectTlsSegRefs;
173 X86DAGToDAGISel() =
delete;
175 explicit X86DAGToDAGISel(X86TargetMachine &tm,
CodeGenOptLevel OptLevel)
176 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr),
177 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
179 bool runOnMachineFunction(MachineFunction &MF)
override {
183 "indirect-tls-seg-refs");
190 void emitFunctionEntryCode()
override;
192 bool IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const override;
194 void PreprocessISelDAG()
override;
195 void PostprocessISelDAG()
override;
198#include "X86GenDAGISel.inc"
201 void Select(SDNode *
N)
override;
203 bool foldOffsetIntoAddress(uint64_t
Offset, X86ISelAddressMode &AM);
204 bool matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
205 bool AllowSegmentRegForX32 =
false);
206 bool matchWrapper(
SDValue N, X86ISelAddressMode &AM);
207 bool matchAddress(
SDValue N, X86ISelAddressMode &AM);
208 bool matchVectorAddress(
SDValue N, X86ISelAddressMode &AM);
209 bool matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
212 bool matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
214 bool matchVectorAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
216 bool matchAddressBase(
SDValue N, X86ISelAddressMode &AM);
220 bool selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
SDValue IndexOp,
234 bool tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
244 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
247 bool tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
252 bool isProfitableToFormMaskedOp(SDNode *
N)
const;
255 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
257 std::vector<SDValue> &OutOps)
override;
259 void emitSpecialCodeForMain();
261 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
265 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
266 Base = CurDAG->getTargetFrameIndex(
267 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
268 else if (AM.Base_Reg.
getNode())
271 Base = CurDAG->getRegister(0, VT);
273 Scale = getI8Imm(AM.Scale,
DL);
275#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
277 if (AM.NegateIndex) {
303 Index = CurDAG->getRegister(0, VT);
308 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(),
312 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
313 AM.Disp, AM.SymbolFlags);
315 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
316 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
317 }
else if (AM.MCSym) {
318 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
319 assert(AM.SymbolFlags == 0 &&
"oo");
320 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
321 }
else if (AM.JT != -1) {
322 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
323 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
324 }
else if (AM.BlockAddr)
325 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
328 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
331 Segment = AM.Segment;
333 Segment = CurDAG->getRegister(0, MVT::i16);
338 bool isAMXSDNode(SDNode *
N)
const {
344 switch (
N->getOpcode()) {
347 case X86::PT2RPNTLVWZ0V:
348 case X86::PT2RPNTLVWZ0T1V:
349 case X86::PT2RPNTLVWZ1V:
350 case X86::PT2RPNTLVWZ1T1V:
351 case X86::PT2RPNTLVWZ0RSV:
352 case X86::PT2RPNTLVWZ0RST1V:
353 case X86::PT2RPNTLVWZ1RSV:
354 case X86::PT2RPNTLVWZ1RST1V:
357 for (
unsigned Idx = 0,
E =
N->getNumValues(); Idx !=
E; ++Idx) {
358 if (
N->getValueType(Idx) == MVT::x86amx)
361 for (
unsigned Idx = 0,
E =
N->getNumOperands(); Idx !=
E; ++Idx) {
363 if (
Op.getValueType() == MVT::x86amx)
375 bool shouldAvoidImmediateInstFormsForSize(SDNode *
N)
const {
376 uint32_t UseCount = 0;
381 if (!CurDAG->shouldOptForSize())
385 for (
const SDNode *User :
N->users()) {
391 if (
User->isMachineOpcode()) {
397 if (
User->getOpcode() == ISD::STORE &&
398 User->getOperand(1).getNode() ==
N) {
409 if (
User->getNumOperands() != 2)
430 OtherOp =
User->getOperand(1);
433 RegisterSDNode *RegNode;
437 if ((RegNode->
getReg() == X86::ESP) ||
438 (RegNode->
getReg() == X86::RSP))
447 return (UseCount > 1);
451 inline SDValue getI8Imm(
unsigned Imm,
const SDLoc &
DL) {
452 return CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
456 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &
DL) {
457 return CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
461 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &
DL) {
462 return CurDAG->getTargetConstant(Imm,
DL, MVT::i64);
465 SDValue getExtractVEXTRACTImmediate(SDNode *
N,
unsigned VecWidth,
467 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
468 uint64_t
Index =
N->getConstantOperandVal(1);
469 MVT VecVT =
N->getOperand(0).getSimpleValueType();
473 SDValue getInsertVINSERTImmediate(SDNode *
N,
unsigned VecWidth,
475 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
476 uint64_t
Index =
N->getConstantOperandVal(2);
477 MVT VecVT =
N->getSimpleValueType(0);
481 SDValue getPermuteVINSERTCommutedImmediate(SDNode *
N,
unsigned VecWidth,
483 assert(VecWidth == 128 &&
"Unexpected vector width");
484 uint64_t
Index =
N->getConstantOperandVal(2);
485 MVT VecVT =
N->getSimpleValueType(0);
487 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
490 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
495 MVT VT =
N->getSimpleValueType(0);
498 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
500 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
501 if (VT == MVT::i64) {
503 CurDAG->getMachineNode(
504 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
505 CurDAG->getTargetConstant(0, dl, MVT::i64), Zero,
506 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
511 unsigned Opcode =
N->getOpcode();
513 "Unexpected opcode for SBB materialization");
514 unsigned FlagOpIndex = Opcode ==
X86ISD::SBB ? 2 : 1;
516 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
517 N->getOperand(FlagOpIndex),
SDValue());
521 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
522 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
523 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
525 CurDAG->getMachineNode(
Opc, dl, VTs,
526 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
532 bool isUnneededShiftMask(SDNode *
N,
unsigned Width)
const {
534 const APInt &Val =
N->getConstantOperandAPInt(1);
539 APInt
Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
540 return Mask.countr_one() >= Width;
546 SDNode *getGlobalBaseReg();
550 const X86TargetMachine &getTargetMachine()
const {
551 return static_cast<const X86TargetMachine &
>(
TM);
556 const X86InstrInfo *getInstrInfo()
const {
557 return Subtarget->getInstrInfo();
566 bool ComplexPatternFuncMutatesDAG()
const override {
570 bool isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const;
573 bool useNonTemporalLoad(LoadSDNode *
N)
const {
574 if (!
N->isNonTemporal())
577 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
579 if (
N->getAlign().value() < StoreSize)
588 return Subtarget->hasSSE41();
590 return Subtarget->hasAVX2();
592 return Subtarget->hasAVX512();
596 bool foldLoadStoreIntoMemOperand(SDNode *Node);
597 MachineSDNode *matchBEXTRFromAndImm(SDNode *Node);
598 bool matchBitExtract(SDNode *Node);
599 bool shrinkAndImmediate(SDNode *
N);
600 bool isMaskZeroExtended(SDNode *
N)
const;
601 bool tryShiftAmountMod(SDNode *
N);
602 bool tryShrinkShlLogicImm(SDNode *
N);
603 bool tryVPTERNLOG(SDNode *
N);
604 bool matchVPTERNLOG(SDNode *Root, SDNode *ParentA, SDNode *ParentB,
608 bool tryMatchBitSelect(SDNode *
N);
610 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
611 const SDLoc &dl, MVT VT, SDNode *Node);
612 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
613 const SDLoc &dl, MVT VT, SDNode *Node,
616 bool tryOptimizeRem8Extend(SDNode *
N);
618 bool onlyUsesZeroFlag(
SDValue Flags)
const;
619 bool hasNoSignFlagUses(
SDValue Flags)
const;
620 bool hasNoCarryFlagUses(
SDValue Flags)
const;
626 explicit X86DAGToDAGISelLegacy(X86TargetMachine &tm,
628 : SelectionDAGISelLegacy(
629 ID, std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
633char X86DAGToDAGISelLegacy::ID = 0;
640 unsigned Opcode =
N->getOpcode();
647 EVT OpVT =
N->getOperand(0).getValueType();
651 OpVT =
N->getOperand(1).getValueType();
653 return Subtarget->hasVLX();
667bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
679X86DAGToDAGISel::IsProfitableToFold(
SDValue N, SDNode *U, SDNode *Root)
const {
680 if (OptLevel == CodeGenOptLevel::None)
686 if (
N.getOpcode() != ISD::LOAD)
695 switch (
U->getOpcode()) {
722 if (
Imm->getAPIntValue().isSignedIntN(8))
731 Imm->getAPIntValue().getBitWidth() == 64 &&
732 Imm->getAPIntValue().isIntN(32))
739 (
Imm->getAPIntValue() == UINT8_MAX ||
740 Imm->getAPIntValue() == UINT16_MAX ||
741 Imm->getAPIntValue() == UINT32_MAX))
747 (-
Imm->getAPIntValue()).isSignedIntN(8))
751 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
752 hasNoCarryFlagUses(
SDValue(U, 1)))
777 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
781 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
790 if (
C &&
C->getSExtValue() == -2)
796 if (
C &&
C->getSExtValue() == -2)
831bool X86DAGToDAGISel::isProfitableToFormMaskedOp(SDNode *
N)
const {
834 "Unexpected opcode!");
839 return N->getOperand(1).hasOneUse();
848 if (Chain.
getNode() == Load.getNode())
849 Ops.push_back(Load.getOperand(0));
852 "Unexpected chain operand");
855 Ops.push_back(Load.getOperand(0));
861 Ops.push_back(NewChain);
866 Load.getOperand(1), Load.getOperand(2));
884 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
894 while (HasCallSeq && Chain.
getOpcode() != ISD::CALLSEQ_START) {
911 Callee.getValue(1).hasOneUse())
919 if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
922 uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
923 0x65, 0x66, 0x67, 0xf0, 0xf2};
926 uint8_t Byte = (Imm >> i) & 0xFF;
938 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
941void X86DAGToDAGISel::PreprocessISelDAG() {
942 bool MadeChange =
false;
944 E = CurDAG->allnodes_end();
I !=
E; ) {
963 MVT VT =
N->getSimpleValueType(0);
965 int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
970 "cf-protection-branch");
973 SDValue Complement = CurDAG->getConstant(~Imm, dl, VT,
false,
true);
974 Complement = CurDAG->getNOT(dl, Complement, VT);
976 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Complement);
986 if (
N->getOpcode() ==
X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
988 N->getOperand(0),
N->getOperand(1));
990 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1014 auto mayPreventLoadFold = [&]() {
1016 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1017 !
N->getOperand(1).hasOneUse();
1020 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1026 MVT VT =
N->getSimpleValueType(0);
1034 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1036 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1043 switch (
N->getOpcode()) {
1045 MVT VT =
N->getSimpleValueType(0);
1047 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1054 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1057 CurDAG->getIntPtrConstant(Index, dl));
1060 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1069 MVT VT =
N->getSimpleValueType(0);
1071 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1075 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1076 SDValue Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1077 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1079 MemNode->getMemOperand());
1082 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1085 CurDAG->getIntPtrConstant(Index, dl));
1089 CurDAG->ReplaceAllUsesWith(
N, To);
1101 MVT VT =
N->getSimpleValueType(0);
1107 SDNode *MaxLd =
nullptr;
1109 SDValue Chain = Ld->getChain();
1110 for (SDNode *User :
Ptr->users()) {
1112 MVT UserVT =
User->getSimpleValueType(0);
1114 UserLd->getBasePtr() ==
Ptr && UserLd->getChain() == Chain &&
1115 !
User->hasAnyUseOfValue(1) &&
1129 CurDAG->getIntPtrConstant(0, dl));
1130 SDValue Res = CurDAG->getBitcast(VT, Extract);
1134 CurDAG->ReplaceAllUsesWith(
N, To);
1143 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1144 if (EleVT == MVT::i1)
1147 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1148 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1149 "We can't replace VSELECT with BLENDV in vXi16!");
1151 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1154 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1155 CurDAG->getTargetConstant(0xCA, SDLoc(
N), MVT::i8));
1158 N->getOperand(0),
N->getOperand(1),
1162 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1175 if (!
N->getSimpleValueType(0).isVector())
1179 switch (
N->getOpcode()) {
1189 if (
N->isStrictFPOpcode())
1191 CurDAG->getNode(NewOpc, SDLoc(
N), {
N->getValueType(0), MVT::Other},
1192 {
N->getOperand(0),
N->getOperand(1)});
1195 CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1198 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1208 if (!
N->getValueType(0).isVector())
1212 switch (
N->getOpcode()) {
1218 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1219 N->getOperand(0),
N->getOperand(1));
1221 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1230 if (!
N->getValueType(0).isVector())
1234 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1236 "Unexpected opcode for mask vector!");
1244 SDValue Res = CurDAG->getNode(NewOpc, SDLoc(
N),
N->getValueType(0),
1247 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1258 case ISD::FROUNDEVEN:
1260 case ISD::FNEARBYINT:
1267 switch (
N->getOpcode()) {
1270 case ISD::FCEIL:
Imm = 0xA;
break;
1272 case ISD::FFLOOR:
Imm = 0x9;
break;
1274 case ISD::FTRUNC:
Imm = 0xB;
break;
1276 case ISD::FROUNDEVEN:
Imm = 0x8;
break;
1278 case ISD::FNEARBYINT:
Imm = 0xC;
break;
1280 case ISD::FRINT:
Imm = 0x4;
break;
1283 bool IsStrict =
N->isStrictFPOpcode();
1287 {
N->getValueType(0), MVT::Other},
1288 {
N->getOperand(0),
N->getOperand(1),
1289 CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
1293 CurDAG->getTargetConstant(Imm, dl, MVT::i32));
1295 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1306 MVT VT =
N->getSimpleValueType(0);
1307 if (VT.
isVector() || VT == MVT::f128)
1310 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1311 : VT == MVT::f32 ? MVT::v4f32
1321 if (Subtarget->hasSSE2()) {
1322 EVT IntVT = EVT(VecVT).changeVectorElementTypeToInteger();
1323 Op0 = CurDAG->getNode(ISD::BITCAST, dl, IntVT, Op0);
1324 Op1 = CurDAG->getNode(ISD::BITCAST, dl, IntVT, Op1);
1326 switch (
N->getOpcode()) {
1333 Res = CurDAG->getNode(
Opc, dl, IntVT, Op0, Op1);
1334 Res = CurDAG->getNode(ISD::BITCAST, dl, VecVT, Res);
1336 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1339 CurDAG->getIntPtrConstant(0, dl));
1341 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1348 if (OptLevel != CodeGenOptLevel::None &&
1351 !Subtarget->useIndirectThunkCalls() &&
1352 ((
N->getOpcode() ==
X86ISD::CALL && !Subtarget->slowTwoMemOps()) ||
1354 (Subtarget->is64Bit() ||
1355 !getTargetMachine().isPositionIndependent())))) {
1394 switch (
N->getOpcode()) {
1397 case ISD::FP_EXTEND:
1399 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1400 MVT DstVT =
N->getSimpleValueType(0);
1408 const X86TargetLowering *X86Lowering =
1409 static_cast<const X86TargetLowering *
>(TLI);
1412 if (SrcIsSSE && DstIsSSE)
1415 if (!SrcIsSSE && !DstIsSSE) {
1417 if (
N->getOpcode() == ISD::FP_EXTEND)
1420 if (
N->getConstantOperandVal(1))
1428 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1430 MachinePointerInfo MPI =
1437 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1439 MemTmp, MPI, MemVT);
1446 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1455 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1456 MVT DstVT =
N->getSimpleValueType(0);
1464 const X86TargetLowering *X86Lowering =
1465 static_cast<const X86TargetLowering *
>(TLI);
1468 if (SrcIsSSE && DstIsSSE)
1471 if (!SrcIsSSE && !DstIsSSE) {
1476 if (
N->getConstantOperandVal(2))
1484 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1486 MachinePointerInfo MPI =
1495 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1496 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1500 if (
N->getFlags().hasNoFPExcept()) {
1502 Flags.setNoFPExcept(
true);
1503 Store->setFlags(Flags);
1506 assert(SrcVT == MemVT &&
"Unexpected VT!");
1507 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1512 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1514 Result = CurDAG->getMemIntrinsicNode(
1517 if (
N->getFlags().hasNoFPExcept()) {
1519 Flags.setNoFPExcept(
true);
1523 assert(DstVT == MemVT &&
"Unexpected VT!");
1524 Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
1532 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1546 CurDAG->RemoveDeadNodes();
1550bool X86DAGToDAGISel::tryOptimizeRem8Extend(SDNode *
N) {
1551 unsigned Opc =
N->getMachineOpcode();
1552 if (
Opc != X86::MOVZX32rr8 &&
Opc != X86::MOVSX32rr8 &&
1553 Opc != X86::MOVSX64rr8)
1565 unsigned ExpectedOpc =
Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1566 : X86::MOVSX32rr8_NOREX;
1571 if (
Opc == X86::MOVSX64rr8) {
1574 MachineSDNode *Extend = CurDAG->getMachineNode(X86::MOVSX64rr32, SDLoc(
N),
1576 ReplaceUses(
N, Extend);
1585void X86DAGToDAGISel::PostprocessISelDAG() {
1587 if (
TM.getOptLevel() == CodeGenOptLevel::None)
1592 bool MadeChange =
false;
1593 while (Position != CurDAG->allnodes_begin()) {
1594 SDNode *
N = &*--Position;
1596 if (
N->use_empty() || !
N->isMachineOpcode())
1599 if (tryOptimizeRem8Extend(
N)) {
1604 unsigned Opc =
N->getMachineOpcode();
1615 case X86::CTEST16rr:
1616 case X86::CTEST32rr:
1617 case X86::CTEST64rr: {
1623#define CASE_ND(OP) \
1626 switch (
And.getMachineOpcode()) {
1633 if (
And->hasAnyUseOfValue(1))
1636 Ops[0] =
And.getOperand(0);
1637 Ops[1] =
And.getOperand(1);
1638 MachineSDNode *
Test =
1639 CurDAG->getMachineNode(
Opc, SDLoc(
N), MVT::i32,
Ops);
1640 ReplaceUses(
N,
Test);
1648 if (
And->hasAnyUseOfValue(1))
1651 bool IsCTESTCC = X86::isCTESTCC(
Opc);
1652#define FROM_TO(A, B) \
1653 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1655 switch (
And.getMachineOpcode()) {
1665 And.getOperand(3),
And.getOperand(4),
1666 And.getOperand(5),
And.getOperand(0)};
1669 Ops.push_back(
N->getOperand(2));
1670 Ops.push_back(
N->getOperand(3));
1673 Ops.push_back(
And.getOperand(6));
1676 Ops.push_back(
N->getOperand(4));
1678 MachineSDNode *
Test = CurDAG->getMachineNode(
1679 NewOpc, SDLoc(
N), MVT::i32, MVT::Other,
Ops);
1680 CurDAG->setNodeMemRefs(
1693 case X86::KORTESTBkk:
1694 case X86::KORTESTWkk:
1695 case X86::KORTESTDkk:
1696 case X86::KORTESTQkk: {
1698 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1713#define FROM_TO(A, B) \
1725 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1728 MachineSDNode *KTest = CurDAG->getMachineNode(
1730 ReplaceUses(
N, KTest);
1735 case TargetOpcode::SUBREG_TO_REG: {
1736 unsigned SubRegIdx =
N->getConstantOperandVal(2);
1737 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1754 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1755 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1756 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1757 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1758 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1759 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1760 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1761 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1766 if (!
In.isMachineOpcode() ||
1767 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1772 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1780 CurDAG->UpdateNodeOperands(
N,
N->getOperand(0), In,
N->getOperand(2));
1787 CurDAG->RemoveDeadNodes();
1792void X86DAGToDAGISel::emitSpecialCodeForMain() {
1793 if (Subtarget->isTargetCygMing()) {
1794 TargetLowering::ArgListTy
Args;
1795 auto &
DL = CurDAG->getDataLayout();
1797 TargetLowering::CallLoweringInfo CLI(*CurDAG);
1798 CLI.setChain(CurDAG->getRoot())
1799 .setCallee(CallingConv::C, Type::getVoidTy(*CurDAG->getContext()),
1800 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1802 const TargetLowering &TLI = CurDAG->getTargetLoweringInfo();
1804 CurDAG->setRoot(
Result.second);
1808void X86DAGToDAGISel::emitFunctionEntryCode() {
1811 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1812 emitSpecialCodeForMain();
1825bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t
Offset,
1826 X86ISelAddressMode &AM) {
1831 int64_t Val = AM.Disp +
Offset;
1834 if (Val != 0 && (AM.ES || AM.MCSym))
1838 if (Subtarget->is64Bit()) {
1841 AM.hasSymbolicDisplacement()))
1845 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1864 if (Subtarget->isTarget64BitILP32() &&
1866 !AM.hasBaseOrIndexReg())
1876bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *
N, X86ISelAddressMode &AM,
1877 bool AllowSegmentRegForX32) {
1890 !IndirectTlsSegRefs &&
1891 (Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() ||
1892 Subtarget->isTargetFuchsia())) {
1893 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1895 switch (
N->getPointerInfo().getAddrSpace()) {
1897 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1900 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1913bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1916 if (AM.hasSymbolicDisplacement())
1919 bool IsRIPRelTLS =
false;
1937 if (IsRIPRel && AM.hasBaseOrIndexReg())
1941 X86ISelAddressMode Backup = AM;
1946 AM.GV =
G->getGlobal();
1947 AM.SymbolFlags =
G->getTargetFlags();
1950 AM.CP =
CP->getConstVal();
1951 AM.Alignment =
CP->getAlign();
1952 AM.SymbolFlags =
CP->getTargetFlags();
1955 AM.ES = S->getSymbol();
1956 AM.SymbolFlags = S->getTargetFlags();
1958 AM.MCSym = S->getMCSymbol();
1960 AM.JT = J->getIndex();
1961 AM.SymbolFlags = J->getTargetFlags();
1963 AM.BlockAddr = BA->getBlockAddress();
1964 AM.SymbolFlags = BA->getTargetFlags();
1965 Offset = BA->getOffset();
1970 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1971 TM.isLargeGlobalValue(AM.GV)) {
1976 if (foldOffsetIntoAddress(
Offset, AM)) {
1982 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
1990bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
1991 if (matchAddressRecursively(
N, AM, 0))
1998 if (Subtarget->isTarget64BitILP32() &&
1999 AM.BaseType == X86ISelAddressMode::RegBase &&
2000 AM.Base_Reg.
getNode() !=
nullptr && AM.IndexReg.
getNode() ==
nullptr) {
2001 SDValue Save_Base_Reg = AM.Base_Reg;
2004 if (matchLoadInAddress(LoadN, AM,
true))
2005 AM.Base_Reg = Save_Base_Reg;
2011 if (AM.Scale == 2 &&
2012 AM.BaseType == X86ISelAddressMode::RegBase &&
2013 AM.Base_Reg.
getNode() ==
nullptr) {
2014 AM.Base_Reg = AM.IndexReg;
2021 (!AM.GV || !
TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2022 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2023 AM.Base_Reg.
getNode() ==
nullptr && AM.IndexReg.
getNode() ==
nullptr &&
2035 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2041bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
2045 HandleSDNode Handle(
N);
2047 X86ISelAddressMode Backup = AM;
2048 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
2049 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
2054 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
2056 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2063 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2066 N = Handle.getValue();
2072 N = Handle.getValue();
2082 if (
N->getNodeId() == -1 ||
2102 X86ISelAddressMode &AM) {
2109 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2110 Mask != (0xffu << ScaleLog))
2113 MVT XVT =
X.getSimpleValueType();
2114 MVT VT =
N.getSimpleValueType();
2139 AM.Scale = (1 << ScaleLog);
2147 X86ISelAddressMode &AM) {
2158 bool FoundAnyExtend =
false;
2162 FoundAnyExtend =
true;
2180 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2183 MVT VT =
N.getSimpleValueType();
2185 if (FoundAnyExtend) {
2206 AM.Scale = 1 << ShiftAmt;
2207 AM.IndexReg = NewAnd;
2241 X86ISelAddressMode &AM) {
2247 unsigned MaskIdx, MaskLen;
2250 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2256 unsigned AMShiftAmt = MaskIdx;
2260 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2264 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2265 if (MaskLZ < ScaleDown)
2267 MaskLZ -= ScaleDown;
2275 bool ReplacingAnyExtend =
false;
2277 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2278 X.getOperand(0).getSimpleValueType().getSizeInBits();
2281 X =
X.getOperand(0);
2282 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2283 ReplacingAnyExtend =
true;
2285 APInt MaskedHighBits =
2292 MVT VT =
N.getSimpleValueType();
2293 if (ReplacingAnyExtend) {
2294 assert(
X.getValueType() != VT);
2301 MVT XVT =
X.getSimpleValueType();
2322 AM.Scale = 1 << AMShiftAmt;
2323 AM.IndexReg = NewExt;
2333 X86ISelAddressMode &AM,
2341 if (!Subtarget.hasTBM() &&
2342 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2346 unsigned MaskIdx, MaskLen;
2354 unsigned AMShiftAmt = MaskIdx;
2358 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2360 MVT XVT =
X.getSimpleValueType();
2361 MVT VT =
N.getSimpleValueType();
2386 AM.Scale = 1 << AMShiftAmt;
2387 AM.IndexReg = NewExt;
2394 X86ISelAddressMode &AM,
2396 assert(AM.IndexReg.
getNode() ==
nullptr &&
"IndexReg already matched");
2397 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2398 "Illegal index scale");
2404 EVT VT =
N.getValueType();
2405 unsigned Opc =
N.getOpcode();
2408 if (CurDAG->isBaseWithConstantOffset(
N)) {
2410 uint64_t
Offset = (uint64_t)AddVal->getSExtValue() * AM.Scale;
2411 if (!foldOffsetIntoAddress(
Offset, AM))
2412 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2416 if (
Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2417 if (AM.Scale <= 4) {
2419 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2425 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2426 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2427 if ((AM.Scale * ScaleAmt) <= 8) {
2428 AM.Scale *= ScaleAmt;
2429 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2437 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2439 if (CurDAG->isBaseWithConstantOffset(Src)) {
2440 SDValue AddSrc = Src.getOperand(0);
2442 int64_t
Offset = AddVal->getSExtValue();
2443 if (!foldOffsetIntoAddress((uint64_t)
Offset * AM.Scale, AM)) {
2451 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2452 CurDAG->RemoveDeadNode(
N.getNode());
2464 unsigned SrcOpc = Src.getOpcode();
2465 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2466 CurDAG->isADDLike(Src,
true)) &&
2468 if (CurDAG->isBaseWithConstantOffset(Src)) {
2469 SDValue AddSrc = Src.getOperand(0);
2470 uint64_t
Offset = Src.getConstantOperandVal(1);
2471 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2481 uint64_t ScaleAmt = 1ULL << ShAmt;
2482 if ((AM.Scale * ScaleAmt) <= 8 &&
2484 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2485 AM.Scale *= ScaleAmt;
2486 SDValue ExtShVal = CurDAG->getNode(
Opc,
DL, VT, ShVal);
2497 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2501 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2502 CurDAG->RemoveDeadNode(
N.getNode());
2503 return Res ? Res : ExtSrc;
2513bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2516 dbgs() <<
"MatchAddress: ";
2521 return matchAddressBase(
N, AM);
2526 if (AM.isRIPRelative()) {
2530 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2534 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2539 switch (
N.getOpcode()) {
2542 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2545 AM.MCSym = ESNode->getMCSymbol();
2552 if (!foldOffsetIntoAddress(Val, AM))
2559 if (!matchWrapper(
N, AM))
2569 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2570 AM.Base_Reg.
getNode() ==
nullptr &&
2572 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2579 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2583 unsigned Val = CN->getZExtValue();
2588 if (Val == 1 || Val == 2 || Val == 3) {
2590 AM.Scale = 1 << Val;
2591 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2599 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2603 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2604 "Unexpected value size!");
2616 uint64_t
Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2628 if (
N.getResNo() != 0)
break;
2633 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2634 AM.Base_Reg.
getNode() ==
nullptr &&
2635 AM.IndexReg.
getNode() ==
nullptr) {
2637 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2638 CN->getZExtValue() == 9) {
2639 AM.Scale = unsigned(CN->getZExtValue())-1;
2651 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2652 if (foldOffsetIntoAddress(Disp, AM))
2653 Reg =
N.getOperand(0);
2655 Reg =
N.getOperand(0);
2658 AM.IndexReg = AM.Base_Reg =
Reg;
2674 HandleSDNode Handle(
N);
2677 X86ISelAddressMode Backup = AM;
2678 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2679 N = Handle.getValue();
2683 N = Handle.getValue();
2685 if (AM.IndexReg.
getNode() || AM.isRIPRelative()) {
2700 RHS.getOperand(0).getValueType() == MVT::i32))
2704 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode() &&
2706 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2710 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2711 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2724 AM.NegateIndex =
true;
2732 if (!CurDAG->isADDLike(
N))
2736 if (!matchAdd(
N, AM,
Depth))
2745 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
break;
2749 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2750 "Unexpected value size!");
2755 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2759 uint64_t
Mask =
N.getConstantOperandVal(1);
2784 if (AM.IndexReg.
getNode() !=
nullptr || AM.Scale != 1)
2792 if (
SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2794 AM.IndexReg =
Index;
2800 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2802 Mask = MaskC->getAPIntValue();
2803 Src = Src.getOperand(0);
2806 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2808 SDValue ShlSrc = Src.getOperand(0);
2809 SDValue ShlAmt = Src.getOperand(1);
2813 unsigned ShAmtV = ShAmtC->getZExtValue();
2821 if (!Src->getFlags().hasNoUnsignedWrap() &&
2822 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2830 MVT VT =
N.getSimpleValueType();
2834 if (!
Mask.isAllOnes()) {
2835 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2837 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2844 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2845 CurDAG->RemoveDeadNode(
N.getNode());
2848 AM.Scale = 1 << ShAmtV;
2852 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2856 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2859 Src.getOperand(0), AM))
2864 Src.getOperand(0), AM))
2869 Src.getOperand(0), AM, *Subtarget))
2877 return matchAddressBase(
N, AM);
2882bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2884 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.
getNode()) {
2897 AM.BaseType = X86ISelAddressMode::RegBase;
2902bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2903 X86ISelAddressMode &AM,
2906 dbgs() <<
"MatchVectorAddress: ";
2911 return matchAddressBase(
N, AM);
2914 switch (
N.getOpcode()) {
2917 if (!foldOffsetIntoAddress(Val, AM))
2922 if (!matchWrapper(
N, AM))
2928 HandleSDNode Handle(
N);
2930 X86ISelAddressMode Backup = AM;
2931 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2932 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2938 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2940 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2945 N = Handle.getValue();
2950 return matchAddressBase(
N, AM);
2956bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2957 return matchVectorAddressRecursively(
N, AM, 0);
2960bool X86DAGToDAGISel::selectVectorAddr(MemSDNode *Parent,
SDValue BasePtr,
2965 X86ISelAddressMode AM;
2971 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2973 AM.IndexReg = IndexOp;
2977 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
2979 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
2981 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
2984 MVT VT =
BasePtr.getSimpleValueType();
2987 if (matchVectorAddress(BasePtr, AM))
2990 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3004 X86ISelAddressMode AM;
3016 unsigned AddrSpace =
3019 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3021 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3023 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3028 MVT VT =
N.getSimpleValueType();
3030 if (matchAddress(
N, AM))
3033 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3049 N =
N.getOperand(0);
3066 return CR->getUnsignedMax().ult(1ull << 32);
3068 return !
TM.isLargeGlobalValue(GV);
3077 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3090 if (RN &&
RN->getReg() == 0)
3091 Base = CurDAG->getRegister(0, MVT::i64);
3101 [[maybe_unused]] EVT IndexType =
Index.getValueType();
3103 if (RN &&
RN->getReg() == 0)
3104 Index = CurDAG->getRegister(0, MVT::i64);
3107 "Expect to be extending 8/16/32-bit registers for use in LEA");
3110 Index = CurDAG->getTargetInsertSubreg(
SubReg,
DL, MVT::i64, ImplDef, Index);
3118bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3122 X86ISelAddressMode AM;
3126 MVT VT =
N.getSimpleValueType();
3131 SDValue T = CurDAG->getRegister(0, MVT::i32);
3133 if (matchAddress(
N, AM))
3138 unsigned Complexity = 0;
3139 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.
getNode())
3141 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3157 if (AM.hasSymbolicDisplacement()) {
3159 if (Subtarget->is64Bit())
3169 auto isMathWithFlags = [](
SDValue V) {
3170 switch (
V.getOpcode()) {
3184 return !
SDValue(
V.getNode(), 1).use_empty();
3191 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3199 if (Complexity <= 2)
3202 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3213 X86ISelAddressMode AM;
3215 AM.GV = GA->getGlobal();
3216 AM.Disp += GA->getOffset();
3217 AM.SymbolFlags = GA->getTargetFlags();
3220 AM.ES = SA->getSymbol();
3221 AM.SymbolFlags = SA->getTargetFlags();
3224 if (Subtarget->is32Bit()) {
3226 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3229 MVT VT =
N.getSimpleValueType();
3230 getAddressOperands(AM, SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3238 EVT VT =
N.getValueType();
3239 bool WasTruncated =
false;
3241 WasTruncated =
true;
3242 N =
N.getOperand(0);
3251 unsigned Opc =
N.getOperand(0)->getOpcode();
3253 Op =
N.getOperand(0);
3256 return !WasTruncated;
3261 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3262 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3266 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(
N), VT,
3267 GA->getOffset(), GA->getTargetFlags());
3271bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *
P,
SDValue N,
3275 assert(Root &&
P &&
"Unknown root/parent nodes");
3277 !IsProfitableToFold(
N,
P, Root) ||
3278 !IsLegalToFold(
N,
P, Root, OptLevel))
3281 return selectAddr(
N.getNode(),
3282 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3285bool X86DAGToDAGISel::tryFoldBroadcast(SDNode *Root, SDNode *
P,
SDValue N,
3289 assert(Root &&
P &&
"Unknown root/parent nodes");
3291 !IsProfitableToFold(
N,
P, Root) ||
3292 !IsLegalToFold(
N,
P, Root, OptLevel))
3295 return selectAddr(
N.getNode(),
3296 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3302SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3305 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3308bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width, SDNode *
N)
const {
3310 N =
N->getOperand(0).getNode();
3318 auto *GV = GA->getGlobal();
3321 return CR->getSignedMin().sge(-1ull << Width) &&
3322 CR->getSignedMax().slt(1ull << Width);
3327 return Width == 32 && !
TM.isLargeGlobalValue(GV);
3331 assert(
N->isMachineOpcode() &&
"Unexpected node");
3332 unsigned Opc =
N->getMachineOpcode();
3333 const MCInstrDesc &MCID = getInstrInfo()->get(
Opc);
3338 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3343bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3345 for (SDUse &Use :
Flags->uses()) {
3347 if (
Use.getResNo() !=
Flags.getResNo())
3355 for (SDUse &FlagUse :
User->uses()) {
3357 if (FlagUse.getResNo() != 1)
3360 if (!FlagUse.getUser()->isMachineOpcode())
3380bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3382 for (SDUse &Use :
Flags->uses()) {
3384 if (
Use.getResNo() !=
Flags.getResNo())
3392 for (SDUse &FlagUse :
User->uses()) {
3394 if (FlagUse.getResNo() != 1)
3397 if (!FlagUse.getUser()->isMachineOpcode())
3437 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3439 for (SDUse &Use :
Flags->uses()) {
3441 if (
Use.getResNo() !=
Flags.getResNo())
3445 unsigned UserOpc =
User->getOpcode();
3452 for (SDUse &FlagUse :
User->uses()) {
3454 if (FlagUse.getResNo() != 1)
3457 if (!FlagUse.getUser()->isMachineOpcode())
3498 if (StoredVal.
getResNo() != 0)
return false;
3515 if (!Load.hasOneUse())
3523 bool FoundLoad =
false;
3527 const unsigned int Max = 1024;
3569 if (Chain == Load.getValue(1)) {
3575 if (
Op == Load.getValue(1)) {
3591 if (
Op.getNode() != LoadNode)
3623bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
3625 SDValue StoredVal = StoreNode->getOperand(1);
3631 EVT MemVT = StoreNode->getMemoryVT();
3632 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3636 bool IsCommutable =
false;
3637 bool IsNegate =
false;
3651 IsCommutable =
true;
3655 unsigned LoadOpNo = IsNegate ? 1 : 0;
3656 LoadSDNode *LoadNode =
nullptr;
3659 LoadNode, InputChain)) {
3666 LoadNode, InputChain))
3671 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3675 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3696 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3699 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3706 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
3710 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3713 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
3714 : SelectOpcode(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
3716 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32,
3727 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
3730 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
3733 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
3736 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
3739 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
3742 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
3745 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
3747 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
3753 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
3756 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
3759 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
3762 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
3765 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
3768 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
3771 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
3774 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
3781 unsigned NewOpc = SelectRegOpcode(
Opc);
3787 int64_t OperandV = OperandC->getSExtValue();
3794 (MemVT == MVT::i64 && !
isInt<32>(OperandV) &&
3796 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3797 OperandV = -OperandV;
3801 if (MemVT != MVT::i64 ||
isInt<32>(OperandV)) {
3802 Operand = CurDAG->getSignedTargetConstant(OperandV, SDLoc(Node), MemVT);
3803 NewOpc = SelectImmOpcode(
Opc);
3809 CurDAG->getCopyToReg(InputChain, SDLoc(Node), X86::EFLAGS,
3813 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
3814 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3818 Segment, Operand, InputChain};
3819 Result = CurDAG->getMachineNode(NewOpc, SDLoc(Node), MVT::i32, MVT::Other,
3828 MachineMemOperand *MemOps[] = {StoreNode->getMemOperand(),
3830 CurDAG->setNodeMemRefs(Result, MemOps);
3836 CurDAG->RemoveDeadNode(Node);
3847bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
3851 "Should be either an and-mask, or right-shift after clearing high bits.");
3854 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
3857 MVT NVT =
Node->getSimpleValueType(0);
3860 if (NVT != MVT::i32 && NVT != MVT::i64)
3868 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
3869 auto checkUses = [AllowExtraUsesByDefault](
3871 std::optional<bool> AllowExtraUses) {
3872 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
3873 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
3875 auto checkOneUse = [checkUses](
SDValue Op,
3876 std::optional<bool> AllowExtraUses =
3878 return checkUses(
Op, 1, AllowExtraUses);
3880 auto checkTwoUse = [checkUses](
SDValue Op,
3881 std::optional<bool> AllowExtraUses =
3883 return checkUses(
Op, 2, AllowExtraUses);
3886 auto peekThroughOneUseTruncation = [checkOneUse](
SDValue V) {
3888 assert(
V.getSimpleValueType() == MVT::i32 &&
3889 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
3890 "Expected i64 -> i32 truncation");
3891 V =
V.getOperand(0);
3897 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
3900 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
3906 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3911 NBits =
M0->getOperand(1);
3912 NegateNBits =
false;
3916 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](
SDValue V) {
3917 V = peekThroughOneUseTruncation(V);
3918 return CurDAG->MaskedValueIsAllOnes(
3924 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
3927 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
3930 if (!isAllOnes(
Mask->getOperand(1)))
3933 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3937 if (!isAllOnes(
M0->getOperand(0)))
3939 NBits =
M0->getOperand(1);
3940 NegateNBits =
false;
3946 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](
SDValue ShiftAmt,
3947 unsigned Bitwidth) {
3952 NBits = NBits.getOperand(0);
3958 if (!V0 || V0->getZExtValue() != Bitwidth)
3960 NBits = NBits.getOperand(1);
3961 NegateNBits =
false;
3967 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
3970 Mask = peekThroughOneUseTruncation(Mask);
3971 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
3973 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
3980 if (!checkOneUse(
M1))
3982 canonicalizeShiftAmt(
M1, Bitwidth);
3987 return !NegateNBits;
3995 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
3996 AllowExtraUsesByDefault, &NegateNBits,
3997 &
X](SDNode *
Node) ->
bool {
4009 canonicalizeShiftAmt(N1, Bitwidth);
4013 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
4014 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4020 auto matchLowBitMask = [matchPatternA, matchPatternB,
4022 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4026 X =
Node->getOperand(0);
4029 if (matchLowBitMask(Mask)) {
4033 if (!matchLowBitMask(Mask))
4036 }
else if (matchLowBitMask(
SDValue(Node, 0))) {
4037 X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
4038 }
else if (!matchPatternD(Node))
4043 if (NegateNBits && !Subtarget->hasBMI2())
4055 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4058 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4060 NBits =
SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4061 MVT::i32, ImplDef, NBits, SRIdxVal),
4071 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4075 if (Subtarget->hasBMI2()) {
4077 if (NVT != MVT::i32) {
4084 ReplaceNode(Node, Extract.
getNode());
4085 SelectCode(Extract.
getNode());
4094 SDValue RealX = peekThroughOneUseTruncation(
X);
4100 MVT XVT =
X.getSimpleValueType();
4110 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4118 SDValue ShiftAmt =
X.getOperand(1);
4119 X =
X.getOperand(0);
4122 "Expected shift amount to be i8");
4126 SDValue OrigShiftAmt = ShiftAmt;
4131 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4136 if (XVT != MVT::i32) {
4150 ReplaceNode(Node, Extract.
getNode());
4151 SelectCode(Extract.
getNode());
4157MachineSDNode *X86DAGToDAGISel::matchBEXTRFromAndImm(SDNode *Node) {
4158 MVT NVT =
Node->getSimpleValueType(0);
4171 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4172 if (!PreferBEXTR && !Subtarget->hasBMI2())
4184 if (NVT != MVT::i32 && NVT != MVT::i64)
4190 if (!MaskCst || !ShiftCst)
4194 uint64_t
Mask = MaskCst->getZExtValue();
4198 uint64_t Shift = ShiftCst->getZExtValue();
4203 if (Shift == 8 && MaskSize == 8)
4214 if (!PreferBEXTR && MaskSize <= 32)
4218 unsigned ROpc, MOpc;
4220#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4222 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4226 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4231 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4232 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4238 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4239 if (Subtarget->hasTBM()) {
4240 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4241 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4243 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4249 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4250 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4254 MachineSDNode *NewNode;
4256 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4257 if (tryFoldLoad(Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4259 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4260 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4261 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4265 CurDAG->setNodeMemRefs(NewNode, {
cast<LoadSDNode>(Input)->getMemOperand()});
4267 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4272 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4276 CurDAG->getMachineNode(NewOpc, dl, NVT,
SDValue(NewNode, 0), ShAmt);
4283MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4284 bool MayFoldLoad,
const SDLoc &dl,
4285 MVT VT, SDNode *Node) {
4290 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4293 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4294 if (MayFoldLoad && tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4297 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4298 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4307 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4308 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4315MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4316 bool MayFoldLoad,
const SDLoc &dl,
4317 MVT VT, SDNode *Node,
4323 Imm = CurDAG->getTargetConstant(*Val, SDLoc(Node),
Imm.getValueType());
4326 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4327 if (MayFoldLoad && tryFoldLoad(Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4330 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4331 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
4341 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4342 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs,
Ops);
4347bool X86DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4348 EVT VT =
N->getValueType(0);
4355 unsigned Size = VT == MVT::i64 ? 64 : 32;
4358 SDValue ShiftAmt = OrigShiftAmt;
4377 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4381 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4382 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4386 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4395 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4396 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4402 Add0C->getZExtValue() != 0) {
4405 if (Add0C->getZExtValue() %
Size == 0)
4408 Add0C->getZExtValue() % 32 == 0) {
4416 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4420 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4442 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4449 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4450 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4454 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4456 if (UpdatedNode !=
N) {
4459 ReplaceNode(
N, UpdatedNode);
4466 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4474bool X86DAGToDAGISel::tryShrinkShlLogicImm(SDNode *
N) {
4475 MVT NVT =
N->getSimpleValueType(0);
4476 unsigned Opcode =
N->getOpcode();
4488 int64_t Val = Cst->getSExtValue();
4493 bool FoundAnyExtend =
false;
4497 FoundAnyExtend =
true;
4505 if (NVT != MVT::i32 && NVT != MVT::i64)
4512 uint64_t ShAmt = ShlCst->getZExtValue();
4516 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4517 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4522 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4526 ShiftedVal = (uint64_t)Val >> ShAmt;
4530 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4533 ShiftedVal = Val >> ShAmt;
4539 ShiftedVal = (uint64_t)Val >> ShAmt;
4547 if (!CanShrinkImmediate(ShiftedVal))
4557 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4563 NeededMask &= ~Cst->getAPIntValue();
4565 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4570 if (FoundAnyExtend) {
4576 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4578 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4587bool X86DAGToDAGISel::matchVPTERNLOG(SDNode *Root, SDNode *ParentA,
4588 SDNode *ParentB, SDNode *ParentC,
4591 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4592 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4594 auto tryFoldLoadOrBCast =
4597 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4601 if (
L.getOpcode() == ISD::BITCAST &&
L.hasOneUse()) {
4603 L =
L.getOperand(0);
4611 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4615 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4618 bool FoldedLoad =
false;
4619 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4620 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4622 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4627 uint8_t OldImm =
Imm;
4628 Imm = OldImm & 0xa5;
4629 if (OldImm & 0x02)
Imm |= 0x10;
4630 if (OldImm & 0x10)
Imm |= 0x02;
4631 if (OldImm & 0x08)
Imm |= 0x40;
4632 if (OldImm & 0x40)
Imm |= 0x08;
4633 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4638 uint8_t OldImm =
Imm;
4639 Imm = OldImm & 0x99;
4640 if (OldImm & 0x02)
Imm |= 0x04;
4641 if (OldImm & 0x04)
Imm |= 0x02;
4642 if (OldImm & 0x20)
Imm |= 0x40;
4643 if (OldImm & 0x40)
Imm |= 0x20;
4648 SDValue TImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
4652 MachineSDNode *MNode;
4654 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4659 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4660 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4662 bool UseD = EltSize == 32;
4664 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4666 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4668 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4674 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4676 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4678 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4684 MNode = CurDAG->getMachineNode(
Opc,
DL, VTs,
Ops);
4687 ReplaceUses(
C.getValue(1),
SDValue(MNode, 1));
4694 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
4696 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
4698 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
4702 MNode = CurDAG->getMachineNode(
Opc,
DL, NVT, {
A,
B,
C, TImm});
4706 CurDAG->RemoveDeadNode(Root);
4712bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *
N) {
4713 MVT NVT =
N->getSimpleValueType(0);
4716 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
4727 auto getFoldableLogicOp = [](
SDValue Op) {
4729 if (
Op.getOpcode() == ISD::BITCAST &&
Op.hasOneUse())
4730 Op =
Op.getOperand(0);
4732 if (!
Op.hasOneUse())
4735 unsigned Opc =
Op.getOpcode();
4744 if ((FoldableOp = getFoldableLogicOp(N1))) {
4746 }
else if ((FoldableOp = getFoldableLogicOp(N0))) {
4753 SDNode *ParentA =
N;
4754 SDNode *ParentB = FoldableOp.
getNode();
4755 SDNode *ParentC = FoldableOp.
getNode();
4759 uint8_t TernlogMagicA = 0xf0;
4760 uint8_t TernlogMagicB = 0xcc;
4761 uint8_t TernlogMagicC = 0xaa;
4766 auto PeekThroughNot = [](
SDValue &
Op, SDNode *&Parent, uint8_t &
Magic) {
4770 Parent =
Op.getNode();
4771 Op =
Op.getOperand(0);
4775 PeekThroughNot(
A, ParentA, TernlogMagicA);
4776 PeekThroughNot(
B, ParentB, TernlogMagicB);
4777 PeekThroughNot(
C, ParentC, TernlogMagicC);
4782 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
4783 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
4784 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
4788 switch (
N->getOpcode()) {
4792 Imm &= ~TernlogMagicA;
4794 Imm = ~(
Imm) & TernlogMagicA;
4801 return matchVPTERNLOG(
N, ParentA, ParentB, ParentC,
A,
B,
C, Imm);
4811bool X86DAGToDAGISel::shrinkAndImmediate(SDNode *
And) {
4814 MVT VT =
And->getSimpleValueType(0);
4815 if (VT != MVT::i32 && VT != MVT::i64)
4827 APInt MaskVal = And1C->getAPIntValue();
4829 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
4833 if (VT == MVT::i64 && MaskLZ >= 32) {
4835 MaskVal = MaskVal.
trunc(32);
4840 APInt NegMaskVal = MaskVal | HighZeros;
4849 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
4850 NegMaskVal = NegMaskVal.
zext(64);
4851 HighZeros = HighZeros.
zext(64);
4857 KnownBits Known0 = CurDAG->computeKnownBits(And0);
4869 SDValue NewMask = CurDAG->getConstant(NegMaskVal, SDLoc(
And), VT);
4878 bool FoldedBCast,
bool Masked) {
4879#define VPTESTM_CASE(VT, SUFFIX) \
4882 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
4883 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
4886#define VPTESTM_BROADCAST_CASES(SUFFIX) \
4887default: llvm_unreachable("Unexpected VT!"); \
4888VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
4889VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
4890VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
4891VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
4892VPTESTM_CASE(v16i32, DZ##SUFFIX) \
4893VPTESTM_CASE(v8i64, QZ##SUFFIX)
4895#define VPTESTM_FULL_CASES(SUFFIX) \
4896VPTESTM_BROADCAST_CASES(SUFFIX) \
4897VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
4898VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
4899VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
4900VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
4901VPTESTM_CASE(v64i8, BZ##SUFFIX) \
4902VPTESTM_CASE(v32i16, WZ##SUFFIX)
4920#undef VPTESTM_FULL_CASES
4921#undef VPTESTM_BROADCAST_CASES
4927bool X86DAGToDAGISel::tryVPTESTM(SDNode *Root,
SDValue Setcc,
4929 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
4974 auto tryFoldLoadOrBCast = [&](SDNode *Root, SDNode *
P,
SDValue &
L,
4979 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4984 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
4988 if (
L.getOpcode() == ISD::BITCAST &&
L.hasOneUse()) {
4990 L =
L.getOperand(0);
4997 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
5000 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
5004 bool CanFoldLoads = Src0 != Src1;
5006 bool FoldedLoad =
false;
5007 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5009 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
5013 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5022 bool IsMasked = InMask.
getNode() !=
nullptr;
5035 SDValue ImplDef =
SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5037 Src0 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src0);
5040 Src1 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src1);
5045 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5046 InMask =
SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5047 dl, MaskVT, InMask, RC), 0);
5055 MachineSDNode *CNode;
5057 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5060 SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5062 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5064 SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5066 CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5072 CurDAG->setNodeMemRefs(CNode, {
cast<MemSDNode>(Src1)->getMemOperand()});
5075 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, InMask, Src0, Src1);
5077 CNode = CurDAG->getMachineNode(
Opc, dl, MaskVT, Src0, Src1);
5083 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5084 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5085 dl, ResVT,
SDValue(CNode, 0), RC);
5089 CurDAG->RemoveDeadNode(Root);
5095bool X86DAGToDAGISel::tryMatchBitSelect(SDNode *
N) {
5098 MVT NVT =
N->getSimpleValueType(0);
5101 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5135 SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5143void X86DAGToDAGISel::Select(SDNode *Node) {
5144 MVT NVT =
Node->getSimpleValueType(0);
5145 unsigned Opcode =
Node->getOpcode();
5148 if (
Node->isMachineOpcode()) {
5150 Node->setNodeId(-1);
5157 unsigned IntNo =
Node->getConstantOperandVal(1);
5160 case Intrinsic::x86_encodekey128:
5161 case Intrinsic::x86_encodekey256: {
5162 if (!Subtarget->hasKL())
5168 case Intrinsic::x86_encodekey128:
5169 Opcode = X86::ENCODEKEY128;
5171 case Intrinsic::x86_encodekey256:
5172 Opcode = X86::ENCODEKEY256;
5177 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5179 if (Opcode == X86::ENCODEKEY256)
5180 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5183 MachineSDNode *Res = CurDAG->getMachineNode(
5184 Opcode, dl,
Node->getVTList(),
5185 {Node->getOperand(2), Chain, Chain.getValue(1)});
5186 ReplaceNode(Node, Res);
5189 case Intrinsic::x86_tileloaddrs64_internal:
5190 case Intrinsic::x86_tileloaddrst164_internal:
5191 if (!Subtarget->hasAMXMOVRS())
5194 case Intrinsic::x86_tileloadd64_internal:
5195 case Intrinsic::x86_tileloaddt164_internal: {
5196 if (!Subtarget->hasAMXTILE())
5199 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5200 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5205 case Intrinsic::x86_tileloaddrs64_internal:
5206 Opc = X86::PTILELOADDRSV;
5208 case Intrinsic::x86_tileloaddrst164_internal:
5209 Opc = X86::PTILELOADDRST1V;
5211 case Intrinsic::x86_tileloadd64_internal:
5212 Opc = X86::PTILELOADDV;
5214 case Intrinsic::x86_tileloaddt164_internal:
5215 Opc = X86::PTILELOADDT1V;
5220 SDValue Scale = getI8Imm(1, dl);
5222 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5223 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5225 MachineSDNode *CNode;
5227 Node->getOperand(3),
5234 CNode = CurDAG->getMachineNode(
Opc, dl, {MVT::x86amx, MVT::Other},
Ops);
5235 ReplaceNode(Node, CNode);
5242 unsigned IntNo =
Node->getConstantOperandVal(1);
5245 case Intrinsic::x86_sse3_monitor:
5246 case Intrinsic::x86_monitorx:
5247 case Intrinsic::x86_clzero: {
5248 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5253 case Intrinsic::x86_sse3_monitor:
5254 if (!Subtarget->hasSSE3())
5256 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5258 case Intrinsic::x86_monitorx:
5259 if (!Subtarget->hasMWAITX())
5261 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5263 case Intrinsic::x86_clzero:
5264 if (!Subtarget->hasCLZERO())
5266 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5271 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5272 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5276 if (IntNo == Intrinsic::x86_sse3_monitor ||
5277 IntNo == Intrinsic::x86_monitorx) {
5279 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5282 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5287 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
5289 ReplaceNode(Node, CNode);
5295 case Intrinsic::x86_tilestored64_internal: {
5297 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5298 MFI->setAMXProgModel(AMXProgModelEnum::ManagedRA);
5299 unsigned Opc = X86::PTILESTOREDV;
5302 SDValue Scale = getI8Imm(1, dl);
5304 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5305 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5307 MachineSDNode *CNode;
5309 Node->getOperand(3),
5315 Node->getOperand(6),
5317 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5318 ReplaceNode(Node, CNode);
5321 case Intrinsic::x86_tileloaddrs64:
5322 case Intrinsic::x86_tileloaddrst164:
5323 if (!Subtarget->hasAMXMOVRS())
5326 case Intrinsic::x86_tileloadd64:
5327 case Intrinsic::x86_tileloaddt164:
5328 case Intrinsic::x86_tilestored64: {
5329 if (!Subtarget->hasAMXTILE())
5332 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5333 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5337 case Intrinsic::x86_tileloadd64:
Opc = X86::PTILELOADD;
break;
5338 case Intrinsic::x86_tileloaddrs64:
5339 Opc = X86::PTILELOADDRS;
5341 case Intrinsic::x86_tileloaddt164:
Opc = X86::PTILELOADDT1;
break;
5342 case Intrinsic::x86_tileloaddrst164:
5343 Opc = X86::PTILELOADDRST1;
5345 case Intrinsic::x86_tilestored64:
Opc = X86::PTILESTORED;
break;
5348 unsigned TIndex =
Node->getConstantOperandVal(2);
5351 SDValue Scale = getI8Imm(1, dl);
5353 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5354 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5356 MachineSDNode *CNode;
5357 if (
Opc == X86::PTILESTORED) {
5359 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5362 CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5364 ReplaceNode(Node, CNode);
5367 case Intrinsic::x86_t2rpntlvwz0rs:
5368 case Intrinsic::x86_t2rpntlvwz0rst1:
5369 case Intrinsic::x86_t2rpntlvwz1rs:
5370 case Intrinsic::x86_t2rpntlvwz1rst1:
5371 if (!Subtarget->hasAMXMOVRS())
5374 case Intrinsic::x86_t2rpntlvwz0:
5375 case Intrinsic::x86_t2rpntlvwz0t1:
5376 case Intrinsic::x86_t2rpntlvwz1:
5377 case Intrinsic::x86_t2rpntlvwz1t1: {
5378 if (!Subtarget->hasAMXTRANSPOSE())
5381 CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
5382 MFI->setAMXProgModel(AMXProgModelEnum::DirectReg);
5387 case Intrinsic::x86_t2rpntlvwz0:
5388 Opc = X86::PT2RPNTLVWZ0;
5390 case Intrinsic::x86_t2rpntlvwz0t1:
5391 Opc = X86::PT2RPNTLVWZ0T1;
5393 case Intrinsic::x86_t2rpntlvwz1:
5394 Opc = X86::PT2RPNTLVWZ1;
5396 case Intrinsic::x86_t2rpntlvwz1t1:
5397 Opc = X86::PT2RPNTLVWZ1T1;
5399 case Intrinsic::x86_t2rpntlvwz0rs:
5400 Opc = X86::PT2RPNTLVWZ0RS;
5402 case Intrinsic::x86_t2rpntlvwz0rst1:
5403 Opc = X86::PT2RPNTLVWZ0RST1;
5405 case Intrinsic::x86_t2rpntlvwz1rs:
5406 Opc = X86::PT2RPNTLVWZ1RS;
5408 case Intrinsic::x86_t2rpntlvwz1rst1:
5409 Opc = X86::PT2RPNTLVWZ1RST1;
5413 unsigned TIndex =
Node->getConstantOperandVal(2);
5416 SDValue Scale = getI8Imm(1, dl);
5418 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5419 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5422 MachineSDNode *CNode = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
5423 ReplaceNode(Node, CNode);
5431 if (Subtarget->isTarget64BitILP32()) {
5436 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5437 SDValue ZextTarget = CurDAG->getZExtOrTrunc(Target, dl, MVT::i64);
5438 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5439 Node->getOperand(0), ZextTarget);
5440 ReplaceNode(Node, Brind.
getNode());
5441 SelectCode(ZextTarget.
getNode());
5448 ReplaceNode(Node, getGlobalBaseReg());
5455 ReplaceUses(
SDValue(Node, 0),
Node->getOperand(0));
5456 CurDAG->RemoveDeadNode(Node);
5462 if (matchBitExtract(Node))
5467 if (tryShiftAmountMod(Node))
5472 uint8_t
Imm =
Node->getConstantOperandVal(3);
5473 if (matchVPTERNLOG(Node, Node, Node, Node,
Node->getOperand(0),
5474 Node->getOperand(1),
Node->getOperand(2), Imm))
5480 if (tryVPTERNLOG(Node))
5490 tryVPTESTM(Node, N0, N1))
5493 tryVPTESTM(Node, N1, N0))
5497 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(Node)) {
5499 CurDAG->RemoveDeadNode(Node);
5502 if (matchBitExtract(Node))
5510 if (tryShrinkShlLogicImm(Node))
5512 if (Opcode ==
ISD::OR && tryMatchBitSelect(Node))
5514 if (tryVPTERNLOG(Node))
5519 if (Opcode ==
ISD::ADD && matchBitExtract(Node))
5529 if (!CurDAG->shouldOptForSize())
5533 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5543 int64_t Val = Cst->getSExtValue();
5551 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5555 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5559 unsigned ROpc, MOpc;
5668 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5669 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5671 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5672 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5678 CurDAG->RemoveDeadNode(Node);
5683 CurDAG->SelectNodeTo(Node, ROpc, NVT, MVT::i32, N0, N1);
5696 unsigned LoReg, ROpc, MOpc;
5701 ROpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
5702 MOpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
5721 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5722 bool FoldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5725 FoldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5730 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5733 MachineSDNode *CNode;
5739 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5741 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
5745 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5756 VTs = CurDAG->getVTList(NVT, MVT::i32);
5758 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
5760 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
5764 ReplaceUses(
SDValue(Node, 1),
SDValue(CNode, NVT == MVT::i8 ? 1 : 2));
5765 CurDAG->RemoveDeadNode(Node);
5775 unsigned LoReg, HiReg;
5777 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
5778 bool UseMULXHi = UseMULX &&
SDValue(Node, 0).use_empty();
5782 Opc = UseMULXHi ? X86::MULX32Hrr
5784 : IsSigned ?
X86::IMUL32r
5786 MOpc = UseMULXHi ? X86::MULX32Hrm
5788 : IsSigned ?
X86::IMUL32m
5790 LoReg = UseMULX ? X86::EDX : X86::EAX;
5794 Opc = UseMULXHi ? X86::MULX64Hrr
5796 : IsSigned ?
X86::IMUL64r
5798 MOpc = UseMULXHi ? X86::MULX64Hrm
5800 : IsSigned ?
X86::IMUL64m
5802 LoReg = UseMULX ? X86::RDX : X86::RAX;
5807 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5808 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5811 foldedLoad = tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5816 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5821 MachineSDNode *CNode =
nullptr;
5825 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5826 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5829 }
else if (UseMULX) {
5830 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
5831 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5836 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5837 CNode = CurDAG->getMachineNode(MOpc, dl, VTs,
Ops);
5843 ReplaceUses(N1.
getValue(1), Chain);
5849 SDVTList VTs = CurDAG->getVTList(NVT);
5850 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5852 }
else if (UseMULX) {
5853 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
5854 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5858 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
5859 SDNode *CNode = CurDAG->getMachineNode(
Opc, dl, VTs,
Ops);
5865 if (!
SDValue(Node, 0).use_empty()) {
5867 assert(LoReg &&
"Register for low half is not defined!");
5868 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
5872 ReplaceUses(
SDValue(Node, 0), ResLo);
5877 if (!
SDValue(Node, 1).use_empty()) {
5879 assert(HiReg &&
"Register for high half is not defined!");
5880 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
5884 ReplaceUses(
SDValue(Node, 1), ResHi);
5889 CurDAG->RemoveDeadNode(Node);
5898 unsigned ROpc, MOpc;
5903 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
5904 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
5905 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
5906 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
5911 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
5912 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
5913 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
5914 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
5918 unsigned LoReg, HiReg, ClrReg;
5919 unsigned SExtOpcode;
5923 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
5927 LoReg = X86::AX; HiReg = X86::DX;
5929 SExtOpcode = X86::CWD;
5932 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
5933 SExtOpcode = X86::CDQ;
5936 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
5937 SExtOpcode = X86::CQO;
5941 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5942 bool foldedLoad = tryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5943 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
5946 if (NVT == MVT::i8) {
5949 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
5950 MachineSDNode *Move;
5951 if (tryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5953 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rm8
5955 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, MVT::Other,
Ops);
5957 ReplaceUses(N0.
getValue(1), Chain);
5961 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rr8
5963 Move = CurDAG->getMachineNode(
Opc, dl, MVT::i16, N0);
5964 Chain = CurDAG->getEntryNode();
5966 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX,
SDValue(Move, 0),
5971 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
5972 LoReg, N0,
SDValue()).getValue(1);
5976 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
5979 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
5981 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
5985 SDValue(CurDAG->getMachineNode(
5986 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
5987 CurDAG->getTargetConstant(X86::sub_16bit, dl,
5995 SDValue(CurDAG->getMachineNode(
5996 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
5997 CurDAG->getTargetConstant(0, dl, MVT::i64), ClrNode,
5998 CurDAG->getTargetConstant(X86::sub_32bit, dl,
6006 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
6007 ClrNode, InGlue).getValue(1);
6014 MachineSDNode *CNode =
6015 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue,
Ops);
6023 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
6033 if (HiReg == X86::AH && !
SDValue(Node, 1).use_empty()) {
6034 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
6035 unsigned AHExtOpcode =
6036 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6038 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6039 MVT::Glue, AHCopy, InGlue);
6044 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6046 ReplaceUses(
SDValue(Node, 1), Result);
6051 if (!
SDValue(Node, 0).use_empty()) {
6052 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6053 LoReg, NVT, InGlue);
6054 InGlue =
Result.getValue(2);
6055 ReplaceUses(
SDValue(Node, 0), Result);
6060 if (!
SDValue(Node, 1).use_empty()) {
6061 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6062 HiReg, NVT, InGlue);
6063 InGlue =
Result.getValue(2);
6064 ReplaceUses(
SDValue(Node, 1), Result);
6068 CurDAG->RemoveDeadNode(Node);
6077 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6078 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6084 if (Subtarget->canUseCMOV())
6093 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6096 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6099 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6104 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6107 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6108 Chain =
SDValue(CurDAG->getMachineNode(
Opc, dl, VTs, {N0, N1, Chain}), 0);
6111 Glue =
SDValue(CurDAG->getMachineNode(
Opc, dl, MVT::Glue, N0, N1), 0);
6116 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6120 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6124 assert(Subtarget->canUseLAHFSAHF() &&
6125 "Target doesn't support SAHF or FCOMI?");
6126 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract,
SDValue());
6129 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6132 ReplaceUses(
SDValue(Node, 1), Chain);
6134 ReplaceUses(
SDValue(Node, 0), SAHF);
6135 CurDAG->RemoveDeadNode(Node);
6155 if (MachineSDNode *NewNode = matchBEXTRFromAndImm(N0.
getNode())) {
6156 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6159 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6161 CurDAG->RemoveDeadNode(Node);
6181 uint64_t
Mask = MaskC->getZExtValue();
6188 onlyUsesZeroFlag(
SDValue(Node, 0))) {
6193 unsigned TestOpcode;
6201 if (LeadingZeros == 0 && SavesBytes) {
6206 ShiftAmt = TrailingZeros;
6208 TestOpcode = X86::TEST64rr;
6209 }
else if (TrailingZeros == 0 && SavesBytes) {
6214 ShiftAmt = LeadingZeros;
6216 TestOpcode = X86::TEST64rr;
6217 }
else if (MaskC->hasOneUse() && !
isInt<32>(Mask)) {
6220 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6221 if (PopCount == 8) {
6223 ShiftAmt = TrailingZeros;
6224 SubRegIdx = X86::sub_8bit;
6226 TestOpcode = X86::TEST8rr;
6227 }
else if (PopCount == 16) {
6229 ShiftAmt = TrailingZeros;
6230 SubRegIdx = X86::sub_16bit;
6231 SubRegVT = MVT::i16;
6232 TestOpcode = X86::TEST16rr;
6233 }
else if (PopCount == 32) {
6235 ShiftAmt = TrailingZeros;
6236 SubRegIdx = X86::sub_32bit;
6237 SubRegVT = MVT::i32;
6238 TestOpcode = X86::TEST32rr;
6242 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6244 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6247 if (SubRegIdx != 0) {
6249 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6251 MachineSDNode *
Test =
6252 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6253 ReplaceNode(Node,
Test);
6260 unsigned ROpc, MOpc;
6268 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6269 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6272 SubRegOp = X86::sub_8bit;
6273 ROpc = X86::TEST8ri;
6274 MOpc = X86::TEST8mi;
6275 }
else if (OptForMinSize &&
isUInt<16>(Mask) &&
6276 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6277 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6283 SubRegOp = X86::sub_16bit;
6284 ROpc = X86::TEST16ri;
6285 MOpc = X86::TEST16mi;
6287 ((!(Mask & 0x80000000) &&
6290 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6291 CmpVT == MVT::i32 ||
6292 hasNoSignFlagUses(
SDValue(Node, 0)))) {
6299 SubRegOp = X86::sub_32bit;
6300 ROpc = X86::TEST32ri;
6301 MOpc = X86::TEST32mi;
6307 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6311 MachineSDNode *NewNode;
6312 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6313 if (tryFoldLoad(Node, N0.
getNode(),
Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6315 if (!LoadN->isSimple()) {
6316 unsigned NumVolBits = LoadN->getValueType(0).getSizeInBits();
6317 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6318 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6319 (MOpc == X86::TEST32mi && NumVolBits != 32))
6324 Reg.getOperand(0) };
6325 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other,
Ops);
6327 ReplaceUses(
Reg.getValue(1),
SDValue(NewNode, 1));
6329 CurDAG->setNodeMemRefs(NewNode,
6334 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT,
Reg);
6336 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32,
Reg, Imm);
6339 ReplaceNode(Node, NewNode);
6345 if (!Subtarget->hasSSE42())
6348 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6349 bool NeedMask = !
SDValue(Node, 1).use_empty();
6351 bool MayFoldLoad = !NeedIndex || !NeedMask;
6353 MachineSDNode *CNode;
6356 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6358 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6359 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node);
6362 if (NeedIndex || !NeedMask) {
6364 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6366 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6367 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node);
6373 CurDAG->RemoveDeadNode(Node);
6377 if (!Subtarget->hasSSE42())
6381 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6382 Node->getOperand(1),
6384 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6385 Node->getOperand(3), InGlue).getValue(1);
6387 bool NeedIndex = !
SDValue(Node, 0).use_empty();
6388 bool NeedMask = !
SDValue(Node, 1).use_empty();
6390 bool MayFoldLoad = !NeedIndex || !NeedMask;
6392 MachineSDNode *CNode;
6395 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6397 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6399 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8, Node, InGlue);
6402 if (NeedIndex || !NeedMask) {
6404 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6406 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6407 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32, Node, InGlue);
6412 CurDAG->RemoveDeadNode(Node);
6424 if (foldLoadStoreIntoMemOperand(Node))
6429 MVT VT =
Node->getSimpleValueType(0);
6431 if (Subtarget->hasSBBDepBreaking()) {
6436 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6441 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6442 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6444 CurDAG->getMachineNode(
Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6449 Result = getSBBZero(Node);
6453 if (VT == MVT::i8 || VT == MVT::i16) {
6454 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6455 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6458 ReplaceUses(
SDValue(Node, 0), Result);
6459 CurDAG->RemoveDeadNode(Node);
6471 if (!
SDValue(Node, 0).use_empty()) {
6473 MVT VT =
Node->getSimpleValueType(0);
6474 if (VT == MVT::i8 || VT == MVT::i16) {
6475 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6476 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6478 ReplaceUses(
SDValue(Node, 0), Result);
6481 CurDAG->RemoveDeadNode(Node);
6488 SDValue IndexOp = Mgt->getIndex();
6491 MVT ValueVT =
Node->getSimpleValueType(0);
6492 MVT MaskVT =
Mask.getSimpleValueType();
6509 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6510 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6511 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6512 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6513 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6514 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6515 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6516 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6517 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6518 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6519 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6520 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6521 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6522 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6523 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6524 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6525 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6526 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6527 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6528 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6529 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6530 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6531 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6532 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6534 assert(EVT(MaskVT) == EVT(ValueVT).changeVectorElementTypeToInteger() &&
6535 "Unexpected mask VT!");
6536 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6537 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6538 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6539 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6540 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6541 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6542 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6543 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6544 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6545 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6546 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6547 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6548 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6549 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6550 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6551 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6558 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6559 Base, Scale, Index, Disp, Segment))
6562 SDValue PassThru = Mgt->getPassThru();
6563 SDValue Chain = Mgt->getChain();
6565 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6567 MachineSDNode *NewNode;
6570 Index, Disp, Segment, Chain};
6571 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6574 Disp, Segment,
Mask, Chain};
6575 NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6577 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6580 CurDAG->RemoveDeadNode(Node);
6586 SDValue IndexOp = Sc->getIndex();
6588 MVT ValueVT =
Value.getSimpleValueType();
6603 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6604 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6605 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6606 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6607 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6608 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6609 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6610 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6611 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6612 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6613 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6614 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6615 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6616 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6617 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6618 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6619 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6620 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6621 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6622 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6623 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6624 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6625 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6626 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6631 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6632 Base, Scale, Index, Disp, Segment))
6636 SDValue Chain = Sc->getChain();
6638 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6641 MachineSDNode *NewNode = CurDAG->getMachineNode(
Opc, SDLoc(dl), VTs,
Ops);
6642 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6644 CurDAG->RemoveDeadNode(Node);
6647 case ISD::PREALLOCATED_SETUP: {
6648 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6649 auto CallId = MFI->getPreallocatedIdForCallSite(
6652 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6653 MachineSDNode *
New = CurDAG->getMachineNode(
6654 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6656 CurDAG->RemoveDeadNode(Node);
6659 case ISD::PREALLOCATED_ARG: {
6660 auto *MFI = CurDAG->getMachineFunction().getInfo<X86MachineFunctionInfo>();
6664 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6667 Ops[0] = CallIdValue;
6670 MachineSDNode *
New = CurDAG->getMachineNode(
6671 TargetOpcode::PREALLOCATED_ARG, dl,
6672 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
6677 CurDAG->RemoveDeadNode(Node);
6684 if (!Subtarget->hasWIDEKL())
6688 switch (
Node->getOpcode()) {
6692 Opcode = X86::AESENCWIDE128KL;
6695 Opcode = X86::AESDECWIDE128KL;
6698 Opcode = X86::AESENCWIDE256KL;
6701 Opcode = X86::AESDECWIDE256KL;
6709 if (!selectAddr(Node, Addr,
Base, Scale, Index, Disp, Segment))
6712 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
6714 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
6716 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
6718 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
6720 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
6722 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
6724 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
6726 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
6729 MachineSDNode *Res = CurDAG->getMachineNode(
6730 Opcode, dl,
Node->getVTList(),
6731 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
6733 ReplaceNode(Node, Res);
6740 if (
Node->getNumValues() == 3)
6741 Glue =
Node->getOperand(2);
6743 CurDAG->getCopyFromReg(Chain, dl,
Reg,
Node->getValueType(0), Glue);
6744 ReplaceNode(Node,
Copy.getNode());
6752bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
6754 std::vector<SDValue> &OutOps) {
6755 SDValue Op0, Op1, Op2, Op3, Op4;
6756 switch (ConstraintID) {
6759 case InlineAsm::ConstraintCode::o:
6760 case InlineAsm::ConstraintCode::v:
6761 case InlineAsm::ConstraintCode::m:
6762 case InlineAsm::ConstraintCode::X:
6763 case InlineAsm::ConstraintCode::p:
6764 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
6769 OutOps.push_back(Op0);
6770 OutOps.push_back(Op1);
6771 OutOps.push_back(Op2);
6772 OutOps.push_back(Op3);
6773 OutOps.push_back(Op4);
6779 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
6785 return new X86DAGToDAGISelLegacy(TM, OptLevel);
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
#define CASE(ATTRNAME, AANAME,...)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isSigned(unsigned int Opcode)
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static bool isFusableLoadOpStorePattern(StoreSDNode *StoreNode, SDValue StoredVal, SelectionDAG *CurDAG, LoadSDNode *&LoadNode, SDValue &InputChain)
static void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII)
Check if the instruction uses RIP relative addressing.
#define FROM_TO(FROM, TO)
#define GET_EGPR_IF_ENABLED(OPC)
static bool isLegalMaskCompare(SDNode *N, const X86Subtarget *Subtarget)
static bool foldMaskAndShiftToScale(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static bool foldMaskAndShiftToExtract(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM)
static bool needBWI(MVT VT)
static unsigned getVPTESTMOpc(MVT TestVT, bool IsTestN, bool FoldedLoad, bool FoldedBCast, bool Masked)
static bool foldMaskedShiftToBEXTR(SelectionDAG &DAG, SDValue N, uint64_t Mask, SDValue Shift, SDValue X, X86ISelAddressMode &AM, const X86Subtarget &Subtarget)
static bool mayUseCarryFlag(X86::CondCode CC)
static cl::opt< bool > EnablePromoteAnyextLoad("x86-promote-anyext-load", cl::init(true), cl::desc("Enable promoting aligned anyext load to wider load"), cl::Hidden)
static void moveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load, SDValue Call, SDValue OrigChain)
Replace the original chain operand of the call with load's chain operand and move load below the call...
#define GET_ND_IF_ENABLED(OPC)
#define VPTESTM_BROADCAST_CASES(SUFFIX)
static cl::opt< bool > AndImmShrink("x86-and-imm-shrink", cl::init(true), cl::desc("Enable setting constant bits to reduce size of mask immediates"), cl::Hidden)
static bool foldMaskedShiftToScaledMask(SelectionDAG &DAG, SDValue N, X86ISelAddressMode &AM)
#define VPTESTM_FULL_CASES(SUFFIX)
static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq)
Return true if call address is a load and it can be moved below CALLSEQ_START and the chains leading ...
static bool isDispSafeForFrameIndexOrRegBase(int64_t Val)
static bool isEndbrImm64(uint64_t Imm)
cl::opt< bool > IndirectBranchTracking("x86-indirect-branch-tracking", cl::init(false), cl::Hidden, cl::desc("Enable X86 indirect branch tracking pass."))
#define GET_ND_IF_ENABLED(OPC)
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countl_zero() const
The APInt version of std::countl_zero.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
bool isOne() const
Determine if this is a value of 1.
unsigned countr_one() const
Count the number of trailing one bits.
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI std::optional< ConstantRange > getAbsoluteSymbolRange() const
If this is an absolute symbol reference, returns the range of the symbol, otherwise returns std::null...
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
bool is128BitVector() const
Return true if this is a 128-bit vector type.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool is512BitVector() const
Return true if this is a 512-bit vector type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MVT getHalfNumVectorElementsVT() const
Return a VT for a vector type with the same element type but half the number of elements.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
bool isNonTemporal() const
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
int getNodeId() const
Return the unique node id.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
SDNodeFlags getFlags() const
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
op_iterator op_end() const
op_iterator op_begin() const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISelPass(std::unique_ptr< SelectionDAGISel > Selector)
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
static int getUninvalidatedNodeId(SDNode *N)
virtual bool runOnMachineFunction(MachineFunction &mf)
static void InvalidateNodeId(SDNode *N)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
void RepositionNode(allnodes_iterator Position, SDNode *N)
Move node N in the AllNodes list to be immediately before the given iterator Position.
ilist< SDNode >::iterator allnodes_iterator
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
unsigned getID() const
Return the register class ID number.
bool hasOneUse() const
Return true if there is exactly one use of this value.
X86ISelDAGToDAGPass(X86TargetMachine &TM)
size_t getPreallocatedIdForCallSite(const Value *CS)
bool isScalarFPTypeInSSEReg(EVT VT) const
Return true if the specified scalar FP type is computed in an SSE register, not on the X87 floating p...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ LOCAL_RECOVER
LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ X86
Windows x64, Windows Itanium (IA-64)
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ FST
This instruction implements a truncating store from FP stack slots.
@ CMPM
Vector comparison generating mask bits for fp and integer signed and unsigned data types.
@ CMP
X86 compare and logical compare instructions.
@ BLENDV
Dynamic (non-constant condition) vector blend where only the sign bits of the condition elements are ...
@ STRICT_CMPM
Vector comparison generating mask bits for fp and integer signed and unsigned data types.
@ NT_BRIND
BRIND node with NoTrack prefix.
@ FSETCCM
X86 FP SETCC, similar to above, but with output as an i1 mask and and a version with SAE.
@ FXOR
Bitwise logical XOR of floating point values.
@ BRCOND
X86 conditional branches.
@ CALL
These operations represent an abstract X86 call instruction, which includes a bunch of information.
@ FANDN
Bitwise logical ANDNOT of floating point values.
@ GlobalBaseReg
On Darwin, this node represents the result of the popl at function entry, used for PIC code.
@ FLD
This instruction implements an extending load to FP stack slots.
@ TC_RETURN
Tail call return.
@ FOR
Bitwise logical OR of floating point values.
@ Wrapper
A wrapper node for TargetConstantPool, TargetJumpTable, TargetExternalSymbol, TargetGlobalAddress,...
@ ANDNP
Bitwise Logical AND NOT of Packed FP values.
@ POP_FROM_X87_REG
The same as ISD::CopyFromReg except that this node makes it explicit that it may lower to an x87 FPU ...
@ FAND
Bitwise logical AND of floating point values.
@ CMOV
X86 conditional moves.
@ WrapperRIP
Special wrapper used under X86-64 PIC mode for RIP relative displacements.
int getCondSrcNoFromDesc(const MCInstrDesc &MCID)
Return the source operand # for condition code by MCID.
bool mayFoldLoad(SDValue Op, const X86Subtarget &Subtarget, bool AssumeSingleUse=false)
Check if Op is a load operation that could be folded into some other x86 instruction as a memory oper...
bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M, bool hasSymbolicDisplacement)
Returns true of the given offset can be fit into displacement field of the instruction.
bool isConstantSplat(SDValue Op, APInt &SplatVal, bool AllowPartialUndefs)
If Op is a constant whose elements are all the same constant or undefined, return true and return the...
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isa_and_nonnull(const Y &Val)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
unsigned M1(unsigned Val)
auto dyn_cast_or_null(const Y &Val)
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
FunctionPass * createX86ISelDag(X86TargetMachine &TM, CodeGenOptLevel OptLevel)
This pass converts a legalized DAG into a X86-specific DAG, ready for instruction scheduling.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
int popcount(T Value) noexcept
Count the number of set bits in a value.
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