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;
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 {
98 if (
BaseType != RegBase)
return false;
100 dyn_cast_or_null<RegisterSDNode>(Base_Reg.
getNode()))
101 return RegNode->getReg() == X86::RIP;
110#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
112 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
113 dbgs() <<
"Base_Reg ";
119 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
120 dbgs() <<
" Scale " << Scale <<
'\n'
128 dbgs() <<
" Disp " << Disp <<
'\n'
150 dbgs() <<
" JT" <<
JT <<
" Align" << Alignment.
value() <<
'\n';
170 bool IndirectTlsSegRefs;
173 X86DAGToDAGISel() =
delete;
177 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
183 "indirect-tls-seg-refs");
188 "OptForMinSize implies OptForSize");
200#include "X86GenDAGISel.inc"
205 bool foldOffsetIntoAddress(
uint64_t Offset, X86ISelAddressMode &AM);
206 bool matchLoadInAddress(
LoadSDNode *
N, X86ISelAddressMode &AM,
207 bool AllowSegmentRegForX32 =
false);
208 bool matchWrapper(
SDValue N, X86ISelAddressMode &AM);
209 bool matchAddress(
SDValue N, X86ISelAddressMode &AM);
210 bool matchVectorAddress(
SDValue N, X86ISelAddressMode &AM);
211 bool matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
214 bool matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
216 bool matchVectorAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
218 bool matchAddressBase(
SDValue N, X86ISelAddressMode &AM);
247 return tryFoldLoad(
P,
P,
N,
Base, Scale, Index, Disp, Segment);
255 bool isProfitableToFormMaskedOp(
SDNode *
N)
const;
260 std::vector<SDValue> &OutOps)
override;
262 void emitSpecialCodeForMain();
264 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
268 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
269 Base = CurDAG->getTargetFrameIndex(
270 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
271 else if (AM.Base_Reg.getNode())
274 Base = CurDAG->getRegister(0, VT);
276 Scale = getI8Imm(AM.Scale,
DL);
278#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
280 if (AM.NegateIndex) {
288 if (AM.IndexReg.getNode())
291 Index = CurDAG->getRegister(0, VT);
296 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(),
300 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
301 AM.Disp, AM.SymbolFlags);
303 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
304 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
305 }
else if (AM.MCSym) {
306 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
307 assert(AM.SymbolFlags == 0 &&
"oo");
308 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
309 }
else if (AM.JT != -1) {
310 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
311 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
312 }
else if (AM.BlockAddr)
313 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
316 Disp = CurDAG->getSignedTargetConstant(AM.Disp,
DL, MVT::i32);
318 if (AM.Segment.getNode())
319 Segment = AM.Segment;
321 Segment = CurDAG->getRegister(0, MVT::i16);
326 bool isAMXSDNode(
SDNode *
N)
const {
332 switch (
N->getOpcode()) {
335 case X86::PT2RPNTLVWZ0V:
336 case X86::PT2RPNTLVWZ0T1V:
337 case X86::PT2RPNTLVWZ1V:
338 case X86::PT2RPNTLVWZ1T1V:
339 case X86::PT2RPNTLVWZ0RSV:
340 case X86::PT2RPNTLVWZ0RST1V:
341 case X86::PT2RPNTLVWZ1RSV:
342 case X86::PT2RPNTLVWZ1RST1V:
345 for (
unsigned Idx = 0, E =
N->getNumValues();
Idx != E; ++
Idx) {
346 if (
N->getValueType(
Idx) == MVT::x86amx)
349 for (
unsigned Idx = 0, E =
N->getNumOperands();
Idx != E; ++
Idx) {
351 if (
Op.getValueType() == MVT::x86amx)
363 bool shouldAvoidImmediateInstFormsForSize(
SDNode *
N)
const {
369 if (!CurDAG->shouldOptForSize())
379 if (
User->isMachineOpcode()) {
402 auto *
C = dyn_cast<ConstantSDNode>(
N);
403 if (
C && isInt<8>(
C->getSExtValue()))
423 (RegNode = dyn_cast_or_null<RegisterSDNode>(
425 if ((RegNode->
getReg() == X86::ESP) ||
426 (RegNode->
getReg() == X86::RSP))
435 return (UseCount > 1);
440 return CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
445 return CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
450 return CurDAG->getTargetConstant(Imm,
DL, MVT::i64);
455 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
457 MVT VecVT =
N->getOperand(0).getSimpleValueType();
463 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
465 MVT VecVT =
N->getSimpleValueType(0);
469 SDValue getPermuteVINSERTCommutedImmediate(
SDNode *
N,
unsigned VecWidth,
471 assert(VecWidth == 128 &&
"Unexpected vector width");
473 MVT VecVT =
N->getSimpleValueType(0);
475 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
478 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
483 MVT VT =
N->getSimpleValueType(0);
486 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
488 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
489 if (VT == MVT::i64) {
491 CurDAG->getMachineNode(
492 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
493 CurDAG->getTargetConstant(0, dl, MVT::i64), Zero,
494 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
499 unsigned Opcode =
N->getOpcode();
501 "Unexpected opcode for SBB materialization");
502 unsigned FlagOpIndex = Opcode ==
X86ISD::SBB ? 2 : 1;
504 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
505 N->getOperand(FlagOpIndex),
SDValue());
509 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
510 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
511 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
513 CurDAG->getMachineNode(Opc, dl, VTs,
514 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
520 bool isUnneededShiftMask(
SDNode *
N,
unsigned Width)
const {
522 const APInt &Val =
N->getConstantOperandAPInt(1);
527 APInt Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
528 return Mask.countr_one() >= Width;
534 SDNode *getGlobalBaseReg();
545 return Subtarget->getInstrInfo();
558 bool isSExtAbsoluteSymbolRef(
unsigned Width,
SDNode *
N)
const;
562 if (!
N->isNonTemporal())
565 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
567 if (
N->getAlign().value() < StoreSize)
576 return Subtarget->hasSSE41();
578 return Subtarget->hasAVX2();
580 return Subtarget->hasAVX512();
584 bool foldLoadStoreIntoMemOperand(
SDNode *
Node);
587 bool shrinkAndImmediate(
SDNode *
N);
588 bool isMaskZeroExtended(
SDNode *
N)
const;
589 bool tryShiftAmountMod(
SDNode *
N);
590 bool tryShrinkShlLogicImm(
SDNode *
N);
596 bool tryMatchBitSelect(
SDNode *
N);
598 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
600 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
604 bool tryOptimizeRem8Extend(
SDNode *
N);
606 bool onlyUsesZeroFlag(
SDValue Flags)
const;
607 bool hasNoSignFlagUses(
SDValue Flags)
const;
608 bool hasNoCarryFlagUses(
SDValue Flags)
const;
617 ID,
std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
621char X86DAGToDAGISelLegacy::ID = 0;
628 unsigned Opcode =
N->getOpcode();
635 EVT OpVT =
N->getOperand(0).getValueType();
639 OpVT =
N->getOperand(1).getValueType();
641 return Subtarget->hasVLX();
655bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
668 if (OptLevel == CodeGenOptLevel::None)
678 if (useNonTemporalLoad(cast<LoadSDNode>(
N)))
683 switch (
U->getOpcode()) {
709 if (
auto *Imm = dyn_cast<ConstantSDNode>(Op1)) {
710 if (
Imm->getAPIntValue().isSignedIntN(8))
719 Imm->getAPIntValue().getBitWidth() == 64 &&
720 Imm->getAPIntValue().isIntN(32))
727 (
Imm->getAPIntValue() == UINT8_MAX ||
728 Imm->getAPIntValue() == UINT16_MAX ||
729 Imm->getAPIntValue() == UINT32_MAX))
735 (-
Imm->getAPIntValue()).isSignedIntN(8))
739 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
740 hasNoCarryFlagUses(
SDValue(U, 1)))
765 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
769 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
777 auto *
C = dyn_cast<ConstantSDNode>(U0.
getOperand(0));
778 if (
C &&
C->getSExtValue() == -2)
783 auto *
C = dyn_cast<ConstantSDNode>(U1.
getOperand(0));
784 if (
C &&
C->getSExtValue() == -2)
798 if (isa<ConstantSDNode>(
U->getOperand(1)))
819bool X86DAGToDAGISel::isProfitableToFormMaskedOp(
SDNode *
N)
const {
822 "Unexpected opcode!");
827 return N->getOperand(1).hasOneUse();
836 if (Chain.
getNode() == Load.getNode())
840 "Unexpected chain operand");
854 Load.getOperand(1), Load.getOperand(2));
858 Ops.
append(Call->op_begin() + 1, Call->op_end());
872 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
874 auto *LD = dyn_cast<LoadSDNode>(Callee.getNode());
892 if (isa<MemSDNode>(Chain.
getNode()) &&
893 cast<MemSDNode>(Chain.
getNode())->writeMem())
899 Callee.getValue(1).hasOneUse())
907 if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
910 uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
911 0x65, 0x66, 0x67, 0xf0, 0xf2};
914 uint8_t Byte = (Imm >> i) & 0xFF;
926 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
929void X86DAGToDAGISel::PreprocessISelDAG() {
930 bool MadeChange =
false;
932 E = CurDAG->allnodes_end();
I != E; ) {
951 MVT VT =
N->getSimpleValueType(0);
952 int64_t
Imm = cast<ConstantSDNode>(
N)->getSExtValue();
953 int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
958 "cf-protection-branch");
961 SDValue Complement = CurDAG->getConstant(~Imm, dl, VT,
false,
true);
962 Complement = CurDAG->getNOT(dl, Complement, VT);
964 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Complement);
974 if (
N->getOpcode() ==
X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
976 N->getOperand(0),
N->getOperand(1));
978 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1002 auto mayPreventLoadFold = [&]() {
1004 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
1005 !
N->getOperand(1).hasOneUse();
1008 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
1014 MVT VT =
N->getSimpleValueType(0);
1022 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
1024 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1031 switch (
N->getOpcode()) {
1033 MVT VT =
N->getSimpleValueType(0);
1035 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1042 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1045 CurDAG->getIntPtrConstant(Index, dl));
1048 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1057 MVT VT =
N->getSimpleValueType(0);
1059 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1061 auto *MemNode = cast<MemSDNode>(
N);
1063 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1064 SDValue Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1065 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1067 MemNode->getMemOperand());
1070 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1073 CurDAG->getIntPtrConstant(Index, dl));
1077 CurDAG->ReplaceAllUsesWith(
N, To);
1088 auto *Ld = cast<LoadSDNode>(
N);
1089 MVT VT =
N->getSimpleValueType(0);
1097 SDValue Chain = Ld->getChain();
1099 auto *UserLd = dyn_cast<LoadSDNode>(
User);
1100 MVT UserVT =
User->getSimpleValueType(0);
1102 UserLd->getBasePtr() ==
Ptr && UserLd->getChain() == Chain &&
1103 !
User->hasAnyUseOfValue(1) &&
1117 CurDAG->getIntPtrConstant(0, dl));
1118 SDValue Res = CurDAG->getBitcast(VT, Extract);
1122 CurDAG->ReplaceAllUsesWith(
N, To);
1131 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1132 if (EleVT == MVT::i1)
1135 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1136 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1137 "We can't replace VSELECT with BLENDV in vXi16!");
1139 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1142 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1143 CurDAG->getTargetConstant(0xCA,
SDLoc(
N), MVT::i8));
1146 N->getOperand(0),
N->getOperand(1),
1150 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1163 if (!
N->getSimpleValueType(0).isVector())
1167 switch (
N->getOpcode()) {
1177 if (
N->isStrictFPOpcode())
1179 CurDAG->getNode(NewOpc,
SDLoc(
N), {
N->getValueType(0), MVT::Other},
1180 {
N->getOperand(0),
N->getOperand(1)});
1183 CurDAG->getNode(NewOpc,
SDLoc(
N),
N->getValueType(0),
1186 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1196 if (!
N->getValueType(0).isVector())
1200 switch (
N->getOpcode()) {
1206 SDValue Res = CurDAG->getNode(NewOpc,
SDLoc(
N),
N->getValueType(0),
1207 N->getOperand(0),
N->getOperand(1));
1209 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1218 if (!
N->getValueType(0).isVector())
1222 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1224 "Unexpected opcode for mask vector!");
1232 SDValue Res = CurDAG->getNode(NewOpc,
SDLoc(
N),
N->getValueType(0),
1235 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1255 switch (
N->getOpcode()) {
1271 bool IsStrict =
N->isStrictFPOpcode();
1275 {
N->getValueType(0), MVT::Other},
1276 {
N->getOperand(0),
N->getOperand(1),
1277 CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
1281 CurDAG->getTargetConstant(Imm, dl, MVT::i32));
1283 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1294 MVT VT =
N->getSimpleValueType(0);
1295 if (VT.
isVector() || VT == MVT::f128)
1298 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1299 : VT == MVT::f32 ? MVT::v4f32
1309 if (Subtarget->hasSSE2()) {
1314 switch (
N->getOpcode()) {
1321 Res = CurDAG->getNode(Opc, dl, IntVT, Op0, Op1);
1324 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1327 CurDAG->getIntPtrConstant(0, dl));
1329 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1336 if (OptLevel != CodeGenOptLevel::None &&
1339 !Subtarget->useIndirectThunkCalls() &&
1340 ((
N->getOpcode() ==
X86ISD::CALL && !Subtarget->slowTwoMemOps()) ||
1342 (Subtarget->is64Bit() ||
1343 !getTargetMachine().isPositionIndependent())))) {
1382 switch (
N->getOpcode()) {
1387 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1388 MVT DstVT =
N->getSimpleValueType(0);
1400 if (SrcIsSSE && DstIsSSE)
1403 if (!SrcIsSSE && !DstIsSSE) {
1408 if (
N->getConstantOperandVal(1))
1416 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1417 int SPFI = cast<FrameIndexSDNode>(MemTmp)->getIndex();
1425 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1427 MemTmp, MPI, MemVT);
1434 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1443 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1444 MVT DstVT =
N->getSimpleValueType(0);
1456 if (SrcIsSSE && DstIsSSE)
1459 if (!SrcIsSSE && !DstIsSSE) {
1464 if (
N->getConstantOperandVal(2))
1472 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1473 int SPFI = cast<FrameIndexSDNode>(MemTmp)->getIndex();
1483 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1484 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1488 if (
N->getFlags().hasNoFPExcept()) {
1490 Flags.setNoFPExcept(
true);
1491 Store->setFlags(Flags);
1494 assert(SrcVT == MemVT &&
"Unexpected VT!");
1495 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1500 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1502 Result = CurDAG->getMemIntrinsicNode(
1505 if (
N->getFlags().hasNoFPExcept()) {
1507 Flags.setNoFPExcept(
true);
1511 assert(DstVT == MemVT &&
"Unexpected VT!");
1512 Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
1520 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1534 CurDAG->RemoveDeadNodes();
1538bool X86DAGToDAGISel::tryOptimizeRem8Extend(
SDNode *
N) {
1539 unsigned Opc =
N->getMachineOpcode();
1540 if (Opc != X86::MOVZX32rr8 && Opc != X86::MOVSX32rr8 &&
1541 Opc != X86::MOVSX64rr8)
1553 unsigned ExpectedOpc = Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1554 : X86::MOVSX32rr8_NOREX;
1559 if (Opc == X86::MOVSX64rr8) {
1564 ReplaceUses(
N, Extend);
1573void X86DAGToDAGISel::PostprocessISelDAG() {
1575 if (
TM.getOptLevel() == CodeGenOptLevel::None)
1580 bool MadeChange =
false;
1581 while (Position != CurDAG->allnodes_begin()) {
1584 if (
N->use_empty() || !
N->isMachineOpcode())
1587 if (tryOptimizeRem8Extend(
N)) {
1592 unsigned Opc =
N->getMachineOpcode();
1603 case X86::CTEST16rr:
1604 case X86::CTEST32rr:
1605 case X86::CTEST64rr: {
1606 auto &Op0 =
N->getOperand(0);
1611#define CASE_ND(OP) \
1614 switch (
And.getMachineOpcode()) {
1621 if (
And->hasAnyUseOfValue(1))
1624 Ops[0] =
And.getOperand(0);
1625 Ops[1] =
And.getOperand(1);
1627 CurDAG->getMachineNode(Opc,
SDLoc(
N), MVT::i32, Ops);
1628 ReplaceUses(
N,
Test);
1636 if (
And->hasAnyUseOfValue(1))
1639 bool IsCTESTCC = X86::isCTESTCC(Opc);
1640#define FROM_TO(A, B) \
1641 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1643 switch (
And.getMachineOpcode()) {
1653 And.getOperand(3),
And.getOperand(4),
1654 And.getOperand(5),
And.getOperand(0)};
1667 NewOpc,
SDLoc(
N), MVT::i32, MVT::Other, Ops);
1668 CurDAG->setNodeMemRefs(
1669 Test, cast<MachineSDNode>(
And.getNode())->memoperands());
1681 case X86::KORTESTBkk:
1682 case X86::KORTESTWkk:
1683 case X86::KORTESTDkk:
1684 case X86::KORTESTQkk: {
1686 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1701#define FROM_TO(A, B) \
1713 if (NewOpc == X86::KTESTWkk && !Subtarget->hasDQI())
1718 ReplaceUses(
N, KTest);
1723 case TargetOpcode::SUBREG_TO_REG: {
1724 unsigned SubRegIdx =
N->getConstantOperandVal(2);
1725 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1742 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1743 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1744 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1745 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1746 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1747 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1748 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1749 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1754 if (!
In.isMachineOpcode() ||
1755 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1760 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1768 CurDAG->UpdateNodeOperands(
N,
N->getOperand(0), In,
N->getOperand(2));
1775 CurDAG->RemoveDeadNodes();
1780void X86DAGToDAGISel::emitSpecialCodeForMain() {
1781 if (Subtarget->isTargetCygMing()) {
1783 auto &
DL = CurDAG->getDataLayout();
1786 CLI.setChain(CurDAG->getRoot())
1788 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1792 CurDAG->setRoot(
Result.second);
1796void X86DAGToDAGISel::emitFunctionEntryCode() {
1799 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1800 emitSpecialCodeForMain();
1810 return isInt<31>(Val);
1814 X86ISelAddressMode &AM) {
1819 int64_t Val = AM.Disp +
Offset;
1822 if (Val != 0 && (AM.ES || AM.MCSym))
1826 if (Subtarget->is64Bit()) {
1829 AM.hasSymbolicDisplacement()))
1833 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1852 if (Subtarget->isTarget64BitILP32() &&
1854 !AM.hasBaseOrIndexReg())
1864bool X86DAGToDAGISel::matchLoadInAddress(
LoadSDNode *
N, X86ISelAddressMode &AM,
1865 bool AllowSegmentRegForX32) {
1877 if (
isNullConstant(Address) && AM.Segment.getNode() ==
nullptr &&
1878 !IndirectTlsSegRefs &&
1879 (Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() ||
1880 Subtarget->isTargetFuchsia())) {
1881 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1883 switch (
N->getPointerInfo().getAddrSpace()) {
1885 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1888 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1901bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1904 if (AM.hasSymbolicDisplacement())
1907 bool IsRIPRelTLS =
false;
1925 if (IsRIPRel && AM.hasBaseOrIndexReg())
1929 X86ISelAddressMode Backup = AM;
1933 if (
auto *
G = dyn_cast<GlobalAddressSDNode>(N0)) {
1934 AM.GV =
G->getGlobal();
1935 AM.SymbolFlags =
G->getTargetFlags();
1937 }
else if (
auto *CP = dyn_cast<ConstantPoolSDNode>(N0)) {
1938 AM.CP =
CP->getConstVal();
1939 AM.Alignment =
CP->getAlign();
1940 AM.SymbolFlags =
CP->getTargetFlags();
1942 }
else if (
auto *S = dyn_cast<ExternalSymbolSDNode>(N0)) {
1943 AM.ES = S->getSymbol();
1944 AM.SymbolFlags = S->getTargetFlags();
1945 }
else if (
auto *S = dyn_cast<MCSymbolSDNode>(N0)) {
1946 AM.MCSym = S->getMCSymbol();
1947 }
else if (
auto *J = dyn_cast<JumpTableSDNode>(N0)) {
1948 AM.JT = J->getIndex();
1949 AM.SymbolFlags = J->getTargetFlags();
1950 }
else if (
auto *BA = dyn_cast<BlockAddressSDNode>(N0)) {
1951 AM.BlockAddr = BA->getBlockAddress();
1952 AM.SymbolFlags = BA->getTargetFlags();
1953 Offset = BA->getOffset();
1958 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1959 TM.isLargeGlobalValue(AM.GV)) {
1964 if (foldOffsetIntoAddress(
Offset, AM)) {
1970 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
1978bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
1979 if (matchAddressRecursively(
N, AM, 0))
1986 if (Subtarget->isTarget64BitILP32() &&
1987 AM.BaseType == X86ISelAddressMode::RegBase &&
1988 AM.Base_Reg.getNode() !=
nullptr && AM.IndexReg.getNode() ==
nullptr) {
1989 SDValue Save_Base_Reg = AM.Base_Reg;
1990 if (
auto *LoadN = dyn_cast<LoadSDNode>(Save_Base_Reg)) {
1992 if (matchLoadInAddress(LoadN, AM,
true))
1993 AM.Base_Reg = Save_Base_Reg;
1999 if (AM.Scale == 2 &&
2000 AM.BaseType == X86ISelAddressMode::RegBase &&
2001 AM.Base_Reg.getNode() ==
nullptr) {
2002 AM.Base_Reg = AM.IndexReg;
2009 (!AM.GV || !
TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
2010 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
2011 AM.Base_Reg.getNode() ==
nullptr && AM.IndexReg.getNode() ==
nullptr &&
2020 if (isa_and_nonnull<Function>(AM.GV) && AM.Disp < -16 * 1024 * 1024)
2023 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
2029bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
2035 X86ISelAddressMode Backup = AM;
2036 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
2037 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
2042 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
2044 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2051 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2052 !AM.Base_Reg.getNode() &&
2053 !AM.IndexReg.getNode()) {
2054 N = Handle.getValue();
2055 AM.Base_Reg =
N.getOperand(0);
2056 AM.IndexReg =
N.getOperand(1);
2060 N = Handle.getValue();
2070 if (
N->getNodeId() == -1 ||
2090 X86ISelAddressMode &AM) {
2097 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2098 Mask != (0xffu << ScaleLog))
2101 MVT XVT =
X.getSimpleValueType();
2102 MVT VT =
N.getSimpleValueType();
2127 AM.Scale = (1 << ScaleLog);
2135 X86ISelAddressMode &AM) {
2141 int64_t Mask = cast<ConstantSDNode>(
N->getOperand(1))->getSExtValue();
2146 bool FoundAnyExtend =
false;
2150 FoundAnyExtend =
true;
2168 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2171 MVT VT =
N.getSimpleValueType();
2173 if (FoundAnyExtend) {
2194 AM.Scale = 1 << ShiftAmt;
2195 AM.IndexReg = NewAnd;
2229 X86ISelAddressMode &AM) {
2235 unsigned MaskIdx, MaskLen;
2238 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2244 unsigned AMShiftAmt = MaskIdx;
2248 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2252 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2253 if (MaskLZ < ScaleDown)
2255 MaskLZ -= ScaleDown;
2263 bool ReplacingAnyExtend =
false;
2265 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2266 X.getOperand(0).getSimpleValueType().getSizeInBits();
2269 X =
X.getOperand(0);
2270 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2271 ReplacingAnyExtend =
true;
2273 APInt MaskedHighBits =
2280 MVT VT =
N.getSimpleValueType();
2281 if (ReplacingAnyExtend) {
2282 assert(
X.getValueType() != VT);
2289 MVT XVT =
X.getSimpleValueType();
2310 AM.Scale = 1 << AMShiftAmt;
2311 AM.IndexReg = NewExt;
2321 X86ISelAddressMode &AM,
2329 if (!Subtarget.hasTBM() &&
2330 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2334 unsigned MaskIdx, MaskLen;
2342 unsigned AMShiftAmt = MaskIdx;
2346 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2348 MVT XVT =
X.getSimpleValueType();
2349 MVT VT =
N.getSimpleValueType();
2374 AM.Scale = 1 << AMShiftAmt;
2375 AM.IndexReg = NewExt;
2382 X86ISelAddressMode &AM,
2384 assert(AM.IndexReg.getNode() ==
nullptr &&
"IndexReg already matched");
2385 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2386 "Illegal index scale");
2392 EVT VT =
N.getValueType();
2393 unsigned Opc =
N.getOpcode();
2396 if (CurDAG->isBaseWithConstantOffset(
N)) {
2397 auto *AddVal = cast<ConstantSDNode>(
N.getOperand(1));
2399 if (!foldOffsetIntoAddress(
Offset, AM))
2400 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2404 if (Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2405 if (AM.Scale <= 4) {
2407 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2413 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2414 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2415 if ((AM.Scale * ScaleAmt) <= 8) {
2416 AM.Scale *= ScaleAmt;
2417 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2425 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2427 if (CurDAG->isBaseWithConstantOffset(Src)) {
2428 SDValue AddSrc = Src.getOperand(0);
2429 auto *AddVal = cast<ConstantSDNode>(Src.getOperand(1));
2430 int64_t
Offset = AddVal->getSExtValue();
2433 SDValue ExtSrc = CurDAG->getNode(Opc,
DL, VT, AddSrc);
2439 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2440 CurDAG->RemoveDeadNode(
N.getNode());
2452 unsigned SrcOpc = Src.getOpcode();
2453 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2454 CurDAG->isADDLike(Src,
true)) &&
2456 if (CurDAG->isBaseWithConstantOffset(Src)) {
2457 SDValue AddSrc = Src.getOperand(0);
2459 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2470 if ((AM.Scale * ScaleAmt) <= 8 &&
2472 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2473 AM.Scale *= ScaleAmt;
2474 SDValue ExtShVal = CurDAG->getNode(Opc,
DL, VT, ShVal);
2483 SDValue ExtSrc = CurDAG->getNode(Opc,
DL, VT, AddSrc);
2485 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2489 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2490 CurDAG->RemoveDeadNode(
N.getNode());
2491 return Res ? Res : ExtSrc;
2501bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2505 dbgs() <<
"MatchAddress: ";
2510 return matchAddressBase(
N, AM);
2515 if (AM.isRIPRelative()) {
2519 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2522 if (
auto *Cst = dyn_cast<ConstantSDNode>(
N))
2523 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2528 switch (
N.getOpcode()) {
2531 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2532 if (
const auto *ESNode = dyn_cast<MCSymbolSDNode>(
N.getOperand(0))) {
2534 AM.MCSym = ESNode->getMCSymbol();
2540 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
2541 if (!foldOffsetIntoAddress(Val, AM))
2548 if (!matchWrapper(
N, AM))
2553 if (!matchLoadInAddress(cast<LoadSDNode>(
N), AM))
2558 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2559 AM.Base_Reg.getNode() ==
nullptr &&
2561 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2562 AM.Base_FrameIndex = cast<FrameIndexSDNode>(
N)->getIndex();
2568 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
2571 if (
auto *CN = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
2572 unsigned Val = CN->getZExtValue();
2577 if (Val == 1 || Val == 2 || Val == 3) {
2579 AM.Scale = 1 << Val;
2580 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2588 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
break;
2592 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2593 "Unexpected value size!");
2602 if (!isa<ConstantSDNode>(
N.getOperand(1)) ||
2603 !isa<ConstantSDNode>(
And.getOperand(1)))
2605 uint64_t Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2617 if (
N.getResNo() != 0)
break;
2622 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2623 AM.Base_Reg.getNode() ==
nullptr &&
2624 AM.IndexReg.getNode() ==
nullptr) {
2625 if (
auto *CN = dyn_cast<ConstantSDNode>(
N.getOperand(1)))
2626 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2627 CN->getZExtValue() == 9) {
2628 AM.Scale =
unsigned(CN->getZExtValue())-1;
2639 auto *AddVal = cast<ConstantSDNode>(MulVal.
getOperand(1));
2640 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2641 if (foldOffsetIntoAddress(Disp, AM))
2642 Reg =
N.getOperand(0);
2644 Reg =
N.getOperand(0);
2647 AM.IndexReg = AM.Base_Reg =
Reg;
2666 X86ISelAddressMode Backup = AM;
2667 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2668 N = Handle.getValue();
2672 N = Handle.getValue();
2674 if (AM.IndexReg.getNode() || AM.isRIPRelative()) {
2689 RHS.getOperand(0).getValueType() == MVT::i32))
2693 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.getNode() &&
2694 !AM.Base_Reg.getNode()->hasOneUse()) ||
2695 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2699 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2700 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2701 (AM.Segment.getNode() && !Backup.Segment.getNode()) >= 2)
2713 AM.NegateIndex =
true;
2721 if (!CurDAG->isADDLike(
N))
2725 if (!matchAdd(
N, AM,
Depth))
2734 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
break;
2738 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2739 "Unexpected value size!");
2741 if (!isa<ConstantSDNode>(
N.getOperand(1)))
2744 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2773 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
2781 if (
SDValue Index = matchIndexRecursively(
N, AM,
Depth + 1))
2783 AM.IndexReg =
Index;
2789 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2790 if (
auto *MaskC = dyn_cast<ConstantSDNode>(Src.getOperand(1))) {
2791 Mask = MaskC->getAPIntValue();
2792 Src = Src.getOperand(0);
2795 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2797 SDValue ShlSrc = Src.getOperand(0);
2798 SDValue ShlAmt = Src.getOperand(1);
2799 auto *ShAmtC = dyn_cast<ConstantSDNode>(ShlAmt);
2802 unsigned ShAmtV = ShAmtC->getZExtValue();
2810 if (!Src->getFlags().hasNoUnsignedWrap() &&
2811 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2819 MVT VT =
N.getSimpleValueType();
2823 if (!
Mask.isAllOnes()) {
2824 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2826 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2833 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2834 CurDAG->RemoveDeadNode(
N.getNode());
2837 AM.Scale = 1 << ShAmtV;
2841 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2845 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2848 Src.getOperand(0), AM))
2853 Src.getOperand(0), AM))
2858 Src.getOperand(0), AM, *Subtarget))
2866 return matchAddressBase(
N, AM);
2871bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2873 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.getNode()) {
2875 if (!AM.IndexReg.getNode()) {
2886 AM.BaseType = X86ISelAddressMode::RegBase;
2891bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2892 X86ISelAddressMode &AM,
2896 dbgs() <<
"MatchVectorAddress: ";
2901 return matchAddressBase(
N, AM);
2904 switch (
N.getOpcode()) {
2906 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
2907 if (!foldOffsetIntoAddress(Val, AM))
2912 if (!matchWrapper(
N, AM))
2920 X86ISelAddressMode Backup = AM;
2921 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2922 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2928 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2930 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2935 N = Handle.getValue();
2940 return matchAddressBase(
N, AM);
2946bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2947 return matchVectorAddressRecursively(
N, AM, 0);
2955 X86ISelAddressMode AM;
2961 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2963 AM.IndexReg = IndexOp;
2967 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
2969 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
2971 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
2977 if (matchVectorAddress(BasePtr, AM))
2980 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
2994 X86ISelAddressMode AM;
3006 unsigned AddrSpace =
3007 cast<MemSDNode>(Parent)->getPointerInfo().getAddrSpace();
3009 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
3011 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
3013 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
3018 MVT VT =
N.getSimpleValueType();
3020 if (matchAddress(
N, AM))
3023 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3039 N =
N.getOperand(0);
3054 const GlobalValue *GV = cast<GlobalAddressSDNode>(
N)->getGlobal();
3056 return CR->getUnsignedMax().ult(1ull << 32);
3058 return !
TM.isLargeGlobalValue(GV);
3067 if (!selectLEAAddr(
N,
Base, Scale, Index, Disp, Segment))
3070 auto *
RN = dyn_cast<RegisterSDNode>(
Base);
3071 if (RN &&
RN->getReg() == 0)
3072 Base = CurDAG->getRegister(0, MVT::i64);
3073 else if (
Base.getValueType() == MVT::i32 && !isa<FrameIndexSDNode>(
Base)) {
3077 Base = CurDAG->getTargetInsertSubreg(X86::sub_32bit,
DL, MVT::i64, ImplDef,
3081 RN = dyn_cast<RegisterSDNode>(Index);
3082 if (RN &&
RN->getReg() == 0)
3083 Index = CurDAG->getRegister(0, MVT::i64);
3086 "Expect to be extending 32-bit registers for use in LEA");
3089 Index = CurDAG->getTargetInsertSubreg(X86::sub_32bit,
DL, MVT::i64, ImplDef,
3098bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3102 X86ISelAddressMode AM;
3106 MVT VT =
N.getSimpleValueType();
3111 SDValue T = CurDAG->getRegister(0, MVT::i32);
3113 if (matchAddress(
N, AM))
3118 unsigned Complexity = 0;
3119 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.getNode())
3121 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3124 if (AM.IndexReg.getNode())
3137 if (AM.hasSymbolicDisplacement()) {
3139 if (Subtarget->is64Bit())
3149 auto isMathWithFlags = [](
SDValue V) {
3150 switch (
V.getOpcode()) {
3171 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3179 if (Complexity <= 2)
3182 getAddressOperands(AM,
DL, VT,
Base, Scale, Index, Disp, Segment);
3193 X86ISelAddressMode AM;
3194 if (
auto *GA = dyn_cast<GlobalAddressSDNode>(
N)) {
3195 AM.GV = GA->getGlobal();
3196 AM.Disp += GA->getOffset();
3197 AM.SymbolFlags = GA->getTargetFlags();
3199 auto *SA = cast<ExternalSymbolSDNode>(
N);
3200 AM.ES = SA->getSymbol();
3201 AM.SymbolFlags = SA->getTargetFlags();
3204 if (Subtarget->is32Bit()) {
3206 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3209 MVT VT =
N.getSimpleValueType();
3210 getAddressOperands(AM,
SDLoc(
N), VT,
Base, Scale, Index, Disp, Segment);
3218 EVT VT =
N.getValueType();
3219 bool WasTruncated =
false;
3221 WasTruncated =
true;
3222 N =
N.getOperand(0);
3231 unsigned Opc =
N.getOperand(0)->getOpcode();
3233 Op =
N.getOperand(0);
3236 return !WasTruncated;
3240 auto *GA = cast<GlobalAddressSDNode>(
N.getOperand(0));
3241 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3242 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3246 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
SDLoc(
N), VT,
3247 GA->getOffset(), GA->getTargetFlags());
3255 assert(Root &&
P &&
"Unknown root/parent nodes");
3257 !IsProfitableToFold(
N,
P, Root) ||
3258 !IsLegalToFold(
N,
P, Root, OptLevel))
3261 return selectAddr(
N.getNode(),
3262 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3269 assert(Root &&
P &&
"Unknown root/parent nodes");
3271 !IsProfitableToFold(
N,
P, Root) ||
3272 !IsLegalToFold(
N,
P, Root, OptLevel))
3275 return selectAddr(
N.getNode(),
3276 N.getOperand(1),
Base, Scale, Index, Disp, Segment);
3282SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3283 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
3285 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3288bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width,
SDNode *
N)
const {
3290 N =
N->getOperand(0).getNode();
3294 auto *GA = dyn_cast<GlobalAddressSDNode>(
N->getOperand(0));
3298 auto *GV = GA->getGlobal();
3301 return CR->getSignedMin().sge(-1ull << Width) &&
3302 CR->getSignedMax().slt(1ull << Width);
3307 return Width == 32 && !
TM.isLargeGlobalValue(GV);
3311 assert(
N->isMachineOpcode() &&
"Unexpected node");
3312 unsigned Opc =
N->getMachineOpcode();
3313 const MCInstrDesc &MCID = getInstrInfo()->get(Opc);
3318 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3323bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3327 if (
Use.getResNo() !=
Flags.getResNo())
3332 cast<RegisterSDNode>(
User->
getOperand(1))->getReg() != X86::EFLAGS)
3337 if (FlagUse.getResNo() != 1)
3340 if (!FlagUse.getUser()->isMachineOpcode())
3360bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3364 if (
Use.getResNo() !=
Flags.getResNo())
3369 cast<RegisterSDNode>(
User->
getOperand(1))->getReg() != X86::EFLAGS)
3374 if (FlagUse.getResNo() != 1)
3377 if (!FlagUse.getUser()->isMachineOpcode())
3417 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3421 if (
Use.getResNo() !=
Flags.getResNo())
3425 unsigned UserOpc =
User->getOpcode();
3429 if (cast<RegisterSDNode>(
User->
getOperand(1))->getReg() != X86::EFLAGS)
3434 if (FlagUse.getResNo() != 1)
3437 if (!FlagUse.getUser()->isMachineOpcode())
3478 if (StoredVal.
getResNo() != 0)
return false;
3492 LoadNode = cast<LoadSDNode>(Load);
3495 if (!Load.hasOneUse())
3503 bool FoundLoad =
false;
3507 const unsigned int Max = 1024;
3549 if (Chain == Load.getValue(1)) {
3555 if (
Op == Load.getValue(1)) {
3571 if (
Op.getNode() != LoadNode)
3603bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(
SDNode *
Node) {
3604 auto *StoreNode = cast<StoreSDNode>(
Node);
3611 EVT MemVT = StoreNode->getMemoryVT();
3612 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3616 bool IsCommutable =
false;
3617 bool IsNegate =
false;
3631 IsCommutable =
true;
3635 unsigned LoadOpNo = IsNegate ? 1 : 0;
3639 LoadNode, InputChain)) {
3646 LoadNode, InputChain))
3651 if (!selectAddr(LoadNode, LoadNode->
getBasePtr(),
Base, Scale, Index, Disp,
3655 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3676 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3686 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
3690 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3693 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
3694 : SelectOpcode(
X86::DEC64m,
X86::DEC32m,
X86::DEC16m,
X86::DEC8m);
3707 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
3710 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
3713 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
3716 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
3719 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
3722 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
3725 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
3727 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
3733 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
3736 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
3739 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
3742 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
3745 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
3748 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
3751 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
3754 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
3761 unsigned NewOpc = SelectRegOpcode(Opc);
3766 if (
auto *OperandC = dyn_cast<ConstantSDNode>(Operand)) {
3767 int64_t OperandV = OperandC->getSExtValue();
3773 ((MemVT != MVT::i8 && !isInt<8>(OperandV) && isInt<8>(-OperandV)) ||
3774 (MemVT == MVT::i64 && !isInt<32>(OperandV) &&
3775 isInt<32>(-OperandV))) &&
3776 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3777 OperandV = -OperandV;
3781 if (MemVT != MVT::i64 || isInt<32>(OperandV)) {
3782 Operand = CurDAG->getSignedTargetConstant(OperandV,
SDLoc(
Node), MemVT);
3783 NewOpc = SelectImmOpcode(Opc);
3789 CurDAG->getCopyToReg(InputChain,
SDLoc(
Node), X86::EFLAGS,
3793 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
3794 Result = CurDAG->getMachineNode(NewOpc,
SDLoc(
Node), MVT::i32, MVT::Other,
3798 Segment, Operand, InputChain};
3799 Result = CurDAG->getMachineNode(NewOpc,
SDLoc(
Node), MVT::i32, MVT::Other,
3810 CurDAG->setNodeMemRefs(Result, MemOps);
3816 CurDAG->RemoveDeadNode(
Node);
3827bool X86DAGToDAGISel::matchBitExtract(
SDNode *
Node) {
3831 "Should be either an and-mask, or right-shift after clearing high bits.");
3834 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
3837 MVT NVT =
Node->getSimpleValueType(0);
3840 if (NVT != MVT::i32 && NVT != MVT::i64)
3848 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
3849 auto checkUses = [AllowExtraUsesByDefault](
3851 std::optional<bool> AllowExtraUses) {
3852 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
3853 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
3855 auto checkOneUse = [checkUses](
SDValue Op,
3856 std::optional<bool> AllowExtraUses =
3858 return checkUses(
Op, 1, AllowExtraUses);
3860 auto checkTwoUse = [checkUses](
SDValue Op,
3861 std::optional<bool> AllowExtraUses =
3863 return checkUses(
Op, 2, AllowExtraUses);
3866 auto peekThroughOneUseTruncation = [checkOneUse](
SDValue V) {
3868 assert(
V.getSimpleValueType() == MVT::i32 &&
3869 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
3870 "Expected i64 -> i32 truncation");
3871 V =
V.getOperand(0);
3877 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
3880 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
3886 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3891 NBits =
M0->getOperand(1);
3892 NegateNBits =
false;
3896 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](
SDValue V) {
3897 V = peekThroughOneUseTruncation(V);
3898 return CurDAG->MaskedValueIsAllOnes(
3904 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
3907 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
3910 if (!isAllOnes(
Mask->getOperand(1)))
3913 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3917 if (!isAllOnes(
M0->getOperand(0)))
3919 NBits =
M0->getOperand(1);
3920 NegateNBits =
false;
3926 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](
SDValue ShiftAmt,
3927 unsigned Bitwidth) {
3932 NBits = NBits.getOperand(0);
3937 auto *V0 = dyn_cast<ConstantSDNode>(NBits.getOperand(0));
3938 if (!V0 || V0->getZExtValue() != Bitwidth)
3940 NBits = NBits.getOperand(1);
3941 NegateNBits =
false;
3947 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
3950 Mask = peekThroughOneUseTruncation(Mask);
3951 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
3953 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
3960 if (!checkOneUse(
M1))
3962 canonicalizeShiftAmt(
M1, Bitwidth);
3967 return !NegateNBits;
3975 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
3976 AllowExtraUsesByDefault, &NegateNBits,
3989 canonicalizeShiftAmt(N1, Bitwidth);
3993 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
3994 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
4000 auto matchLowBitMask = [matchPatternA, matchPatternB,
4002 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
4006 X =
Node->getOperand(0);
4009 if (matchLowBitMask(Mask)) {
4013 if (!matchLowBitMask(Mask))
4017 X = CurDAG->getAllOnesConstant(
SDLoc(
Node), NVT);
4018 }
else if (!matchPatternD(
Node))
4023 if (NegateNBits && !Subtarget->hasBMI2())
4035 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
4038 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
4040 NBits =
SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
4041 MVT::i32, ImplDef, NBits, SRIdxVal),
4051 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4055 if (Subtarget->hasBMI2()) {
4057 if (NVT != MVT::i32) {
4065 SelectCode(Extract.
getNode());
4074 SDValue RealX = peekThroughOneUseTruncation(
X);
4080 MVT XVT =
X.getSimpleValueType();
4090 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4098 SDValue ShiftAmt =
X.getOperand(1);
4099 X =
X.getOperand(0);
4102 "Expected shift amount to be i8");
4106 SDValue OrigShiftAmt = ShiftAmt;
4111 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4116 if (XVT != MVT::i32) {
4131 SelectCode(Extract.
getNode());
4138 MVT NVT =
Node->getSimpleValueType(0);
4151 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4152 if (!PreferBEXTR && !Subtarget->hasBMI2())
4164 if (NVT != MVT::i32 && NVT != MVT::i64)
4168 auto *MaskCst = dyn_cast<ConstantSDNode>(N1);
4169 auto *ShiftCst = dyn_cast<ConstantSDNode>(N0->
getOperand(1));
4170 if (!MaskCst || !ShiftCst)
4178 uint64_t Shift = ShiftCst->getZExtValue();
4183 if (Shift == 8 && MaskSize == 8)
4194 if (!PreferBEXTR && MaskSize <= 32)
4198 unsigned ROpc, MOpc;
4200#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4202 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4206 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4211 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4212 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4218 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4219 if (Subtarget->hasTBM()) {
4220 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4221 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4223 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4229 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4230 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4236 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4237 if (tryFoldLoad(
Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4239 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4240 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4241 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
4245 CurDAG->setNodeMemRefs(NewNode, {cast<LoadSDNode>(Input)->getMemOperand()});
4247 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4252 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4256 CurDAG->getMachineNode(NewOpc, dl, NVT,
SDValue(NewNode, 0), ShAmt);
4263MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4264 bool MayFoldLoad,
const SDLoc &dl,
4269 auto *Val = cast<ConstantSDNode>(Imm)->getConstantIntValue();
4270 Imm = CurDAG->getTargetConstant(*Val,
SDLoc(
Node),
Imm.getValueType());
4273 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4274 if (MayFoldLoad && tryFoldLoad(
Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4275 SDValue Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4277 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4278 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
4282 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
4287 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4288 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs, Ops);
4295MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4296 bool MayFoldLoad,
const SDLoc &dl,
4302 auto *Val = cast<ConstantSDNode>(Imm)->getConstantIntValue();
4303 Imm = CurDAG->getTargetConstant(*Val,
SDLoc(
Node),
Imm.getValueType());
4306 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4307 if (MayFoldLoad && tryFoldLoad(
Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4308 SDValue Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4310 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4311 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
4316 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N2)->getMemOperand()});
4321 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4322 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs, Ops);
4327bool X86DAGToDAGISel::tryShiftAmountMod(
SDNode *
N) {
4328 EVT VT =
N->getValueType(0);
4335 unsigned Size = VT == MVT::i64 ? 64 : 32;
4337 SDValue OrigShiftAmt =
N->getOperand(1);
4338 SDValue ShiftAmt = OrigShiftAmt;
4353 auto *Add0C = dyn_cast<ConstantSDNode>(Add0);
4354 auto *Add1C = dyn_cast<ConstantSDNode>(Add1);
4357 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4361 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4362 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4366 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4375 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4376 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4382 Add0C->getZExtValue() != 0) {
4385 if (Add0C->getZExtValue() %
Size == 0)
4388 Add0C->getZExtValue() % 32 == 0) {
4396 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4400 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4422 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4429 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4430 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4434 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4436 if (UpdatedNode !=
N) {
4439 ReplaceNode(
N, UpdatedNode);
4446 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4454bool X86DAGToDAGISel::tryShrinkShlLogicImm(
SDNode *
N) {
4455 MVT NVT =
N->getSimpleValueType(0);
4456 unsigned Opcode =
N->getOpcode();
4464 auto *Cst = dyn_cast<ConstantSDNode>(N1);
4468 int64_t Val = Cst->getSExtValue();
4473 bool FoundAnyExtend =
false;
4477 FoundAnyExtend =
true;
4485 if (NVT != MVT::i32 && NVT != MVT::i64)
4488 auto *ShlCst = dyn_cast<ConstantSDNode>(Shift.
getOperand(1));
4492 uint64_t ShAmt = ShlCst->getZExtValue();
4496 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4497 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4502 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4506 ShiftedVal = (
uint64_t)Val >> ShAmt;
4507 if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
4510 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4513 ShiftedVal = Val >> ShAmt;
4514 if ((!isInt<8>(Val) && isInt<8>(ShiftedVal)) ||
4515 (!isInt<32>(Val) && isInt<32>(ShiftedVal)))
4519 ShiftedVal = (
uint64_t)Val >> ShAmt;
4520 if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
4527 if (!CanShrinkImmediate(ShiftedVal))
4537 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4543 NeededMask &= ~Cst->getAPIntValue();
4545 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4550 if (FoundAnyExtend) {
4556 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4558 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4567bool X86DAGToDAGISel::matchVPTERNLOG(
SDNode *Root,
SDNode *ParentA,
4571 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4572 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4574 auto tryFoldLoadOrBCast =
4577 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4583 L =
L.getOperand(0);
4590 auto *MemIntr = cast<MemIntrinsicSDNode>(L);
4591 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4595 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4598 bool FoldedLoad =
false;
4599 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4600 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4602 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4608 Imm = OldImm & 0xa5;
4609 if (OldImm & 0x02)
Imm |= 0x10;
4610 if (OldImm & 0x10)
Imm |= 0x02;
4611 if (OldImm & 0x08)
Imm |= 0x40;
4612 if (OldImm & 0x40)
Imm |= 0x08;
4613 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4619 Imm = OldImm & 0x99;
4620 if (OldImm & 0x02)
Imm |= 0x04;
4621 if (OldImm & 0x04)
Imm |= 0x02;
4622 if (OldImm & 0x20)
Imm |= 0x40;
4623 if (OldImm & 0x40)
Imm |= 0x20;
4628 SDValue TImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
4634 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4638 auto *MemIntr = cast<MemIntrinsicSDNode>(
C);
4639 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4640 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4642 bool UseD = EltSize == 32;
4644 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4646 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4648 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4654 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4656 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4658 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4663 SDValue Ops[] = {
A,
B, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, TImm,
C.getOperand(0)};
4664 MNode = CurDAG->getMachineNode(Opc,
DL, VTs, Ops);
4667 ReplaceUses(
C.getValue(1),
SDValue(MNode, 1));
4669 CurDAG->setNodeMemRefs(MNode, {cast<MemSDNode>(
C)->getMemOperand()});
4674 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
4676 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
4678 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
4682 MNode = CurDAG->getMachineNode(Opc,
DL, NVT, {
A,
B,
C, TImm});
4686 CurDAG->RemoveDeadNode(Root);
4692bool X86DAGToDAGISel::tryVPTERNLOG(
SDNode *
N) {
4693 MVT NVT =
N->getSimpleValueType(0);
4696 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
4707 auto getFoldableLogicOp = [](
SDValue Op) {
4710 Op =
Op.getOperand(0);
4712 if (!
Op.hasOneUse())
4715 unsigned Opc =
Op.getOpcode();
4724 if ((FoldableOp = getFoldableLogicOp(N1))) {
4726 }
else if ((FoldableOp = getFoldableLogicOp(N0))) {
4750 Parent =
Op.getNode();
4751 Op =
Op.getOperand(0);
4755 PeekThroughNot(
A, ParentA, TernlogMagicA);
4756 PeekThroughNot(
B, ParentB, TernlogMagicB);
4757 PeekThroughNot(
C, ParentC, TernlogMagicC);
4762 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
4763 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
4764 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
4768 switch (
N->getOpcode()) {
4772 Imm &= ~TernlogMagicA;
4774 Imm = ~(
Imm) & TernlogMagicA;
4781 return matchVPTERNLOG(
N, ParentA, ParentB, ParentC,
A,
B,
C, Imm);
4791bool X86DAGToDAGISel::shrinkAndImmediate(
SDNode *
And) {
4794 MVT VT =
And->getSimpleValueType(0);
4795 if (VT != MVT::i32 && VT != MVT::i64)
4798 auto *And1C = dyn_cast<ConstantSDNode>(
And->getOperand(1));
4807 APInt MaskVal = And1C->getAPIntValue();
4809 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
4813 if (VT == MVT::i64 && MaskLZ >= 32) {
4815 MaskVal = MaskVal.
trunc(32);
4820 APInt NegMaskVal = MaskVal | HighZeros;
4829 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
4830 NegMaskVal = NegMaskVal.
zext(64);
4831 HighZeros = HighZeros.
zext(64);
4837 KnownBits Known0 = CurDAG->computeKnownBits(And0);
4858 bool FoldedBCast,
bool Masked) {
4859#define VPTESTM_CASE(VT, SUFFIX) \
4862 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
4863 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
4866#define VPTESTM_BROADCAST_CASES(SUFFIX) \
4867default: llvm_unreachable("Unexpected VT!"); \
4868VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
4869VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
4870VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
4871VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
4872VPTESTM_CASE(v16i32, DZ##SUFFIX) \
4873VPTESTM_CASE(v8i64, QZ##SUFFIX)
4875#define VPTESTM_FULL_CASES(SUFFIX) \
4876VPTESTM_BROADCAST_CASES(SUFFIX) \
4877VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
4878VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
4879VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
4880VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
4881VPTESTM_CASE(v64i8, BZ##SUFFIX) \
4882VPTESTM_CASE(v32i16, WZ##SUFFIX)
4900#undef VPTESTM_FULL_CASES
4901#undef VPTESTM_BROADCAST_CASES
4907bool X86DAGToDAGISel::tryVPTESTM(
SDNode *Root,
SDValue Setcc,
4909 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
4959 if (tryFoldLoad(Root,
P, L,
Base, Scale, Index, Disp, Segment))
4964 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
4970 L =
L.getOperand(0);
4976 auto *MemIntr = cast<MemIntrinsicSDNode>(L);
4977 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
4980 return tryFoldBroadcast(Root,
P, L,
Base, Scale, Index, Disp, Segment);
4984 bool CanFoldLoads = Src0 != Src1;
4986 bool FoldedLoad =
false;
4987 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4989 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
4993 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
5002 bool IsMasked = InMask.
getNode() !=
nullptr;
5015 SDValue ImplDef =
SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
5017 Src0 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src0);
5020 Src1 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src1);
5025 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5026 InMask =
SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5027 dl, MaskVT, InMask, RC), 0);
5032 unsigned Opc =
getVPTESTMOpc(CmpVT, IsTestN, FoldedLoad, FoldedBCast,
5037 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
5040 SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5042 CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
5044 SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5046 CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
5052 CurDAG->setNodeMemRefs(CNode, {cast<MemSDNode>(Src1)->getMemOperand()});
5055 CNode = CurDAG->getMachineNode(Opc, dl, MaskVT, InMask, Src0, Src1);
5057 CNode = CurDAG->getMachineNode(Opc, dl, MaskVT, Src0, Src1);
5063 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5064 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5065 dl, ResVT,
SDValue(CNode, 0), RC);
5069 CurDAG->RemoveDeadNode(Root);
5075bool X86DAGToDAGISel::tryMatchBitSelect(
SDNode *
N) {
5078 MVT NVT =
N->getSimpleValueType(0);
5081 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5115 SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5124 MVT NVT =
Node->getSimpleValueType(0);
5125 unsigned Opcode =
Node->getOpcode();
5128 if (
Node->isMachineOpcode()) {
5130 Node->setNodeId(-1);
5137 unsigned IntNo =
Node->getConstantOperandVal(1);
5140 case Intrinsic::x86_encodekey128:
5141 case Intrinsic::x86_encodekey256: {
5142 if (!Subtarget->hasKL())
5148 case Intrinsic::x86_encodekey128:
5149 Opcode = X86::ENCODEKEY128;
5151 case Intrinsic::x86_encodekey256:
5152 Opcode = X86::ENCODEKEY256;
5157 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5159 if (Opcode == X86::ENCODEKEY256)
5160 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5164 Opcode, dl,
Node->getVTList(),
5165 {Node->getOperand(2), Chain, Chain.getValue(1)});
5166 ReplaceNode(
Node, Res);
5169 case Intrinsic::x86_tileloaddrs64_internal:
5170 case Intrinsic::x86_tileloaddrst164_internal:
5171 if (!Subtarget->hasAMXMOVRS())
5174 case Intrinsic::x86_tileloadd64_internal:
5175 case Intrinsic::x86_tileloaddt164_internal: {
5176 if (!Subtarget->hasAMXTILE())
5185 case Intrinsic::x86_tileloaddrs64_internal:
5186 Opc = X86::PTILELOADDRSV;
5188 case Intrinsic::x86_tileloaddrst164_internal:
5189 Opc = X86::PTILELOADDRST1V;
5191 case Intrinsic::x86_tileloadd64_internal:
5192 Opc = X86::PTILELOADDV;
5194 case Intrinsic::x86_tileloaddt164_internal:
5195 Opc = X86::PTILELOADDT1V;
5200 SDValue Scale = getI8Imm(1, dl);
5202 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5203 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5207 Node->getOperand(3),
5214 CNode = CurDAG->getMachineNode(Opc, dl, {MVT::x86amx, MVT::Other}, Ops);
5215 ReplaceNode(
Node, CNode);
5222 unsigned IntNo =
Node->getConstantOperandVal(1);
5225 case Intrinsic::x86_sse3_monitor:
5226 case Intrinsic::x86_monitorx:
5227 case Intrinsic::x86_clzero: {
5228 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5233 case Intrinsic::x86_sse3_monitor:
5234 if (!Subtarget->hasSSE3())
5236 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5238 case Intrinsic::x86_monitorx:
5239 if (!Subtarget->hasMWAITX())
5241 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5243 case Intrinsic::x86_clzero:
5244 if (!Subtarget->hasCLZERO())
5246 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5251 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5252 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5256 if (IntNo == Intrinsic::x86_sse3_monitor ||
5257 IntNo == Intrinsic::x86_monitorx) {
5259 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5262 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5267 MachineSDNode *CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other,
5269 ReplaceNode(
Node, CNode);
5275 case Intrinsic::x86_tilestored64_internal: {
5279 unsigned Opc = X86::PTILESTOREDV;
5282 SDValue Scale = getI8Imm(1, dl);
5284 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5285 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5289 Node->getOperand(3),
5295 Node->getOperand(6),
5297 CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
5298 ReplaceNode(
Node, CNode);
5301 case Intrinsic::x86_tileloaddrs64:
5302 case Intrinsic::x86_tileloaddrst164:
5303 if (!Subtarget->hasAMXMOVRS())
5306 case Intrinsic::x86_tileloadd64:
5307 case Intrinsic::x86_tileloaddt164:
5308 case Intrinsic::x86_tilestored64: {
5309 if (!Subtarget->hasAMXTILE())
5317 case Intrinsic::x86_tileloadd64: Opc = X86::PTILELOADD;
break;
5318 case Intrinsic::x86_tileloaddrs64:
5319 Opc = X86::PTILELOADDRS;
5321 case Intrinsic::x86_tileloaddt164: Opc = X86::PTILELOADDT1;
break;
5322 case Intrinsic::x86_tileloaddrst164:
5323 Opc = X86::PTILELOADDRST1;
5325 case Intrinsic::x86_tilestored64: Opc = X86::PTILESTORED;
break;
5328 unsigned TIndex =
Node->getConstantOperandVal(2);
5329 SDValue TReg = getI8Imm(TIndex, dl);
5331 SDValue Scale = getI8Imm(1, dl);
5333 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5334 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5337 if (Opc == X86::PTILESTORED) {
5339 CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
5342 CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
5344 ReplaceNode(
Node, CNode);
5347 case Intrinsic::x86_t2rpntlvwz0rs:
5348 case Intrinsic::x86_t2rpntlvwz0rst1:
5349 case Intrinsic::x86_t2rpntlvwz1rs:
5350 case Intrinsic::x86_t2rpntlvwz1rst1:
5351 if (!Subtarget->hasAMXMOVRS())
5354 case Intrinsic::x86_t2rpntlvwz0:
5355 case Intrinsic::x86_t2rpntlvwz0t1:
5356 case Intrinsic::x86_t2rpntlvwz1:
5357 case Intrinsic::x86_t2rpntlvwz1t1: {
5358 if (!Subtarget->hasAMXTRANSPOSE())
5367 case Intrinsic::x86_t2rpntlvwz0:
5368 Opc = X86::PT2RPNTLVWZ0;
5370 case Intrinsic::x86_t2rpntlvwz0t1:
5371 Opc = X86::PT2RPNTLVWZ0T1;
5373 case Intrinsic::x86_t2rpntlvwz1:
5374 Opc = X86::PT2RPNTLVWZ1;
5376 case Intrinsic::x86_t2rpntlvwz1t1:
5377 Opc = X86::PT2RPNTLVWZ1T1;
5379 case Intrinsic::x86_t2rpntlvwz0rs:
5380 Opc = X86::PT2RPNTLVWZ0RS;
5382 case Intrinsic::x86_t2rpntlvwz0rst1:
5383 Opc = X86::PT2RPNTLVWZ0RST1;
5385 case Intrinsic::x86_t2rpntlvwz1rs:
5386 Opc = X86::PT2RPNTLVWZ1RS;
5388 case Intrinsic::x86_t2rpntlvwz1rst1:
5389 Opc = X86::PT2RPNTLVWZ1RST1;
5393 unsigned TIndex =
Node->getConstantOperandVal(2);
5394 SDValue TReg = getI8Imm(TIndex, dl);
5396 SDValue Scale = getI8Imm(1, dl);
5398 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5399 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5402 MachineSDNode *CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
5403 ReplaceNode(
Node, CNode);
5411 if (Subtarget->isTargetNaCl())
5415 if (Subtarget->isTarget64BitILP32()) {
5420 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5421 SDValue ZextTarget = CurDAG->getZExtOrTrunc(
Target, dl, MVT::i64);
5422 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5423 Node->getOperand(0), ZextTarget);
5425 SelectCode(ZextTarget.
getNode());
5432 ReplaceNode(
Node, getGlobalBaseReg());
5440 CurDAG->RemoveDeadNode(
Node);
5446 if (matchBitExtract(
Node))
5451 if (tryShiftAmountMod(
Node))
5458 Node->getOperand(1),
Node->getOperand(2), Imm))
5464 if (tryVPTERNLOG(
Node))
5474 tryVPTESTM(
Node, N0, N1))
5477 tryVPTESTM(
Node, N1, N0))
5483 CurDAG->RemoveDeadNode(
Node);
5486 if (matchBitExtract(
Node))
5494 if (tryShrinkShlLogicImm(
Node))
5498 if (tryVPTERNLOG(
Node))
5513 if (!CurDAG->shouldOptForSize())
5517 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5523 auto *Cst = dyn_cast<ConstantSDNode>(N1);
5527 int64_t Val = Cst->getSExtValue();
5531 if (!isInt<8>(Val) && !isInt<32>(Val))
5535 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5539 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5543 unsigned ROpc, MOpc;
5652 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5653 if (tryFoldLoad(
Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5655 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5656 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5660 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N0)->getMemOperand()});
5662 CurDAG->RemoveDeadNode(
Node);
5667 CurDAG->SelectNodeTo(
Node, ROpc, NVT, MVT::i32, N0, N1);
5680 unsigned LoReg, ROpc, MOpc;
5685 ROpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
5686 MOpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
5705 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5706 bool FoldedLoad = tryFoldLoad(
Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5709 FoldedLoad = tryFoldLoad(
Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5714 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5723 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5725 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
5729 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5734 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
5740 VTs = CurDAG->getVTList(NVT, MVT::i32);
5742 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
5744 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
5749 CurDAG->RemoveDeadNode(
Node);
5759 unsigned LoReg, HiReg;
5761 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
5766 Opc = UseMULXHi ? X86::MULX32Hrr
5768 : IsSigned ?
X86::IMUL32r
5770 MOpc = UseMULXHi ? X86::MULX32Hrm
5772 : IsSigned ?
X86::IMUL32m
5774 LoReg = UseMULX ? X86::EDX : X86::EAX;
5778 Opc = UseMULXHi ? X86::MULX64Hrr
5780 : IsSigned ?
X86::IMUL64r
5782 MOpc = UseMULXHi ? X86::MULX64Hrm
5784 : IsSigned ?
X86::IMUL64m
5786 LoReg = UseMULX ? X86::RDX : X86::RAX;
5791 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5792 bool foldedLoad = tryFoldLoad(
Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5795 foldedLoad = tryFoldLoad(
Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5800 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5809 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5810 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5813 }
else if (UseMULX) {
5814 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
5815 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5820 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5821 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5827 ReplaceUses(N1.
getValue(1), Chain);
5829 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
5831 SDValue Ops[] = { N1, InGlue };
5833 SDVTList VTs = CurDAG->getVTList(NVT);
5834 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
5836 }
else if (UseMULX) {
5837 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
5838 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
5842 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
5843 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
5851 assert(LoReg &&
"Register for low half is not defined!");
5852 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
5863 assert(HiReg &&
"Register for high half is not defined!");
5864 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
5873 CurDAG->RemoveDeadNode(
Node);
5882 unsigned ROpc, MOpc;
5887 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
5888 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
5889 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
5890 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
5895 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
5896 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
5897 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
5898 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
5902 unsigned LoReg, HiReg, ClrReg;
5903 unsigned SExtOpcode;
5907 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
5911 LoReg = X86::AX; HiReg = X86::DX;
5913 SExtOpcode = X86::CWD;
5916 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
5917 SExtOpcode = X86::CDQ;
5920 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
5921 SExtOpcode = X86::CQO;
5925 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5926 bool foldedLoad = tryFoldLoad(
Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5927 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
5930 if (NVT == MVT::i8) {
5933 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
5935 if (tryFoldLoad(
Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5937 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rm8
5939 Move = CurDAG->getMachineNode(Opc, dl, MVT::i16, MVT::Other, Ops);
5941 ReplaceUses(N0.
getValue(1), Chain);
5943 CurDAG->setNodeMemRefs(Move, {cast<LoadSDNode>(N0)->getMemOperand()});
5945 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rr8
5947 Move = CurDAG->getMachineNode(Opc, dl, MVT::i16, N0);
5948 Chain = CurDAG->getEntryNode();
5950 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX,
SDValue(Move, 0),
5955 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
5956 LoReg, N0,
SDValue()).getValue(1);
5960 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
5963 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
5965 SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, {}), 0);
5969 SDValue(CurDAG->getMachineNode(
5970 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
5971 CurDAG->getTargetConstant(X86::sub_16bit, dl,
5979 SDValue(CurDAG->getMachineNode(
5980 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
5981 CurDAG->getTargetConstant(0, dl, MVT::i64), ClrNode,
5982 CurDAG->getTargetConstant(X86::sub_32bit, dl,
5990 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
5991 ClrNode, InGlue).getValue(1);
5999 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue, Ops);
6004 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
6007 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
6017 if (HiReg == X86::AH && !
SDValue(
Node, 1).use_empty()) {
6018 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
6019 unsigned AHExtOpcode =
6020 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
6022 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
6023 MVT::Glue, AHCopy, InGlue);
6028 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
6036 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6037 LoReg, NVT, InGlue);
6038 InGlue =
Result.getValue(2);
6045 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
6046 HiReg, NVT, InGlue);
6047 InGlue =
Result.getValue(2);
6052 CurDAG->RemoveDeadNode(
Node);
6061 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
6062 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
6068 if (Subtarget->canUseCMOV())
6077 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
6080 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
6083 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
6088 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
6091 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
6092 Chain =
SDValue(CurDAG->getMachineNode(Opc, dl, VTs, {N0, N1, Chain}), 0);
6095 Glue =
SDValue(CurDAG->getMachineNode(Opc, dl, MVT::Glue, N0, N1), 0);
6100 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
6104 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
6108 assert(Subtarget->canUseLAHFSAHF() &&
6109 "Target doesn't support SAHF or FCOMI?");
6110 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract,
SDValue());
6113 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
6119 CurDAG->RemoveDeadNode(
Node);
6140 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6143 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6145 CurDAG->RemoveDeadNode(
Node);
6159 auto *MaskC = dyn_cast<ConstantSDNode>(N0.
getOperand(1));
6177 unsigned TestOpcode;
6185 if (LeadingZeros == 0 && SavesBytes) {
6190 ShiftAmt = TrailingZeros;
6192 TestOpcode = X86::TEST64rr;
6193 }
else if (TrailingZeros == 0 && SavesBytes) {
6198 ShiftAmt = LeadingZeros;
6200 TestOpcode = X86::TEST64rr;
6201 }
else if (MaskC->hasOneUse() && !isInt<32>(Mask)) {
6204 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6205 if (PopCount == 8) {
6207 ShiftAmt = TrailingZeros;
6208 SubRegIdx = X86::sub_8bit;
6210 TestOpcode = X86::TEST8rr;
6211 }
else if (PopCount == 16) {
6213 ShiftAmt = TrailingZeros;
6214 SubRegIdx = X86::sub_16bit;
6215 SubRegVT = MVT::i16;
6216 TestOpcode = X86::TEST16rr;
6217 }
else if (PopCount == 32) {
6219 ShiftAmt = TrailingZeros;
6220 SubRegIdx = X86::sub_32bit;
6221 SubRegVT = MVT::i32;
6222 TestOpcode = X86::TEST32rr;
6226 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6228 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6231 if (SubRegIdx != 0) {
6233 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6236 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6244 unsigned ROpc, MOpc;
6251 if (isUInt<8>(Mask) &&
6252 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6256 SubRegOp = X86::sub_8bit;
6257 ROpc = X86::TEST8ri;
6258 MOpc = X86::TEST8mi;
6259 }
else if (OptForMinSize && isUInt<16>(Mask) &&
6260 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6267 SubRegOp = X86::sub_16bit;
6268 ROpc = X86::TEST16ri;
6269 MOpc = X86::TEST16mi;
6270 }
else if (isUInt<32>(Mask) && N0.
getValueType() != MVT::i16 &&
6271 ((!(Mask & 0x80000000) &&
6274 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6275 CmpVT == MVT::i32 ||
6283 SubRegOp = X86::sub_32bit;
6284 ROpc = X86::TEST32ri;
6285 MOpc = X86::TEST32mi;
6291 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6296 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6297 if (tryFoldLoad(
Node, N0.
getNode(), Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6299 if (!LoadN->isSimple()) {
6301 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6302 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6303 (MOpc == X86::TEST32mi && NumVolBits != 32))
6307 SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
6308 Reg.getOperand(0) };
6309 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other, Ops);
6311 ReplaceUses(
Reg.getValue(1),
SDValue(NewNode, 1));
6313 CurDAG->setNodeMemRefs(NewNode,
6314 {cast<LoadSDNode>(Reg)->getMemOperand()});
6318 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT, Reg);
6320 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32, Reg, Imm);
6323 ReplaceNode(
Node, NewNode);
6329 if (!Subtarget->hasSSE42())
6335 bool MayFoldLoad = !NeedIndex || !NeedMask;
6340 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6342 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6343 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8,
Node);
6346 if (NeedIndex || !NeedMask) {
6348 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6350 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6351 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32,
Node);
6357 CurDAG->RemoveDeadNode(
Node);
6361 if (!Subtarget->hasSSE42())
6365 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6366 Node->getOperand(1),
6368 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6369 Node->getOperand(3), InGlue).getValue(1);
6374 bool MayFoldLoad = !NeedIndex || !NeedMask;
6379 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6381 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6383 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8,
Node, InGlue);
6386 if (NeedIndex || !NeedMask) {
6388 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6390 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6391 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32,
Node, InGlue);
6396 CurDAG->RemoveDeadNode(
Node);
6408 if (foldLoadStoreIntoMemOperand(
Node))
6413 MVT VT =
Node->getSimpleValueType(0);
6415 if (Subtarget->hasSBBDepBreaking()) {
6420 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6425 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6426 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6428 CurDAG->getMachineNode(Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6437 if (VT == MVT::i8 || VT == MVT::i16) {
6438 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6439 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6443 CurDAG->RemoveDeadNode(
Node);
6457 MVT VT =
Node->getSimpleValueType(0);
6458 if (VT == MVT::i8 || VT == MVT::i16) {
6459 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6460 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6465 CurDAG->RemoveDeadNode(
Node);
6471 auto *Mgt = cast<X86MaskedGatherSDNode>(
Node);
6472 SDValue IndexOp = Mgt->getIndex();
6475 MVT ValueVT =
Node->getSimpleValueType(0);
6476 MVT MaskVT =
Mask.getSimpleValueType();
6493 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6494 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6495 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6496 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6497 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6498 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6499 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6500 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6501 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6502 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6503 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6504 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6505 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6506 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6507 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6508 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6509 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6510 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6511 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6512 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6513 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6514 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6515 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6516 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6518 assert(
EVT(MaskVT) ==
EVT(ValueVT).changeVectorElementTypeToInteger() &&
6519 "Unexpected mask VT!");
6520 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6521 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6522 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6523 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6524 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6525 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6526 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6527 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6528 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6529 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6530 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6531 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6532 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6533 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6534 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6535 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6542 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6543 Base, Scale, Index, Disp, Segment))
6546 SDValue PassThru = Mgt->getPassThru();
6547 SDValue Chain = Mgt->getChain();
6549 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6554 Index, Disp, Segment, Chain};
6555 NewNode = CurDAG->getMachineNode(Opc,
SDLoc(dl), VTs, Ops);
6558 Disp, Segment,
Mask, Chain};
6559 NewNode = CurDAG->getMachineNode(Opc,
SDLoc(dl), VTs, Ops);
6561 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6564 CurDAG->RemoveDeadNode(
Node);
6568 auto *Sc = cast<X86MaskedScatterSDNode>(
Node);
6570 SDValue IndexOp = Sc->getIndex();
6572 MVT ValueVT =
Value.getSimpleValueType();
6587 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6588 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6589 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6590 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6591 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6592 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6593 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6594 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6595 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6596 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6597 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6598 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6599 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6600 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6601 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6602 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6603 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6604 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6605 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6606 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6607 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6608 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6609 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6610 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6615 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6616 Base, Scale, Index, Disp, Segment))
6620 SDValue Chain = Sc->getChain();
6622 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6626 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6628 CurDAG->RemoveDeadNode(
Node);
6634 cast<SrcValueSDNode>(
Node->getOperand(1))->getValue());
6636 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6638 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6640 CurDAG->RemoveDeadNode(
Node);
6646 cast<SrcValueSDNode>(
Node->getOperand(1))->getValue());
6648 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6651 Ops[0] = CallIdValue;
6655 TargetOpcode::PREALLOCATED_ARG, dl,
6656 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
6661 CurDAG->RemoveDeadNode(
Node);
6668 if (!Subtarget->hasWIDEKL())
6672 switch (
Node->getOpcode()) {
6676 Opcode = X86::AESENCWIDE128KL;
6679 Opcode = X86::AESDECWIDE128KL;
6682 Opcode = X86::AESENCWIDE256KL;
6685 Opcode = X86::AESDECWIDE256KL;
6693 if (!selectAddr(
Node,
Addr,
Base, Scale, Index, Disp, Segment))
6696 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
6698 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
6700 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
6702 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
6704 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
6706 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
6708 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
6710 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
6714 Opcode, dl,
Node->getVTList(),
6715 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
6716 CurDAG->setNodeMemRefs(Res, cast<MemSDNode>(
Node)->getMemOperand());
6717 ReplaceNode(
Node, Res);
6725bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
6727 std::vector<SDValue> &OutOps) {
6728 SDValue Op0, Op1, Op2, Op3, Op4;
6729 switch (ConstraintID) {
6732 case InlineAsm::ConstraintCode::o:
6733 case InlineAsm::ConstraintCode::v:
6734 case InlineAsm::ConstraintCode::m:
6735 case InlineAsm::ConstraintCode::X:
6736 case InlineAsm::ConstraintCode::p:
6737 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
6742 OutOps.push_back(Op0);
6743 OutOps.push_back(Op1);
6744 OutOps.push_back(Op2);
6745 OutOps.push_back(Op3);
6746 OutOps.push_back(Op4);
6752 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
6758 return new X86DAGToDAGISelLegacy(TM, OptLevel);
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII)
Check if the instruction uses RIP relative addressing.
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 isFusableLoadOpStorePattern(StoreSDNode *StoreNode, SDValue StoredVal, SelectionDAG *CurDAG, unsigned LoadOpNo, LoadSDNode *&LoadNode, SDValue &InputChain)
Check whether or not the chain ending in StoreNode is suitable for doing the {load; op; store} to mod...
#define GET_EGPR_IF_ENABLED(OPC)
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)
cl::opt< bool > IndirectBranchTracking
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...
static void insertDAGNode(SelectionDAG &DAG, SDValue Pos, SDValue N)
#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)
#define GET_ND_IF_ENABLED(OPC)
DEMANGLE_DUMP_METHOD void dump() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
APInt zext(unsigned width) const
Zero extend to a new width.
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.
The address of a basic block.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
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...
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 form a handle around another node that is persistent and is updated across invo...
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
Describe properties that are true of each instruction in the target description file.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
An SDNode that represents everything that will be needed to construct a MachineInstr.
This is an abstract virtual class for memory operations.
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.
void dump() const
Dump this node, for debugging.
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
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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
Represents a use of a SDNode.
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
bool use_empty() const
Return true if there are no nodes using value ResNo of Node.
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
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
virtual void PostprocessISelDAG()
PostprocessISelDAG() - This hook allows the target to hack on the graph right after selection.
static int getUninvalidatedNodeId(SDNode *N)
virtual void emitFunctionEntryCode()
virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const
IsProfitableToFold - Returns true if it's profitable to fold the specific operand node N of U during ...
virtual bool ComplexPatternFuncMutatesDAG() const
Return true if complex patterns for this target can mutate the DAG.
virtual void PreprocessISelDAG()
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
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
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
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...
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
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 append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
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::vector< ArgListEntry > ArgListTy
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
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.
Target - Wrapper for Target specific information.
static Type * getVoidTy(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< use_iterator > uses()
void dump() const
Support for debugging, callable in GDB: V->dump()
X86ISelDAGToDAGPass(X86TargetMachine &TM)
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
void setAMXProgModel(AMXProgModelEnum Model)
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 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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ PREALLOCATED_SETUP
PREALLOCATED_SETUP - This has 2 operands: an input chain and a SRCVALUE with the preallocated call Va...
@ PREALLOCATED_ARG
PREALLOCATED_ARG - This has 3 operands: an input chain, a SRCVALUE with the preallocated call Value,...
@ BRIND
BRIND - Indirect branch.
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ LOCAL_RECOVER
LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
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,...
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)
Reg
All possible values of the reg field in the ModR/M byte.
@ 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.
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ 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.
@ 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)
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
int popcount(T Value) noexcept
Count the number of set bits in a value.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
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)
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
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.
CodeGenOptLevel
Code generation optimization level.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
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.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
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.
This class contains a discriminated union of information about pointers in memory operands,...
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
These are IR-level optimization flags that may be propagated to SDNodes.
bool hasNoUnsignedWrap() const
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.