23#include "llvm/Config/llvm-config.h"
28#include "llvm/IR/IntrinsicsX86.h"
39#define DEBUG_TYPE "x86-isel"
40#define PASS_NAME "X86 DAG->DAG Instruction Selection"
42STATISTIC(NumLoadMoved,
"Number of loads moved below TokenFactor");
45 cl::desc(
"Enable setting constant bits to reduce size of mask immediates"),
49 "x86-promote-anyext-load",
cl::init(
true),
61 struct X86ISelAddressMode {
69 int Base_FrameIndex = 0;
78 const char *ES =
nullptr;
83 bool NegateIndex =
false;
85 X86ISelAddressMode() =
default;
87 bool hasSymbolicDisplacement()
const {
88 return GV !=
nullptr ||
CP !=
nullptr || ES !=
nullptr ||
89 MCSym !=
nullptr ||
JT != -1 || BlockAddr !=
nullptr;
92 bool hasBaseOrIndexReg()
const {
99 if (
BaseType != RegBase)
return false;
101 dyn_cast_or_null<RegisterSDNode>(Base_Reg.
getNode()))
102 return RegNode->getReg() == X86::RIP;
111#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
113 dbgs() <<
"X86ISelAddressMode " <<
this <<
'\n';
114 dbgs() <<
"Base_Reg ";
120 dbgs() <<
" Base.FrameIndex " << Base_FrameIndex <<
'\n';
121 dbgs() <<
" Scale " << Scale <<
'\n'
129 dbgs() <<
" Disp " << Disp <<
'\n'
151 dbgs() <<
" JT" <<
JT <<
" Align" << Alignment.
value() <<
'\n';
171 bool IndirectTlsSegRefs;
174 X86DAGToDAGISel() =
delete;
178 OptForMinSize(
false), IndirectTlsSegRefs(
false) {}
184 "indirect-tls-seg-refs");
189 "OptForMinSize implies OptForSize");
201#include "X86GenDAGISel.inc"
206 bool foldOffsetIntoAddress(
uint64_t Offset, X86ISelAddressMode &AM);
207 bool matchLoadInAddress(
LoadSDNode *
N, X86ISelAddressMode &AM,
208 bool AllowSegmentRegForX32 =
false);
209 bool matchWrapper(
SDValue N, X86ISelAddressMode &AM);
210 bool matchAddress(
SDValue N, X86ISelAddressMode &AM);
211 bool matchVectorAddress(
SDValue N, X86ISelAddressMode &AM);
212 bool matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
unsigned Depth);
215 bool matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
217 bool matchVectorAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
219 bool matchAddressBase(
SDValue N, X86ISelAddressMode &AM);
248 return tryFoldLoad(
P,
P,
N,
Base, Scale,
Index, Disp, Segment);
256 bool isProfitableToFormMaskedOp(
SDNode *
N)
const;
261 std::vector<SDValue> &OutOps)
override;
263 void emitSpecialCodeForMain();
265 inline void getAddressOperands(X86ISelAddressMode &AM,
const SDLoc &
DL,
269 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
270 Base = CurDAG->getTargetFrameIndex(
271 AM.Base_FrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
272 else if (AM.Base_Reg.getNode())
275 Base = CurDAG->getRegister(0, VT);
277 Scale = getI8Imm(AM.Scale,
DL);
279#define GET_ND_IF_ENABLED(OPC) (Subtarget->hasNDD() ? OPC##_ND : OPC)
281 if (AM.NegateIndex) {
289 if (AM.IndexReg.getNode())
292 Index = CurDAG->getRegister(0, VT);
297 Disp = CurDAG->getTargetGlobalAddress(AM.GV,
SDLoc(),
301 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment,
302 AM.Disp, AM.SymbolFlags);
304 assert(!AM.Disp &&
"Non-zero displacement is ignored with ES.");
305 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
306 }
else if (AM.MCSym) {
307 assert(!AM.Disp &&
"Non-zero displacement is ignored with MCSym.");
308 assert(AM.SymbolFlags == 0 &&
"oo");
309 Disp = CurDAG->getMCSymbol(AM.MCSym, MVT::i32);
310 }
else if (AM.JT != -1) {
311 assert(!AM.Disp &&
"Non-zero displacement is ignored with JT.");
312 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
313 }
else if (AM.BlockAddr)
314 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
318 CurDAG->getSignedConstant(AM.Disp,
DL, MVT::i32,
true);
320 if (AM.Segment.getNode())
321 Segment = AM.Segment;
323 Segment = CurDAG->getRegister(0, MVT::i16);
332 bool shouldAvoidImmediateInstFormsForSize(
SDNode *
N)
const {
338 if (!CurDAG->shouldOptForSize())
348 if (
User->isMachineOpcode()) {
371 auto *
C = dyn_cast<ConstantSDNode>(
N);
372 if (
C && isInt<8>(
C->getSExtValue()))
392 (RegNode = dyn_cast_or_null<RegisterSDNode>(
394 if ((RegNode->
getReg() == X86::ESP) ||
395 (RegNode->
getReg() == X86::RSP))
404 return (UseCount > 1);
409 return CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
414 return CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
419 return CurDAG->getTargetConstant(Imm,
DL, MVT::i64);
424 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
426 MVT VecVT =
N->getOperand(0).getSimpleValueType();
432 assert((VecWidth == 128 || VecWidth == 256) &&
"Unexpected vector width");
434 MVT VecVT =
N->getSimpleValueType(0);
438 SDValue getPermuteVINSERTCommutedImmediate(
SDNode *
N,
unsigned VecWidth,
440 assert(VecWidth == 128 &&
"Unexpected vector width");
442 MVT VecVT =
N->getSimpleValueType(0);
444 assert((InsertIdx == 0 || InsertIdx == 1) &&
"Bad insertf128 index");
447 return getI8Imm(InsertIdx ? 0x02 : 0x30,
DL);
452 MVT VT =
N->getSimpleValueType(0);
455 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
457 CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, std::nullopt), 0);
458 if (VT == MVT::i64) {
460 CurDAG->getMachineNode(
461 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
462 CurDAG->getTargetConstant(0, dl, MVT::i64), Zero,
463 CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
468 unsigned Opcode =
N->getOpcode();
470 "Unexpected opcode for SBB materialization");
471 unsigned FlagOpIndex = Opcode ==
X86ISD::SBB ? 2 : 1;
473 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
474 N->getOperand(FlagOpIndex),
SDValue());
478 unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
479 MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
480 VTs = CurDAG->getVTList(SBBVT, MVT::i32);
482 CurDAG->getMachineNode(Opc, dl, VTs,
483 {Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
489 bool isUnneededShiftMask(
SDNode *
N,
unsigned Width)
const {
491 const APInt &Val =
N->getConstantOperandAPInt(1);
496 APInt Mask = Val | CurDAG->computeKnownBits(
N->getOperand(0)).Zero;
497 return Mask.countr_one() >= Width;
503 SDNode *getGlobalBaseReg();
514 return Subtarget->getInstrInfo();
527 bool isSExtAbsoluteSymbolRef(
unsigned Width,
SDNode *
N)
const;
531 if (!
N->isNonTemporal())
534 unsigned StoreSize =
N->getMemoryVT().getStoreSize();
536 if (
N->getAlign().value() < StoreSize)
545 return Subtarget->hasSSE41();
547 return Subtarget->hasAVX2();
549 return Subtarget->hasAVX512();
553 bool foldLoadStoreIntoMemOperand(
SDNode *
Node);
556 bool shrinkAndImmediate(
SDNode *
N);
557 bool isMaskZeroExtended(
SDNode *
N)
const;
558 bool tryShiftAmountMod(
SDNode *
N);
559 bool tryShrinkShlLogicImm(
SDNode *
N);
565 bool tryMatchBitSelect(
SDNode *
N);
567 MachineSDNode *emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
569 MachineSDNode *emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
bool MayFoldLoad,
573 bool tryOptimizeRem8Extend(
SDNode *
N);
575 bool onlyUsesZeroFlag(
SDValue Flags)
const;
576 bool hasNoSignFlagUses(
SDValue Flags)
const;
577 bool hasNoCarryFlagUses(
SDValue Flags)
const;
586 ID,
std::make_unique<X86DAGToDAGISel>(tm, OptLevel)) {}
590char X86DAGToDAGISelLegacy::ID = 0;
597 unsigned Opcode =
N->getOpcode();
604 EVT OpVT =
N->getOperand(0).getValueType();
608 OpVT =
N->getOperand(1).getValueType();
610 return Subtarget->hasVLX();
624bool X86DAGToDAGISel::isMaskZeroExtended(
SDNode *
N)
const {
637 if (OptLevel == CodeGenOptLevel::None)
647 if (useNonTemporalLoad(cast<LoadSDNode>(
N)))
652 switch (
U->getOpcode()) {
678 if (
auto *Imm = dyn_cast<ConstantSDNode>(Op1)) {
679 if (
Imm->getAPIntValue().isSignedIntN(8))
688 Imm->getAPIntValue().getBitWidth() == 64 &&
689 Imm->getAPIntValue().isIntN(32))
696 (
Imm->getAPIntValue() == UINT8_MAX ||
697 Imm->getAPIntValue() == UINT16_MAX ||
698 Imm->getAPIntValue() == UINT32_MAX))
704 (-
Imm->getAPIntValue()).isSignedIntN(8))
708 (-
Imm->getAPIntValue()).isSignedIntN(8) &&
709 hasNoCarryFlagUses(
SDValue(U, 1)))
734 if (
U->getOperand(0).getOpcode() ==
ISD::SHL &&
738 if (
U->getOperand(1).getOpcode() ==
ISD::SHL &&
746 auto *
C = dyn_cast<ConstantSDNode>(U0.
getOperand(0));
747 if (
C &&
C->getSExtValue() == -2)
752 auto *
C = dyn_cast<ConstantSDNode>(U1.
getOperand(0));
753 if (
C &&
C->getSExtValue() == -2)
767 if (isa<ConstantSDNode>(
U->getOperand(1)))
788bool X86DAGToDAGISel::isProfitableToFormMaskedOp(
SDNode *
N)
const {
791 "Unexpected opcode!");
796 return N->getOperand(1).hasOneUse();
805 if (Chain.
getNode() == Load.getNode())
809 "Unexpected chain operand");
823 Load.getOperand(1), Load.getOperand(2));
827 Ops.
append(Call->op_begin() + 1, Call->op_end());
841 if (Callee.getNode() == Chain.
getNode() || !Callee.hasOneUse())
843 auto *LD = dyn_cast<LoadSDNode>(Callee.getNode());
861 if (isa<MemSDNode>(Chain.
getNode()) &&
862 cast<MemSDNode>(Chain.
getNode())->writeMem())
868 Callee.getValue(1).hasOneUse())
876 if ((Imm & 0x00FFFFFF) != 0x0F1EFA)
879 uint8_t OptionalPrefixBytes [] = {0x26, 0x2e, 0x36, 0x3e, 0x64,
880 0x65, 0x66, 0x67, 0xf0, 0xf2};
883 uint8_t Byte = (Imm >> i) & 0xFF;
895 return (VT == MVT::v32i16 || VT == MVT::v32f16 || VT == MVT::v64i8);
898void X86DAGToDAGISel::PreprocessISelDAG() {
899 bool MadeChange =
false;
901 E = CurDAG->allnodes_end();
I != E; ) {
920 MVT VT =
N->getSimpleValueType(0);
921 int64_t
Imm = cast<ConstantSDNode>(
N)->getSExtValue();
922 int32_t EndbrImm = Subtarget->is64Bit() ? 0xF30F1EFA : 0xF30F1EFB;
927 "cf-protection-branch");
930 SDValue Complement = CurDAG->getConstant(~Imm, dl, VT,
false,
true);
931 Complement = CurDAG->getNOT(dl, Complement, VT);
933 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Complement);
943 if (
N->getOpcode() ==
X86ISD::AND && !
N->hasAnyUseOfValue(1)) {
945 N->getOperand(0),
N->getOperand(1));
947 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
971 auto mayPreventLoadFold = [&]() {
973 N->getOpcode() ==
ISD::ADD && Subtarget->hasAVX() &&
974 !
N->getOperand(1).hasOneUse();
977 N->getSimpleValueType(0).isVector() && !mayPreventLoadFold()) {
983 MVT VT =
N->getSimpleValueType(0);
991 CurDAG->getNode(NewOpcode,
DL, VT,
N->getOperand(0),
AllOnes);
993 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1000 switch (
N->getOpcode()) {
1002 MVT VT =
N->getSimpleValueType(0);
1004 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1011 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1014 CurDAG->getIntPtrConstant(
Index, dl));
1017 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1026 MVT VT =
N->getSimpleValueType(0);
1028 if (!Subtarget->hasBWI() &&
needBWI(VT)) {
1030 auto *MemNode = cast<MemSDNode>(
N);
1032 SDVTList VTs = CurDAG->getVTList(NarrowVT, MVT::Other);
1033 SDValue Ops[] = {MemNode->getChain(), MemNode->getBasePtr()};
1034 SDValue NarrowBCast = CurDAG->getMemIntrinsicNode(
1036 MemNode->getMemOperand());
1039 NarrowBCast, CurDAG->getIntPtrConstant(0, dl));
1042 CurDAG->getIntPtrConstant(
Index, dl));
1046 CurDAG->ReplaceAllUsesWith(
N, To);
1057 auto *Ld = cast<LoadSDNode>(
N);
1058 MVT VT =
N->getSimpleValueType(0);
1066 SDValue Chain = Ld->getChain();
1068 auto *UserLd = dyn_cast<LoadSDNode>(
User);
1069 MVT UserVT =
User->getSimpleValueType(0);
1071 UserLd->getBasePtr() ==
Ptr && UserLd->getChain() == Chain &&
1072 !
User->hasAnyUseOfValue(1) &&
1086 CurDAG->getIntPtrConstant(0, dl));
1087 SDValue Res = CurDAG->getBitcast(VT, Extract);
1091 CurDAG->ReplaceAllUsesWith(
N, To);
1100 EVT EleVT =
N->getOperand(0).getValueType().getVectorElementType();
1101 if (EleVT == MVT::i1)
1104 assert(Subtarget->hasSSE41() &&
"Expected SSE4.1 support!");
1105 assert(
N->getValueType(0).getVectorElementType() != MVT::i16 &&
1106 "We can't replace VSELECT with BLENDV in vXi16!");
1108 if (Subtarget->hasVLX() && CurDAG->ComputeNumSignBits(
N->getOperand(0)) ==
1111 N->getOperand(0),
N->getOperand(1),
N->getOperand(2),
1112 CurDAG->getTargetConstant(0xCA,
SDLoc(
N), MVT::i8));
1115 N->getOperand(0),
N->getOperand(1),
1119 CurDAG->ReplaceAllUsesWith(
N,
R.getNode());
1132 if (!
N->getSimpleValueType(0).isVector())
1136 switch (
N->getOpcode()) {
1146 if (
N->isStrictFPOpcode())
1148 CurDAG->getNode(NewOpc,
SDLoc(
N), {
N->getValueType(0), MVT::Other},
1149 {
N->getOperand(0),
N->getOperand(1)});
1152 CurDAG->getNode(NewOpc,
SDLoc(
N),
N->getValueType(0),
1155 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1165 if (!
N->getValueType(0).isVector())
1169 switch (
N->getOpcode()) {
1175 SDValue Res = CurDAG->getNode(NewOpc,
SDLoc(
N),
N->getValueType(0),
1176 N->getOperand(0),
N->getOperand(1));
1178 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1187 if (!
N->getValueType(0).isVector())
1191 if (
N->getOperand(0).getScalarValueSizeInBits() == 1) {
1193 "Unexpected opcode for mask vector!");
1201 SDValue Res = CurDAG->getNode(NewOpc,
SDLoc(
N),
N->getValueType(0),
1204 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1224 switch (
N->getOpcode()) {
1240 bool IsStrict =
N->isStrictFPOpcode();
1244 {
N->getValueType(0), MVT::Other},
1245 {
N->getOperand(0),
N->getOperand(1),
1246 CurDAG->getTargetConstant(Imm, dl, MVT::i32)});
1250 CurDAG->getTargetConstant(Imm, dl, MVT::i32));
1252 CurDAG->ReplaceAllUsesWith(
N, Res.
getNode());
1263 MVT VT =
N->getSimpleValueType(0);
1264 if (VT.
isVector() || VT == MVT::f128)
1267 MVT VecVT = VT == MVT::f64 ? MVT::v2f64
1268 : VT == MVT::f32 ? MVT::v4f32
1278 if (Subtarget->hasSSE2()) {
1283 switch (
N->getOpcode()) {
1290 Res = CurDAG->getNode(Opc, dl, IntVT, Op0, Op1);
1293 Res = CurDAG->getNode(
N->getOpcode(), dl, VecVT, Op0, Op1);
1296 CurDAG->getIntPtrConstant(0, dl));
1298 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Res);
1305 if (OptLevel != CodeGenOptLevel::None &&
1308 !Subtarget->useIndirectThunkCalls() &&
1309 ((
N->getOpcode() ==
X86ISD::CALL && !Subtarget->slowTwoMemOps()) ||
1311 (Subtarget->is64Bit() ||
1312 !getTargetMachine().isPositionIndependent())))) {
1351 switch (
N->getOpcode()) {
1356 MVT SrcVT =
N->getOperand(0).getSimpleValueType();
1357 MVT DstVT =
N->getSimpleValueType(0);
1369 if (SrcIsSSE && DstIsSSE)
1372 if (!SrcIsSSE && !DstIsSSE) {
1377 if (
N->getConstantOperandVal(1))
1385 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1386 int SPFI = cast<FrameIndexSDNode>(MemTmp)->getIndex();
1394 CurDAG->getEntryNode(), dl,
N->getOperand(0), MemTmp, MPI, MemVT);
1396 MemTmp, MPI, MemVT);
1403 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(
N, 0), Result);
1412 MVT SrcVT =
N->getOperand(1).getSimpleValueType();
1413 MVT DstVT =
N->getSimpleValueType(0);
1425 if (SrcIsSSE && DstIsSSE)
1428 if (!SrcIsSSE && !DstIsSSE) {
1433 if (
N->getConstantOperandVal(2))
1441 SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
1442 int SPFI = cast<FrameIndexSDNode>(MemTmp)->getIndex();
1452 SDVTList VTs = CurDAG->getVTList(MVT::Other);
1453 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1), MemTmp};
1457 if (
N->getFlags().hasNoFPExcept()) {
1459 Flags.setNoFPExcept(
true);
1460 Store->setFlags(Flags);
1463 assert(SrcVT == MemVT &&
"Unexpected VT!");
1464 Store = CurDAG->getStore(
N->getOperand(0), dl,
N->getOperand(1), MemTmp,
1469 SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other);
1471 Result = CurDAG->getMemIntrinsicNode(
1474 if (
N->getFlags().hasNoFPExcept()) {
1476 Flags.setNoFPExcept(
true);
1480 assert(DstVT == MemVT &&
"Unexpected VT!");
1481 Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
1489 CurDAG->ReplaceAllUsesWith(
N,
Result.getNode());
1503 CurDAG->RemoveDeadNodes();
1507bool X86DAGToDAGISel::tryOptimizeRem8Extend(
SDNode *
N) {
1508 unsigned Opc =
N->getMachineOpcode();
1509 if (Opc != X86::MOVZX32rr8 && Opc != X86::MOVSX32rr8 &&
1510 Opc != X86::MOVSX64rr8)
1522 unsigned ExpectedOpc = Opc == X86::MOVZX32rr8 ? X86::MOVZX32rr8_NOREX
1523 : X86::MOVSX32rr8_NOREX;
1528 if (Opc == X86::MOVSX64rr8) {
1533 ReplaceUses(
N, Extend);
1542void X86DAGToDAGISel::PostprocessISelDAG() {
1544 if (
TM.getOptLevel() == CodeGenOptLevel::None)
1549 bool MadeChange =
false;
1550 while (Position != CurDAG->allnodes_begin()) {
1553 if (
N->use_empty() || !
N->isMachineOpcode())
1556 if (tryOptimizeRem8Extend(
N)) {
1561 unsigned Opc =
N->getMachineOpcode();
1572 case X86::CTEST16rr:
1573 case X86::CTEST32rr:
1574 case X86::CTEST64rr: {
1575 auto &Op0 =
N->getOperand(0);
1580#define CASE_ND(OP) \
1583 switch (
And.getMachineOpcode()) {
1590 if (
And->hasAnyUseOfValue(1))
1593 Ops[0] =
And.getOperand(0);
1594 Ops[1] =
And.getOperand(1);
1596 CurDAG->getMachineNode(Opc,
SDLoc(
N), MVT::i32, Ops);
1597 ReplaceUses(
N,
Test);
1605 if (
And->hasAnyUseOfValue(1))
1608 bool IsCTESTCC = X86::isCTESTCC(Opc);
1609#define FROM_TO(A, B) \
1610 CASE_ND(A) NewOpc = IsCTESTCC ? X86::C##B : X86::B; \
1612 switch (
And.getMachineOpcode()) {
1622 And.getOperand(3),
And.getOperand(4),
1623 And.getOperand(5),
And.getOperand(0)};
1636 NewOpc,
SDLoc(
N), MVT::i32, MVT::Other, Ops);
1637 CurDAG->setNodeMemRefs(
1638 Test, cast<MachineSDNode>(
And.getNode())->memoperands());
1650 case X86::KORTESTBrr:
1651 case X86::KORTESTWrr:
1652 case X86::KORTESTDrr:
1653 case X86::KORTESTQrr: {
1655 if (Op0 !=
N->getOperand(1) || !
N->isOnlyUserOf(Op0.
getNode()) ||
1670#define FROM_TO(A, B) \
1682 if (NewOpc == X86::KTESTWrr && !Subtarget->hasDQI())
1687 ReplaceUses(
N, KTest);
1692 case TargetOpcode::SUBREG_TO_REG: {
1693 unsigned SubRegIdx =
N->getConstantOperandVal(2);
1694 if (SubRegIdx != X86::sub_xmm && SubRegIdx != X86::sub_ymm)
1711 CASE(VMOVAPDZ128rr)
CASE(VMOVUPDZ128rr)
1712 CASE(VMOVAPSZ128rr)
CASE(VMOVUPSZ128rr)
1713 CASE(VMOVDQA32Z128rr)
CASE(VMOVDQU32Z128rr)
1714 CASE(VMOVDQA64Z128rr)
CASE(VMOVDQU64Z128rr)
1715 CASE(VMOVAPDZ256rr)
CASE(VMOVUPDZ256rr)
1716 CASE(VMOVAPSZ256rr)
CASE(VMOVUPSZ256rr)
1717 CASE(VMOVDQA32Z256rr)
CASE(VMOVDQU32Z256rr)
1718 CASE(VMOVDQA64Z256rr)
CASE(VMOVDQU64Z256rr)
1723 if (!
In.isMachineOpcode() ||
1724 In.getMachineOpcode() <= TargetOpcode::GENERIC_OP_END)
1729 uint64_t TSFlags = getInstrInfo()->get(
In.getMachineOpcode()).TSFlags;
1737 CurDAG->UpdateNodeOperands(
N,
N->getOperand(0), In,
N->getOperand(2));
1744 CurDAG->RemoveDeadNodes();
1749void X86DAGToDAGISel::emitSpecialCodeForMain() {
1750 if (Subtarget->isTargetCygMing()) {
1752 auto &
DL = CurDAG->getDataLayout();
1755 CLI.setChain(CurDAG->getRoot())
1757 CurDAG->getExternalSymbol(
"__main", TLI->getPointerTy(
DL)),
1761 CurDAG->setRoot(
Result.second);
1765void X86DAGToDAGISel::emitFunctionEntryCode() {
1768 if (
F.hasExternalLinkage() &&
F.getName() ==
"main")
1769 emitSpecialCodeForMain();
1779 return isInt<31>(Val);
1783 X86ISelAddressMode &AM) {
1788 int64_t Val = AM.Disp +
Offset;
1791 if (Val != 0 && (AM.ES || AM.MCSym))
1795 if (Subtarget->is64Bit()) {
1798 AM.hasSymbolicDisplacement()))
1802 if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
1821 if (Subtarget->isTarget64BitILP32() && !isUInt<31>(Val) &&
1822 !AM.hasBaseOrIndexReg())
1829bool X86DAGToDAGISel::matchLoadInAddress(
LoadSDNode *
N, X86ISelAddressMode &AM,
1830 bool AllowSegmentRegForX32) {
1842 if (
isNullConstant(Address) && AM.Segment.getNode() ==
nullptr &&
1843 !IndirectTlsSegRefs &&
1844 (Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() ||
1845 Subtarget->isTargetFuchsia())) {
1846 if (Subtarget->isTarget64BitILP32() && !AllowSegmentRegForX32)
1848 switch (
N->getPointerInfo().getAddrSpace()) {
1850 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
1853 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
1866bool X86DAGToDAGISel::matchWrapper(
SDValue N, X86ISelAddressMode &AM) {
1869 if (AM.hasSymbolicDisplacement())
1872 bool IsRIPRelTLS =
false;
1890 if (IsRIPRel && AM.hasBaseOrIndexReg())
1894 X86ISelAddressMode Backup = AM;
1898 if (
auto *
G = dyn_cast<GlobalAddressSDNode>(N0)) {
1899 AM.GV =
G->getGlobal();
1900 AM.SymbolFlags =
G->getTargetFlags();
1902 }
else if (
auto *CP = dyn_cast<ConstantPoolSDNode>(N0)) {
1903 AM.CP =
CP->getConstVal();
1904 AM.Alignment =
CP->getAlign();
1905 AM.SymbolFlags =
CP->getTargetFlags();
1907 }
else if (
auto *S = dyn_cast<ExternalSymbolSDNode>(N0)) {
1908 AM.ES = S->getSymbol();
1909 AM.SymbolFlags = S->getTargetFlags();
1910 }
else if (
auto *S = dyn_cast<MCSymbolSDNode>(N0)) {
1911 AM.MCSym = S->getMCSymbol();
1912 }
else if (
auto *J = dyn_cast<JumpTableSDNode>(N0)) {
1913 AM.JT = J->getIndex();
1914 AM.SymbolFlags = J->getTargetFlags();
1915 }
else if (
auto *BA = dyn_cast<BlockAddressSDNode>(N0)) {
1916 AM.BlockAddr = BA->getBlockAddress();
1917 AM.SymbolFlags = BA->getTargetFlags();
1918 Offset = BA->getOffset();
1923 if (Subtarget->is64Bit() && !IsRIPRel && AM.GV &&
1924 TM.isLargeGlobalValue(AM.GV)) {
1929 if (foldOffsetIntoAddress(
Offset, AM)) {
1935 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
1943bool X86DAGToDAGISel::matchAddress(
SDValue N, X86ISelAddressMode &AM) {
1944 if (matchAddressRecursively(
N, AM, 0))
1951 if (Subtarget->isTarget64BitILP32() &&
1952 AM.BaseType == X86ISelAddressMode::RegBase &&
1953 AM.Base_Reg.getNode() !=
nullptr && AM.IndexReg.getNode() ==
nullptr) {
1954 SDValue Save_Base_Reg = AM.Base_Reg;
1955 if (
auto *LoadN = dyn_cast<LoadSDNode>(Save_Base_Reg)) {
1957 if (matchLoadInAddress(LoadN, AM,
true))
1958 AM.Base_Reg = Save_Base_Reg;
1964 if (AM.Scale == 2 &&
1965 AM.BaseType == X86ISelAddressMode::RegBase &&
1966 AM.Base_Reg.getNode() ==
nullptr) {
1967 AM.Base_Reg = AM.IndexReg;
1974 (!AM.GV || !
TM.isLargeGlobalValue(AM.GV)) && Subtarget->is64Bit() &&
1975 AM.Scale == 1 && AM.BaseType == X86ISelAddressMode::RegBase &&
1976 AM.Base_Reg.getNode() ==
nullptr && AM.IndexReg.getNode() ==
nullptr &&
1978 AM.Base_Reg = CurDAG->getRegister(X86::RIP, MVT::i64);
1984bool X86DAGToDAGISel::matchAdd(
SDValue &
N, X86ISelAddressMode &AM,
1990 X86ISelAddressMode Backup = AM;
1991 if (!matchAddressRecursively(
N.getOperand(0), AM,
Depth+1) &&
1992 !matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth+1))
1997 if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM,
1999 !matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1))
2006 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2007 !AM.Base_Reg.getNode() &&
2008 !AM.IndexReg.getNode()) {
2009 N = Handle.getValue();
2010 AM.Base_Reg =
N.getOperand(0);
2011 AM.IndexReg =
N.getOperand(1);
2015 N = Handle.getValue();
2025 if (
N->getNodeId() == -1 ||
2045 X86ISelAddressMode &AM) {
2052 if (ScaleLog <= 0 || ScaleLog >= 4 ||
2053 Mask != (0xffu << ScaleLog))
2056 MVT XVT =
X.getSimpleValueType();
2057 MVT VT =
N.getSimpleValueType();
2082 AM.Scale = (1 << ScaleLog);
2090 X86ISelAddressMode &AM) {
2096 int64_t Mask = cast<ConstantSDNode>(
N->getOperand(1))->getSExtValue();
2101 bool FoundAnyExtend =
false;
2105 FoundAnyExtend =
true;
2123 if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
2126 MVT VT =
N.getSimpleValueType();
2128 if (FoundAnyExtend) {
2149 AM.Scale = 1 << ShiftAmt;
2150 AM.IndexReg = NewAnd;
2184 X86ISelAddressMode &AM) {
2190 unsigned MaskIdx, MaskLen;
2193 unsigned MaskLZ = 64 - (MaskIdx + MaskLen);
2199 unsigned AMShiftAmt = MaskIdx;
2203 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2207 unsigned ScaleDown = (64 -
X.getSimpleValueType().getSizeInBits()) + ShiftAmt;
2208 if (MaskLZ < ScaleDown)
2210 MaskLZ -= ScaleDown;
2218 bool ReplacingAnyExtend =
false;
2220 unsigned ExtendBits =
X.getSimpleValueType().getSizeInBits() -
2221 X.getOperand(0).getSimpleValueType().getSizeInBits();
2224 X =
X.getOperand(0);
2225 MaskLZ = ExtendBits > MaskLZ ? 0 : MaskLZ - ExtendBits;
2226 ReplacingAnyExtend =
true;
2228 APInt MaskedHighBits =
2235 MVT VT =
N.getSimpleValueType();
2236 if (ReplacingAnyExtend) {
2237 assert(
X.getValueType() != VT);
2244 MVT XVT =
X.getSimpleValueType();
2265 AM.Scale = 1 << AMShiftAmt;
2266 AM.IndexReg = NewExt;
2276 X86ISelAddressMode &AM,
2284 if (!Subtarget.hasTBM() &&
2285 !(Subtarget.hasBMI() && Subtarget.hasFastBEXTR()))
2289 unsigned MaskIdx, MaskLen;
2297 unsigned AMShiftAmt = MaskIdx;
2301 if (AMShiftAmt == 0 || AMShiftAmt > 3)
return true;
2303 MVT XVT =
X.getSimpleValueType();
2304 MVT VT =
N.getSimpleValueType();
2329 AM.Scale = 1 << AMShiftAmt;
2330 AM.IndexReg = NewExt;
2337 X86ISelAddressMode &AM,
2339 assert(AM.IndexReg.getNode() ==
nullptr &&
"IndexReg already matched");
2340 assert((AM.Scale == 1 || AM.Scale == 2 || AM.Scale == 4 || AM.Scale == 8) &&
2341 "Illegal index scale");
2347 EVT VT =
N.getValueType();
2348 unsigned Opc =
N.getOpcode();
2351 if (CurDAG->isBaseWithConstantOffset(
N)) {
2352 auto *AddVal = cast<ConstantSDNode>(
N.getOperand(1));
2354 if (!foldOffsetIntoAddress(
Offset, AM))
2355 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2359 if (Opc ==
ISD::ADD &&
N.getOperand(0) ==
N.getOperand(1)) {
2360 if (AM.Scale <= 4) {
2362 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2368 uint64_t ShiftAmt =
N.getConstantOperandVal(1);
2369 uint64_t ScaleAmt = 1ULL << ShiftAmt;
2370 if ((AM.Scale * ScaleAmt) <= 8) {
2371 AM.Scale *= ScaleAmt;
2372 return matchIndexRecursively(
N.getOperand(0), AM,
Depth + 1);
2380 if (Src.getOpcode() ==
ISD::ADD && Src->getFlags().hasNoSignedWrap() &&
2382 if (CurDAG->isBaseWithConstantOffset(Src)) {
2383 SDValue AddSrc = Src.getOperand(0);
2384 auto *AddVal = cast<ConstantSDNode>(Src.getOperand(1));
2386 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2388 SDValue ExtSrc = CurDAG->getNode(Opc,
DL, VT, AddSrc);
2394 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2395 CurDAG->RemoveDeadNode(
N.getNode());
2407 unsigned SrcOpc = Src.getOpcode();
2408 if (((SrcOpc ==
ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2409 CurDAG->isADDLike(Src,
true)) &&
2411 if (CurDAG->isBaseWithConstantOffset(Src)) {
2412 SDValue AddSrc = Src.getOperand(0);
2414 if (!foldOffsetIntoAddress(
Offset * AM.Scale, AM)) {
2425 if ((AM.Scale * ScaleAmt) <= 8 &&
2427 CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
2428 AM.Scale *= ScaleAmt;
2429 SDValue ExtShVal = CurDAG->getNode(Opc,
DL, VT, ShVal);
2438 SDValue ExtSrc = CurDAG->getNode(Opc,
DL, VT, AddSrc);
2440 SDValue ExtAdd = CurDAG->getNode(SrcOpc,
DL, VT, ExtSrc, ExtVal);
2444 CurDAG->ReplaceAllUsesWith(
N, ExtAdd);
2445 CurDAG->RemoveDeadNode(
N.getNode());
2446 return Res ? Res : ExtSrc;
2456bool X86DAGToDAGISel::matchAddressRecursively(
SDValue N, X86ISelAddressMode &AM,
2460 dbgs() <<
"MatchAddress: ";
2465 return matchAddressBase(
N, AM);
2470 if (AM.isRIPRelative()) {
2474 if (!(AM.ES || AM.MCSym) && AM.JT != -1)
2477 if (
auto *Cst = dyn_cast<ConstantSDNode>(
N))
2478 if (!foldOffsetIntoAddress(Cst->getSExtValue(), AM))
2483 switch (
N.getOpcode()) {
2486 if (!AM.hasSymbolicDisplacement() && AM.Disp == 0)
2487 if (
const auto *ESNode = dyn_cast<MCSymbolSDNode>(
N.getOperand(0))) {
2489 AM.MCSym = ESNode->getMCSymbol();
2495 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
2496 if (!foldOffsetIntoAddress(Val, AM))
2503 if (!matchWrapper(
N, AM))
2508 if (!matchLoadInAddress(cast<LoadSDNode>(
N), AM))
2513 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2514 AM.Base_Reg.getNode() ==
nullptr &&
2516 AM.BaseType = X86ISelAddressMode::FrameIndexBase;
2517 AM.Base_FrameIndex = cast<FrameIndexSDNode>(
N)->getIndex();
2523 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
2526 if (
auto *CN = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
2527 unsigned Val = CN->getZExtValue();
2532 if (Val == 1 || Val == 2 || Val == 3) {
2534 AM.Scale = 1 << Val;
2535 AM.IndexReg = matchIndexRecursively(ShVal, AM,
Depth + 1);
2543 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
break;
2547 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2548 "Unexpected value size!");
2557 if (!isa<ConstantSDNode>(
N.getOperand(1)) ||
2558 !isa<ConstantSDNode>(
And.getOperand(1)))
2560 uint64_t Mask =
And.getConstantOperandVal(1) >>
N.getConstantOperandVal(1);
2572 if (
N.getResNo() != 0)
break;
2577 if (AM.BaseType == X86ISelAddressMode::RegBase &&
2578 AM.Base_Reg.getNode() ==
nullptr &&
2579 AM.IndexReg.getNode() ==
nullptr) {
2580 if (
auto *CN = dyn_cast<ConstantSDNode>(
N.getOperand(1)))
2581 if (CN->getZExtValue() == 3 || CN->getZExtValue() == 5 ||
2582 CN->getZExtValue() == 9) {
2583 AM.Scale =
unsigned(CN->getZExtValue())-1;
2594 auto *AddVal = cast<ConstantSDNode>(MulVal.
getOperand(1));
2595 uint64_t Disp = AddVal->getSExtValue() * CN->getZExtValue();
2596 if (foldOffsetIntoAddress(Disp, AM))
2597 Reg =
N.getOperand(0);
2599 Reg =
N.getOperand(0);
2602 AM.IndexReg = AM.Base_Reg =
Reg;
2621 X86ISelAddressMode Backup = AM;
2622 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth+1)) {
2623 N = Handle.getValue();
2627 N = Handle.getValue();
2629 if (AM.IndexReg.getNode() || AM.isRIPRelative()) {
2644 RHS.getOperand(0).getValueType() == MVT::i32))
2648 if ((AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.getNode() &&
2649 !AM.Base_Reg.getNode()->hasOneUse()) ||
2650 AM.BaseType == X86ISelAddressMode::FrameIndexBase)
2654 if ((AM.hasSymbolicDisplacement() && !Backup.hasSymbolicDisplacement()) +
2655 ((AM.Disp != 0) && (Backup.Disp == 0)) +
2656 (AM.Segment.getNode() && !Backup.Segment.getNode()) >= 2)
2668 AM.NegateIndex =
true;
2676 if (!CurDAG->isADDLike(
N))
2680 if (!matchAdd(
N, AM,
Depth))
2689 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
break;
2693 assert(
N.getSimpleValueType().getSizeInBits() <= 64 &&
2694 "Unexpected value size!");
2696 if (!isa<ConstantSDNode>(
N.getOperand(1)))
2699 if (
N.getOperand(0).getOpcode() ==
ISD::SRL) {
2728 if (AM.IndexReg.getNode() !=
nullptr || AM.Scale != 1)
2738 AM.IndexReg =
Index;
2744 if (Src.getOpcode() ==
ISD::AND && Src.hasOneUse())
2745 if (
auto *MaskC = dyn_cast<ConstantSDNode>(Src.getOperand(1))) {
2746 Mask = MaskC->getAPIntValue();
2747 Src = Src.getOperand(0);
2750 if (Src.getOpcode() ==
ISD::SHL && Src.hasOneUse() &&
N->hasOneUse()) {
2752 SDValue ShlSrc = Src.getOperand(0);
2753 SDValue ShlAmt = Src.getOperand(1);
2754 auto *ShAmtC = dyn_cast<ConstantSDNode>(ShlAmt);
2757 unsigned ShAmtV = ShAmtC->getZExtValue();
2765 if (!Src->getFlags().hasNoUnsignedWrap() &&
2766 !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2774 MVT VT =
N.getSimpleValueType();
2778 if (!
Mask.isAllOnes()) {
2779 Res = CurDAG->getConstant(
Mask.lshr(ShAmtV),
DL, SrcVT);
2781 Res = CurDAG->getNode(
ISD::AND,
DL, SrcVT, ShlSrc, Res);
2788 CurDAG->ReplaceAllUsesWith(
N, NewShl);
2789 CurDAG->RemoveDeadNode(
N.getNode());
2792 AM.Scale = 1 << ShAmtV;
2796 AM.IndexReg = matchIndexRecursively(Zext, AM,
Depth + 1);
2800 if (Src.getOpcode() ==
ISD::SRL && !
Mask.isAllOnes()) {
2803 Src.getOperand(0), AM))
2808 Src.getOperand(0), AM))
2813 Src.getOperand(0), AM, *Subtarget))
2821 return matchAddressBase(
N, AM);
2826bool X86DAGToDAGISel::matchAddressBase(
SDValue N, X86ISelAddressMode &AM) {
2828 if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base_Reg.getNode()) {
2830 if (!AM.IndexReg.getNode()) {
2841 AM.BaseType = X86ISelAddressMode::RegBase;
2846bool X86DAGToDAGISel::matchVectorAddressRecursively(
SDValue N,
2847 X86ISelAddressMode &AM,
2851 dbgs() <<
"MatchVectorAddress: ";
2856 return matchAddressBase(
N, AM);
2859 switch (
N.getOpcode()) {
2861 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
2862 if (!foldOffsetIntoAddress(Val, AM))
2867 if (!matchWrapper(
N, AM))
2875 X86ISelAddressMode Backup = AM;
2876 if (!matchVectorAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
2877 !matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2883 if (!matchVectorAddressRecursively(Handle.getValue().getOperand(1), AM,
2885 !matchVectorAddressRecursively(Handle.getValue().getOperand(0), AM,
2890 N = Handle.getValue();
2895 return matchAddressBase(
N, AM);
2901bool X86DAGToDAGISel::matchVectorAddress(
SDValue N, X86ISelAddressMode &AM) {
2902 return matchVectorAddressRecursively(
N, AM, 0);
2910 X86ISelAddressMode AM;
2916 AM.IndexReg = matchIndexRecursively(IndexOp, AM, 0);
2918 AM.IndexReg = IndexOp;
2922 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
2924 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
2926 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
2932 if (matchVectorAddress(BasePtr, AM))
2935 getAddressOperands(AM,
DL, VT,
Base, Scale,
Index, Disp, Segment);
2949 X86ISelAddressMode AM;
2961 unsigned AddrSpace =
2962 cast<MemSDNode>(Parent)->getPointerInfo().getAddrSpace();
2964 AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
2966 AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
2968 AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
2973 MVT VT =
N.getSimpleValueType();
2975 if (matchAddress(
N, AM))
2978 getAddressOperands(AM,
DL, VT,
Base, Scale,
Index, Disp, Segment);
2994 N =
N.getOperand(0);
3009 const GlobalValue *GV = cast<GlobalAddressSDNode>(
N)->getGlobal();
3011 return CR->getUnsignedMax().ult(1ull << 32);
3013 return !
TM.isLargeGlobalValue(GV);
3022 if (!selectLEAAddr(
N,
Base, Scale,
Index, Disp, Segment))
3025 auto *
RN = dyn_cast<RegisterSDNode>(
Base);
3026 if (RN &&
RN->getReg() == 0)
3027 Base = CurDAG->getRegister(0, MVT::i64);
3028 else if (
Base.getValueType() == MVT::i32 && !isa<FrameIndexSDNode>(
Base)) {
3032 Base = CurDAG->getTargetInsertSubreg(X86::sub_32bit,
DL, MVT::i64, ImplDef,
3036 RN = dyn_cast<RegisterSDNode>(
Index);
3037 if (RN &&
RN->getReg() == 0)
3038 Index = CurDAG->getRegister(0, MVT::i64);
3041 "Expect to be extending 32-bit registers for use in LEA");
3044 Index = CurDAG->getTargetInsertSubreg(X86::sub_32bit,
DL, MVT::i64, ImplDef,
3053bool X86DAGToDAGISel::selectLEAAddr(
SDValue N,
3057 X86ISelAddressMode AM;
3061 MVT VT =
N.getSimpleValueType();
3066 SDValue T = CurDAG->getRegister(0, MVT::i32);
3068 if (matchAddress(
N, AM))
3073 unsigned Complexity = 0;
3074 if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base_Reg.getNode())
3076 else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
3079 if (AM.IndexReg.getNode())
3092 if (AM.hasSymbolicDisplacement()) {
3094 if (Subtarget->is64Bit())
3104 auto isMathWithFlags = [](
SDValue V) {
3105 switch (
V.getOpcode()) {
3126 if (isMathWithFlags(
N.getOperand(0)) || isMathWithFlags(
N.getOperand(1)))
3134 if (Complexity <= 2)
3137 getAddressOperands(AM,
DL, VT,
Base, Scale,
Index, Disp, Segment);
3148 X86ISelAddressMode AM;
3149 if (
auto *GA = dyn_cast<GlobalAddressSDNode>(
N)) {
3150 AM.GV = GA->getGlobal();
3151 AM.Disp += GA->getOffset();
3152 AM.SymbolFlags = GA->getTargetFlags();
3154 auto *SA = cast<ExternalSymbolSDNode>(
N);
3155 AM.ES = SA->getSymbol();
3156 AM.SymbolFlags = SA->getTargetFlags();
3159 if (Subtarget->is32Bit()) {
3161 AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32);
3164 MVT VT =
N.getSimpleValueType();
3165 getAddressOperands(AM,
SDLoc(
N), VT,
Base, Scale,
Index, Disp, Segment);
3173 EVT VT =
N.getValueType();
3174 bool WasTruncated =
false;
3176 WasTruncated =
true;
3177 N =
N.getOperand(0);
3186 unsigned Opc =
N.getOperand(0)->getOpcode();
3188 Op =
N.getOperand(0);
3191 return !WasTruncated;
3195 auto *GA = cast<GlobalAddressSDNode>(
N.getOperand(0));
3196 std::optional<ConstantRange> CR = GA->getGlobal()->getAbsoluteSymbolRange();
3197 if (!CR || CR->getUnsignedMax().uge(1ull << VT.
getSizeInBits()))
3201 Op = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
SDLoc(
N), VT,
3202 GA->getOffset(), GA->getTargetFlags());
3210 assert(Root &&
P &&
"Unknown root/parent nodes");
3212 !IsProfitableToFold(
N,
P, Root) ||
3213 !IsLegalToFold(
N,
P, Root, OptLevel))
3216 return selectAddr(
N.getNode(),
3217 N.getOperand(1),
Base, Scale,
Index, Disp, Segment);
3224 assert(Root &&
P &&
"Unknown root/parent nodes");
3226 !IsProfitableToFold(
N,
P, Root) ||
3227 !IsLegalToFold(
N,
P, Root, OptLevel))
3230 return selectAddr(
N.getNode(),
3231 N.getOperand(1),
Base, Scale,
Index, Disp, Segment);
3237SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
3238 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
3240 return CurDAG->getRegister(GlobalBaseReg, TLI->
getPointerTy(
DL)).getNode();
3243bool X86DAGToDAGISel::isSExtAbsoluteSymbolRef(
unsigned Width,
SDNode *
N)
const {
3245 N =
N->getOperand(0).getNode();
3249 auto *GA = dyn_cast<GlobalAddressSDNode>(
N->getOperand(0));
3253 auto *GV = GA->getGlobal();
3256 return CR->getSignedMin().sge(-1ull << Width) &&
3257 CR->getSignedMax().slt(1ull << Width);
3262 return Width == 32 && !
TM.isLargeGlobalValue(GV);
3266 assert(
N->isMachineOpcode() &&
"Unexpected node");
3267 unsigned Opc =
N->getMachineOpcode();
3268 const MCInstrDesc &MCID = getInstrInfo()->get(Opc);
3273 return static_cast<X86::CondCode>(
N->getConstantOperandVal(CondNo));
3278bool X86DAGToDAGISel::onlyUsesZeroFlag(
SDValue Flags)
const {
3283 if (UI.getUse().getResNo() !=
Flags.getResNo())
3287 cast<RegisterSDNode>(UI->getOperand(1))->getReg() != X86::EFLAGS)
3291 FlagUE = UI->
use_end(); FlagUI != FlagUE; ++FlagUI) {
3293 if (FlagUI.getUse().getResNo() != 1)
continue;
3295 if (!FlagUI->isMachineOpcode())
return false;
3314bool X86DAGToDAGISel::hasNoSignFlagUses(
SDValue Flags)
const {
3319 if (UI.getUse().getResNo() !=
Flags.getResNo())
3323 cast<RegisterSDNode>(UI->getOperand(1))->getReg() != X86::EFLAGS)
3327 FlagUE = UI->
use_end(); FlagUI != FlagUE; ++FlagUI) {
3329 if (FlagUI.getUse().getResNo() != 1)
continue;
3331 if (!FlagUI->isMachineOpcode())
return false;
3370 bool X86DAGToDAGISel::hasNoCarryFlagUses(
SDValue Flags)
const {
3375 if (UI.getUse().getResNo() !=
Flags.getResNo())
3378 unsigned UIOpc = UI->getOpcode();
3382 if (cast<RegisterSDNode>(UI->getOperand(1))->getReg() != X86::EFLAGS)
3386 FlagUI != FlagUE; ++FlagUI) {
3388 if (FlagUI.getUse().getResNo() != 1)
3391 if (!FlagUI->isMachineOpcode())
3432 if (StoredVal.
getResNo() != 0)
return false;
3446 LoadNode = cast<LoadSDNode>(Load);
3449 if (!Load.hasOneUse())
3457 bool FoundLoad =
false;
3461 const unsigned int Max = 1024;
3503 if (Chain == Load.getValue(1)) {
3509 if (
Op == Load.getValue(1)) {
3525 if (
Op.getNode() != LoadNode)
3558bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(
SDNode *
Node) {
3559 auto *StoreNode = cast<StoreSDNode>(
Node);
3566 EVT MemVT = StoreNode->getMemoryVT();
3567 if (MemVT != MVT::i64 && MemVT != MVT::i32 && MemVT != MVT::i16 &&
3571 bool IsCommutable =
false;
3572 bool IsNegate =
false;
3586 IsCommutable =
true;
3590 unsigned LoadOpNo = IsNegate ? 1 : 0;
3594 LoadNode, InputChain)) {
3601 LoadNode, InputChain))
3610 auto SelectOpcode = [&](
unsigned Opc64,
unsigned Opc32,
unsigned Opc16,
3631 unsigned NewOpc = SelectOpcode(X86::NEG64m, X86::NEG32m, X86::NEG16m,
3641 if (!Subtarget->slowIncDec() || CurDAG->shouldOptForSize()) {
3645 if ((IsOne || IsNegOne) && hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3648 ? SelectOpcode(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m)
3649 : SelectOpcode(
X86::DEC64m,
X86::DEC32m,
X86::DEC16m,
X86::DEC8m);
3662 auto SelectRegOpcode = [SelectOpcode](
unsigned Opc) {
3665 return SelectOpcode(X86::ADD64mr, X86::ADD32mr, X86::ADD16mr,
3668 return SelectOpcode(X86::ADC64mr, X86::ADC32mr, X86::ADC16mr,
3671 return SelectOpcode(X86::SUB64mr, X86::SUB32mr, X86::SUB16mr,
3674 return SelectOpcode(X86::SBB64mr, X86::SBB32mr, X86::SBB16mr,
3677 return SelectOpcode(X86::AND64mr, X86::AND32mr, X86::AND16mr,
3680 return SelectOpcode(X86::OR64mr, X86::OR32mr, X86::OR16mr, X86::OR8mr);
3682 return SelectOpcode(X86::XOR64mr, X86::XOR32mr, X86::XOR16mr,
3688 auto SelectImmOpcode = [SelectOpcode](
unsigned Opc) {
3691 return SelectOpcode(X86::ADD64mi32, X86::ADD32mi, X86::ADD16mi,
3694 return SelectOpcode(X86::ADC64mi32, X86::ADC32mi, X86::ADC16mi,
3697 return SelectOpcode(X86::SUB64mi32, X86::SUB32mi, X86::SUB16mi,
3700 return SelectOpcode(X86::SBB64mi32, X86::SBB32mi, X86::SBB16mi,
3703 return SelectOpcode(X86::AND64mi32, X86::AND32mi, X86::AND16mi,
3706 return SelectOpcode(X86::OR64mi32, X86::OR32mi, X86::OR16mi,
3709 return SelectOpcode(X86::XOR64mi32, X86::XOR32mi, X86::XOR16mi,
3716 unsigned NewOpc = SelectRegOpcode(Opc);
3721 if (
auto *OperandC = dyn_cast<ConstantSDNode>(Operand)) {
3722 int64_t OperandV = OperandC->getSExtValue();
3728 ((MemVT != MVT::i8 && !isInt<8>(OperandV) && isInt<8>(-OperandV)) ||
3729 (MemVT == MVT::i64 && !isInt<32>(OperandV) &&
3730 isInt<32>(-OperandV))) &&
3731 hasNoCarryFlagUses(StoredVal.
getValue(1))) {
3732 OperandV = -OperandV;
3736 if (MemVT != MVT::i64 || isInt<32>(OperandV)) {
3737 Operand = CurDAG->getSignedConstant(OperandV,
SDLoc(
Node), MemVT,
3739 NewOpc = SelectImmOpcode(Opc);
3745 CurDAG->getCopyToReg(InputChain,
SDLoc(
Node), X86::EFLAGS,
3749 Segment, Operand, CopyTo, CopyTo.
getValue(1)};
3750 Result = CurDAG->getMachineNode(NewOpc,
SDLoc(
Node), MVT::i32, MVT::Other,
3754 Segment, Operand, InputChain};
3755 Result = CurDAG->getMachineNode(NewOpc,
SDLoc(
Node), MVT::i32, MVT::Other,
3766 CurDAG->setNodeMemRefs(Result, MemOps);
3772 CurDAG->RemoveDeadNode(
Node);
3783bool X86DAGToDAGISel::matchBitExtract(
SDNode *
Node) {
3787 "Should be either an and-mask, or right-shift after clearing high bits.");
3790 if (!Subtarget->hasBMI() && !Subtarget->hasBMI2())
3793 MVT NVT =
Node->getSimpleValueType(0);
3796 if (NVT != MVT::i32 && NVT != MVT::i64)
3804 const bool AllowExtraUsesByDefault = Subtarget->hasBMI2();
3805 auto checkUses = [AllowExtraUsesByDefault](
3807 std::optional<bool> AllowExtraUses) {
3808 return AllowExtraUses.value_or(AllowExtraUsesByDefault) ||
3809 Op.getNode()->hasNUsesOfValue(NUses,
Op.getResNo());
3811 auto checkOneUse = [checkUses](
SDValue Op,
3812 std::optional<bool> AllowExtraUses =
3814 return checkUses(
Op, 1, AllowExtraUses);
3816 auto checkTwoUse = [checkUses](
SDValue Op,
3817 std::optional<bool> AllowExtraUses =
3819 return checkUses(
Op, 2, AllowExtraUses);
3822 auto peekThroughOneUseTruncation = [checkOneUse](
SDValue V) {
3824 assert(
V.getSimpleValueType() == MVT::i32 &&
3825 V.getOperand(0).getSimpleValueType() == MVT::i64 &&
3826 "Expected i64 -> i32 truncation");
3827 V =
V.getOperand(0);
3833 auto matchPatternA = [checkOneUse, peekThroughOneUseTruncation, &NBits,
3836 if (
Mask->getOpcode() !=
ISD::ADD || !checkOneUse(Mask))
3842 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3847 NBits =
M0->getOperand(1);
3848 NegateNBits =
false;
3852 auto isAllOnes = [
this, peekThroughOneUseTruncation, NVT](
SDValue V) {
3853 V = peekThroughOneUseTruncation(V);
3854 return CurDAG->MaskedValueIsAllOnes(
3860 auto matchPatternB = [checkOneUse, isAllOnes, peekThroughOneUseTruncation,
3863 if (
Mask.getOpcode() !=
ISD::XOR || !checkOneUse(Mask))
3866 if (!isAllOnes(
Mask->getOperand(1)))
3869 SDValue M0 = peekThroughOneUseTruncation(
Mask->getOperand(0));
3873 if (!isAllOnes(
M0->getOperand(0)))
3875 NBits =
M0->getOperand(1);
3876 NegateNBits =
false;
3882 auto canonicalizeShiftAmt = [&NBits, &NegateNBits](
SDValue ShiftAmt,
3883 unsigned Bitwidth) {
3888 NBits = NBits.getOperand(0);
3893 auto *V0 = dyn_cast<ConstantSDNode>(NBits.getOperand(0));
3894 if (!V0 || V0->getZExtValue() != Bitwidth)
3896 NBits = NBits.getOperand(1);
3897 NegateNBits =
false;
3903 auto matchPatternC = [checkOneUse, peekThroughOneUseTruncation, &NegateNBits,
3906 Mask = peekThroughOneUseTruncation(Mask);
3907 unsigned Bitwidth =
Mask.getSimpleValueType().getSizeInBits();
3909 if (
Mask.getOpcode() !=
ISD::SRL || !checkOneUse(Mask))
3916 if (!checkOneUse(
M1))
3918 canonicalizeShiftAmt(
M1, Bitwidth);
3923 return !NegateNBits;
3931 auto matchPatternD = [checkOneUse, checkTwoUse, canonicalizeShiftAmt,
3932 AllowExtraUsesByDefault, &NegateNBits,
3945 canonicalizeShiftAmt(N1, Bitwidth);
3949 const bool AllowExtraUses = AllowExtraUsesByDefault && !NegateNBits;
3950 if (!checkOneUse(N0, AllowExtraUses) || !checkTwoUse(N1, AllowExtraUses))
3956 auto matchLowBitMask = [matchPatternA, matchPatternB,
3958 return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
3962 X =
Node->getOperand(0);
3965 if (matchLowBitMask(Mask)) {
3969 if (!matchLowBitMask(Mask))
3973 X = CurDAG->getAllOnesConstant(
SDLoc(
Node), NVT);
3974 }
else if (!matchPatternD(
Node))
3979 if (NegateNBits && !Subtarget->hasBMI2())
3991 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, MVT::i32), 0);
3994 SDValue SRIdxVal = CurDAG->getTargetConstant(X86::sub_8bit,
DL, MVT::i32);
3996 NBits =
SDValue(CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
DL,
3997 MVT::i32, ImplDef, NBits, SRIdxVal),
4007 NBits = CurDAG->getNode(
ISD::SUB,
DL, MVT::i32, BitWidthC, NBits);
4011 if (Subtarget->hasBMI2()) {
4013 if (NVT != MVT::i32) {
4021 SelectCode(Extract.
getNode());
4030 SDValue RealX = peekThroughOneUseTruncation(
X);
4036 MVT XVT =
X.getSimpleValueType();
4046 SDValue C8 = CurDAG->getConstant(8,
DL, MVT::i8);
4054 SDValue ShiftAmt =
X.getOperand(1);
4055 X =
X.getOperand(0);
4058 "Expected shift amount to be i8");
4062 SDValue OrigShiftAmt = ShiftAmt;
4067 Control = CurDAG->getNode(
ISD::OR,
DL, MVT::i32, Control, ShiftAmt);
4072 if (XVT != MVT::i32) {
4087 SelectCode(Extract.
getNode());
4094 MVT NVT =
Node->getSimpleValueType(0);
4107 Subtarget->hasTBM() || (Subtarget->hasBMI() && Subtarget->hasFastBEXTR());
4108 if (!PreferBEXTR && !Subtarget->hasBMI2())
4120 if (NVT != MVT::i32 && NVT != MVT::i64)
4124 auto *MaskCst = dyn_cast<ConstantSDNode>(N1);
4125 auto *ShiftCst = dyn_cast<ConstantSDNode>(N0->
getOperand(1));
4126 if (!MaskCst || !ShiftCst)
4134 uint64_t Shift = ShiftCst->getZExtValue();
4139 if (Shift == 8 && MaskSize == 8)
4150 if (!PreferBEXTR && MaskSize <= 32)
4154 unsigned ROpc, MOpc;
4156#define GET_EGPR_IF_ENABLED(OPC) (Subtarget->hasEGPR() ? OPC##_EVEX : OPC)
4158 assert(Subtarget->hasBMI2() &&
"We must have BMI2's BZHI then.");
4162 Control = CurDAG->getTargetConstant(Shift + MaskSize, dl, NVT);
4167 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4168 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4174 Control = CurDAG->getTargetConstant(Shift | (MaskSize << 8), dl, NVT);
4175 if (Subtarget->hasTBM()) {
4176 ROpc = NVT == MVT::i64 ? X86::BEXTRI64ri : X86::BEXTRI32ri;
4177 MOpc = NVT == MVT::i64 ? X86::BEXTRI64mi : X86::BEXTRI32mi;
4179 assert(Subtarget->hasBMI() &&
"We must have BMI1's BEXTR then.");
4185 unsigned NewOpc = NVT == MVT::i64 ? X86::MOV32ri64 : X86::MOV32ri;
4186 Control =
SDValue(CurDAG->getMachineNode(NewOpc, dl, NVT, Control), 0);
4192 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4193 if (tryFoldLoad(
Node, N0.
getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4195 Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Control, Input.
getOperand(0)};
4196 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
4197 NewNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
4201 CurDAG->setNodeMemRefs(NewNode, {cast<LoadSDNode>(Input)->getMemOperand()});
4203 NewNode = CurDAG->getMachineNode(ROpc, dl, NVT, MVT::i32, Input, Control);
4208 SDValue ShAmt = CurDAG->getTargetConstant(Shift, dl, NVT);
4212 CurDAG->getMachineNode(NewOpc, dl, NVT,
SDValue(NewNode, 0), ShAmt);
4219MachineSDNode *X86DAGToDAGISel::emitPCMPISTR(
unsigned ROpc,
unsigned MOpc,
4220 bool MayFoldLoad,
const SDLoc &dl,
4225 auto *Val = cast<ConstantSDNode>(Imm)->getConstantIntValue();
4226 Imm = CurDAG->getTargetConstant(*Val,
SDLoc(
Node),
Imm.getValueType());
4229 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4230 if (MayFoldLoad && tryFoldLoad(
Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4231 SDValue Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4233 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other);
4234 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
4238 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
4243 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32);
4244 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs, Ops);
4251MachineSDNode *X86DAGToDAGISel::emitPCMPESTR(
unsigned ROpc,
unsigned MOpc,
4252 bool MayFoldLoad,
const SDLoc &dl,
4258 auto *Val = cast<ConstantSDNode>(Imm)->getConstantIntValue();
4259 Imm = CurDAG->getTargetConstant(*Val,
SDLoc(
Node),
Imm.getValueType());
4262 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4263 if (MayFoldLoad && tryFoldLoad(
Node, N2, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4264 SDValue Ops[] = { N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
4266 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Other, MVT::Glue);
4267 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
4272 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N2)->getMemOperand()});
4277 SDVTList VTs = CurDAG->getVTList(VT, MVT::i32, MVT::Glue);
4278 MachineSDNode *CNode = CurDAG->getMachineNode(ROpc, dl, VTs, Ops);
4283bool X86DAGToDAGISel::tryShiftAmountMod(
SDNode *
N) {
4284 EVT VT =
N->getValueType(0);
4291 unsigned Size = VT == MVT::i64 ? 64 : 32;
4293 SDValue OrigShiftAmt =
N->getOperand(1);
4294 SDValue ShiftAmt = OrigShiftAmt;
4309 auto *Add0C = dyn_cast<ConstantSDNode>(Add0);
4310 auto *Add1C = dyn_cast<ConstantSDNode>(Add1);
4313 if (Add1C && Add1C->getAPIntValue().urem(
Size) == 0) {
4317 ((Add0C && Add0C->getAPIntValue().urem(
Size) ==
Size - 1) ||
4318 (Add1C && Add1C->getAPIntValue().urem(
Size) ==
Size - 1))) {
4322 assert(Add0C ==
nullptr || Add1C ==
nullptr);
4331 NewShiftAmt = CurDAG->getNode(
ISD::XOR,
DL, OpVT,
4332 Add0C ==
nullptr ? Add0 : Add1,
AllOnes);
4338 Add0C->getZExtValue() != 0) {
4341 if (Add0C->getZExtValue() %
Size == 0)
4344 Add0C->getZExtValue() % 32 == 0) {
4352 Add0 = CurDAG->getZExtOrTrunc(Add0,
DL, SubVT);
4356 X = CurDAG->getNode(
ISD::ADD,
DL, SubVT, Add1, Add0);
4378 NewShiftAmt = CurDAG->getNode(
ISD::TRUNCATE,
DL, MVT::i8, NewShiftAmt);
4385 NewShiftAmt = CurDAG->getNode(
ISD::AND,
DL, MVT::i8, NewShiftAmt,
4386 CurDAG->getConstant(
Size - 1,
DL, MVT::i8));
4390 SDNode *UpdatedNode = CurDAG->UpdateNodeOperands(
N,
N->getOperand(0),
4392 if (UpdatedNode !=
N) {
4395 ReplaceNode(
N, UpdatedNode);
4402 CurDAG->RemoveDeadNode(OrigShiftAmt.
getNode());
4410bool X86DAGToDAGISel::tryShrinkShlLogicImm(
SDNode *
N) {
4411 MVT NVT =
N->getSimpleValueType(0);
4412 unsigned Opcode =
N->getOpcode();
4420 auto *Cst = dyn_cast<ConstantSDNode>(N1);
4424 int64_t Val = Cst->getSExtValue();
4429 bool FoundAnyExtend =
false;
4433 FoundAnyExtend =
true;
4441 if (NVT != MVT::i32 && NVT != MVT::i64)
4444 auto *ShlCst = dyn_cast<ConstantSDNode>(Shift.
getOperand(1));
4448 uint64_t ShAmt = ShlCst->getZExtValue();
4452 uint64_t RemovedBitsMask = (1ULL << ShAmt) - 1;
4453 if (Opcode !=
ISD::AND && (Val & RemovedBitsMask) != 0)
4458 auto CanShrinkImmediate = [&](int64_t &ShiftedVal) {
4462 ShiftedVal = (
uint64_t)Val >> ShAmt;
4463 if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
4466 if (ShiftedVal == UINT8_MAX || ShiftedVal == UINT16_MAX)
4469 ShiftedVal = Val >> ShAmt;
4470 if ((!isInt<8>(Val) && isInt<8>(ShiftedVal)) ||
4471 (!isInt<32>(Val) && isInt<32>(ShiftedVal)))
4475 ShiftedVal = (
uint64_t)Val >> ShAmt;
4476 if (NVT == MVT::i64 && !isUInt<32>(Val) && isUInt<32>(ShiftedVal))
4483 if (!CanShrinkImmediate(ShiftedVal))
4493 unsigned ZExtWidth = Cst->getAPIntValue().getActiveBits();
4499 NeededMask &= ~Cst->getAPIntValue();
4501 if (CurDAG->MaskedValueIsZero(
N->getOperand(0), NeededMask))
4506 if (FoundAnyExtend) {
4512 SDValue NewCst = CurDAG->getSignedConstant(ShiftedVal, dl, NVT);
4514 SDValue NewBinOp = CurDAG->getNode(Opcode, dl, NVT,
X, NewCst);
4523bool X86DAGToDAGISel::matchVPTERNLOG(
SDNode *Root,
SDNode *ParentA,
4527 assert(
A.isOperandOf(ParentA) &&
B.isOperandOf(ParentB) &&
4528 C.isOperandOf(ParentC) &&
"Incorrect parent node");
4530 auto tryFoldLoadOrBCast =
4533 if (tryFoldLoad(Root,
P, L,
Base, Scale,
Index, Disp, Segment))
4539 L =
L.getOperand(0);
4546 auto *MemIntr = cast<MemIntrinsicSDNode>(L);
4547 unsigned Size = MemIntr->getMemoryVT().getSizeInBits();
4551 return tryFoldBroadcast(Root,
P, L,
Base, Scale,
Index, Disp, Segment);
4554 bool FoldedLoad =
false;
4555 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4556 if (tryFoldLoadOrBCast(Root, ParentC,
C, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
4558 }
else if (tryFoldLoadOrBCast(Root, ParentA,
A, Tmp0, Tmp1, Tmp2, Tmp3,
4563 uint8_t OldImm =
Imm;
4564 Imm = OldImm & 0xa5;
4565 if (OldImm & 0x02)
Imm |= 0x10;
4566 if (OldImm & 0x10)
Imm |= 0x02;
4567 if (OldImm & 0x08)
Imm |= 0x40;
4568 if (OldImm & 0x40)
Imm |= 0x08;
4569 }
else if (tryFoldLoadOrBCast(Root, ParentB,
B, Tmp0, Tmp1, Tmp2, Tmp3,
4574 uint8_t OldImm =
Imm;
4575 Imm = OldImm & 0x99;
4576 if (OldImm & 0x02)
Imm |= 0x04;
4577 if (OldImm & 0x04)
Imm |= 0x02;
4578 if (OldImm & 0x20)
Imm |= 0x40;
4579 if (OldImm & 0x40)
Imm |= 0x20;
4584 SDValue TImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i8);
4590 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
4594 auto *MemIntr = cast<MemIntrinsicSDNode>(
C);
4595 unsigned EltSize = MemIntr->getMemoryVT().getSizeInBits();
4596 assert((EltSize == 32 || EltSize == 64) &&
"Unexpected broadcast size!");
4598 bool UseD = EltSize == 32;
4600 Opc = UseD ? X86::VPTERNLOGDZ128rmbi : X86::VPTERNLOGQZ128rmbi;
4602 Opc = UseD ? X86::VPTERNLOGDZ256rmbi : X86::VPTERNLOGQZ256rmbi;
4604 Opc = UseD ? X86::VPTERNLOGDZrmbi : X86::VPTERNLOGQZrmbi;
4610 Opc = UseD ? X86::VPTERNLOGDZ128rmi : X86::VPTERNLOGQZ128rmi;
4612 Opc = UseD ? X86::VPTERNLOGDZ256rmi : X86::VPTERNLOGQZ256rmi;
4614 Opc = UseD ? X86::VPTERNLOGDZrmi : X86::VPTERNLOGQZrmi;
4619 SDValue Ops[] = {
A,
B, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, TImm,
C.getOperand(0)};
4620 MNode = CurDAG->getMachineNode(Opc,
DL, VTs, Ops);
4623 ReplaceUses(
C.getValue(1),
SDValue(MNode, 1));
4625 CurDAG->setNodeMemRefs(MNode, {cast<MemSDNode>(
C)->getMemOperand()});
4630 Opc = UseD ? X86::VPTERNLOGDZ128rri : X86::VPTERNLOGQZ128rri;
4632 Opc = UseD ? X86::VPTERNLOGDZ256rri : X86::VPTERNLOGQZ256rri;
4634 Opc = UseD ? X86::VPTERNLOGDZrri : X86::VPTERNLOGQZrri;
4638 MNode = CurDAG->getMachineNode(Opc,
DL, NVT, {
A,
B,
C, TImm});
4642 CurDAG->RemoveDeadNode(Root);
4648bool X86DAGToDAGISel::tryVPTERNLOG(
SDNode *
N) {
4649 MVT NVT =
N->getSimpleValueType(0);
4652 if (!NVT.
isVector() || !Subtarget->hasAVX512() ||
4663 auto getFoldableLogicOp = [](
SDValue Op) {
4666 Op =
Op.getOperand(0);
4668 if (!
Op.hasOneUse())
4671 unsigned Opc =
Op.getOpcode();
4680 if ((FoldableOp = getFoldableLogicOp(N1))) {
4682 }
else if ((FoldableOp = getFoldableLogicOp(N0))) {
4695 uint8_t TernlogMagicA = 0xf0;
4696 uint8_t TernlogMagicB = 0xcc;
4697 uint8_t TernlogMagicC = 0xaa;
4706 Parent =
Op.getNode();
4707 Op =
Op.getOperand(0);
4711 PeekThroughNot(
A, ParentA, TernlogMagicA);
4712 PeekThroughNot(
B, ParentB, TernlogMagicB);
4713 PeekThroughNot(
C, ParentC, TernlogMagicC);
4718 case ISD::AND:
Imm = TernlogMagicB & TernlogMagicC;
break;
4719 case ISD::OR:
Imm = TernlogMagicB | TernlogMagicC;
break;
4720 case ISD::XOR:
Imm = TernlogMagicB ^ TernlogMagicC;
break;
4724 switch (
N->getOpcode()) {
4728 Imm &= ~TernlogMagicA;
4730 Imm = ~(
Imm) & TernlogMagicA;
4737 return matchVPTERNLOG(
N, ParentA, ParentB, ParentC,
A,
B,
C, Imm);
4747bool X86DAGToDAGISel::shrinkAndImmediate(
SDNode *
And) {
4750 MVT VT =
And->getSimpleValueType(0);
4751 if (VT != MVT::i32 && VT != MVT::i64)
4754 auto *And1C = dyn_cast<ConstantSDNode>(
And->getOperand(1));
4763 APInt MaskVal = And1C->getAPIntValue();
4765 if (!MaskLZ || (VT == MVT::i64 && MaskLZ == 32))
4769 if (VT == MVT::i64 && MaskLZ >= 32) {
4771 MaskVal = MaskVal.
trunc(32);
4776 APInt NegMaskVal = MaskVal | HighZeros;
4785 if (VT == MVT::i64 && MaskVal.
getBitWidth() < 64) {
4786 NegMaskVal = NegMaskVal.
zext(64);
4787 HighZeros = HighZeros.
zext(64);
4792 if (!CurDAG->MaskedValueIsZero(And0, HighZeros))
4812 bool FoldedBCast,
bool Masked) {
4813#define VPTESTM_CASE(VT, SUFFIX) \
4816 return IsTestN ? X86::VPTESTNM##SUFFIX##k: X86::VPTESTM##SUFFIX##k; \
4817 return IsTestN ? X86::VPTESTNM##SUFFIX : X86::VPTESTM##SUFFIX;
4820#define VPTESTM_BROADCAST_CASES(SUFFIX) \
4821default: llvm_unreachable("Unexpected VT!"); \
4822VPTESTM_CASE(v4i32, DZ128##SUFFIX) \
4823VPTESTM_CASE(v2i64, QZ128##SUFFIX) \
4824VPTESTM_CASE(v8i32, DZ256##SUFFIX) \
4825VPTESTM_CASE(v4i64, QZ256##SUFFIX) \
4826VPTESTM_CASE(v16i32, DZ##SUFFIX) \
4827VPTESTM_CASE(v8i64, QZ##SUFFIX)
4829#define VPTESTM_FULL_CASES(SUFFIX) \
4830VPTESTM_BROADCAST_CASES(SUFFIX) \
4831VPTESTM_CASE(v16i8, BZ128##SUFFIX) \
4832VPTESTM_CASE(v8i16, WZ128##SUFFIX) \
4833VPTESTM_CASE(v32i8, BZ256##SUFFIX) \
4834VPTESTM_CASE(v16i16, WZ256##SUFFIX) \
4835VPTESTM_CASE(v64i8, BZ##SUFFIX) \
4836VPTESTM_CASE(v32i16, WZ##SUFFIX)
4854#undef VPTESTM_FULL_CASES
4855#undef VPTESTM_BROADCAST_CASES
4861bool X86DAGToDAGISel::tryVPTESTM(
SDNode *Root,
SDValue Setcc,
4863 assert(Subtarget->hasAVX512() &&
"Expected AVX512!");
4913 if (tryFoldLoad(Root,
P, L,
Base, Scale,
Index, Disp, Segment))
4918 if (CmpSVT != MVT::i32 && CmpSVT != MVT::i64)
4924 L =
L.getOperand(0);
4930 auto *MemIntr = cast<MemIntrinsicSDNode>(L);
4931 if (MemIntr->getMemoryVT().getSizeInBits() != CmpSVT.
getSizeInBits())
4934 return tryFoldBroadcast(Root,
P, L,
Base, Scale,
Index, Disp, Segment);
4938 bool CanFoldLoads = Src0 != Src1;
4940 bool FoldedLoad =
false;
4941 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
4943 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src1, Tmp0, Tmp1, Tmp2,
4947 FoldedLoad = tryFoldLoadOrBCast(Root, N0.
getNode(), Src0, Tmp0, Tmp1,
4956 bool IsMasked = InMask.
getNode() !=
nullptr;
4969 SDValue ImplDef =
SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, dl,
4971 Src0 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src0);
4974 Src1 = CurDAG->getTargetInsertSubreg(
SubReg, dl, CmpVT, ImplDef, Src1);
4979 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
4980 InMask =
SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
4981 dl, MaskVT, InMask, RC), 0);
4986 unsigned Opc =
getVPTESTMOpc(CmpVT, IsTestN, FoldedLoad, FoldedBCast,
4991 SDVTList VTs = CurDAG->getVTList(MaskVT, MVT::Other);
4994 SDValue Ops[] = { InMask, Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
4996 CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
4998 SDValue Ops[] = { Src0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
5000 CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
5006 CurDAG->setNodeMemRefs(CNode, {cast<MemSDNode>(Src1)->getMemOperand()});
5009 CNode = CurDAG->getMachineNode(Opc, dl, MaskVT, InMask, Src0, Src1);
5011 CNode = CurDAG->getMachineNode(Opc, dl, MaskVT, Src0, Src1);
5017 SDValue RC = CurDAG->getTargetConstant(RegClass, dl, MVT::i32);
5018 CNode = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
5019 dl, ResVT,
SDValue(CNode, 0), RC);
5023 CurDAG->RemoveDeadNode(Root);
5029bool X86DAGToDAGISel::tryMatchBitSelect(
SDNode *
N) {
5032 MVT NVT =
N->getSimpleValueType(0);
5035 if (!NVT.
isVector() || !Subtarget->hasAVX512())
5069 SDValue Imm = CurDAG->getTargetConstant(0xCA, dl, MVT::i8);
5078 MVT NVT =
Node->getSimpleValueType(0);
5079 unsigned Opcode =
Node->getOpcode();
5082 if (
Node->isMachineOpcode()) {
5084 Node->setNodeId(-1);
5091 unsigned IntNo =
Node->getConstantOperandVal(1);
5094 case Intrinsic::x86_encodekey128:
5095 case Intrinsic::x86_encodekey256: {
5096 if (!Subtarget->hasKL())
5102 case Intrinsic::x86_encodekey128:
5103 Opcode = X86::ENCODEKEY128;
5105 case Intrinsic::x86_encodekey256:
5106 Opcode = X86::ENCODEKEY256;
5111 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(3),
5113 if (Opcode == X86::ENCODEKEY256)
5114 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(4),
5118 Opcode, dl,
Node->getVTList(),
5119 {Node->getOperand(2), Chain, Chain.getValue(1)});
5120 ReplaceNode(
Node, Res);
5123 case Intrinsic::x86_tileloadd64_internal:
5124 case Intrinsic::x86_tileloaddt164_internal: {
5125 if (!Subtarget->hasAMXTILE())
5130 unsigned Opc = IntNo == Intrinsic::x86_tileloadd64_internal
5132 : X86::PTILELOADDT1V;
5135 SDValue Scale = getI8Imm(1, dl);
5137 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5138 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5142 Node->getOperand(3),
5149 CNode = CurDAG->getMachineNode(Opc, dl, {MVT::x86amx, MVT::Other}, Ops);
5150 ReplaceNode(
Node, CNode);
5157 unsigned IntNo =
Node->getConstantOperandVal(1);
5160 case Intrinsic::x86_sse3_monitor:
5161 case Intrinsic::x86_monitorx:
5162 case Intrinsic::x86_clzero: {
5163 bool Use64BitPtr =
Node->getOperand(2).getValueType() == MVT::i64;
5168 case Intrinsic::x86_sse3_monitor:
5169 if (!Subtarget->hasSSE3())
5171 Opc = Use64BitPtr ? X86::MONITOR64rrr : X86::MONITOR32rrr;
5173 case Intrinsic::x86_monitorx:
5174 if (!Subtarget->hasMWAITX())
5176 Opc = Use64BitPtr ? X86::MONITORX64rrr : X86::MONITORX32rrr;
5178 case Intrinsic::x86_clzero:
5179 if (!Subtarget->hasCLZERO())
5181 Opc = Use64BitPtr ? X86::CLZERO64r : X86::CLZERO32r;
5186 unsigned PtrReg = Use64BitPtr ? X86::RAX : X86::EAX;
5187 SDValue Chain = CurDAG->getCopyToReg(
Node->getOperand(0), dl, PtrReg,
5191 if (IntNo == Intrinsic::x86_sse3_monitor ||
5192 IntNo == Intrinsic::x86_monitorx) {
5194 Chain = CurDAG->getCopyToReg(Chain, dl, X86::ECX,
Node->getOperand(3),
5197 Chain = CurDAG->getCopyToReg(Chain, dl, X86::EDX,
Node->getOperand(4),
5202 MachineSDNode *CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other,
5204 ReplaceNode(
Node, CNode);
5210 case Intrinsic::x86_tilestored64_internal: {
5214 unsigned Opc = X86::PTILESTOREDV;
5217 SDValue Scale = getI8Imm(1, dl);
5219 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5220 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5224 Node->getOperand(3),
5230 Node->getOperand(6),
5232 CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
5233 ReplaceNode(
Node, CNode);
5236 case Intrinsic::x86_tileloadd64:
5237 case Intrinsic::x86_tileloaddt164:
5238 case Intrinsic::x86_tilestored64: {
5239 if (!Subtarget->hasAMXTILE())
5247 case Intrinsic::x86_tileloadd64: Opc = X86::PTILELOADD;
break;
5248 case Intrinsic::x86_tileloaddt164: Opc = X86::PTILELOADDT1;
break;
5249 case Intrinsic::x86_tilestored64: Opc = X86::PTILESTORED;
break;
5252 unsigned TIndex =
Node->getConstantOperandVal(2);
5253 SDValue TReg = getI8Imm(TIndex, dl);
5255 SDValue Scale = getI8Imm(1, dl);
5257 SDValue Disp = CurDAG->getTargetConstant(0, dl, MVT::i32);
5258 SDValue Segment = CurDAG->getRegister(0, MVT::i16);
5261 if (Opc == X86::PTILESTORED) {
5263 CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
5266 CNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
5268 ReplaceNode(
Node, CNode);
5276 if (Subtarget->isTargetNaCl())
5280 if (Subtarget->isTarget64BitILP32()) {
5285 assert(
Target.getValueType() == MVT::i32 &&
"Unexpected VT!");
5286 SDValue ZextTarget = CurDAG->getZExtOrTrunc(
Target, dl, MVT::i64);
5287 SDValue Brind = CurDAG->getNode(Opcode, dl, MVT::Other,
5288 Node->getOperand(0), ZextTarget);
5290 SelectCode(ZextTarget.
getNode());
5297 ReplaceNode(
Node, getGlobalBaseReg());
5305 CurDAG->RemoveDeadNode(
Node);
5311 if (matchBitExtract(
Node))
5316 if (tryShiftAmountMod(
Node))
5321 uint8_t
Imm =
Node->getConstantOperandVal(3);
5323 Node->getOperand(1),
Node->getOperand(2), Imm))
5329 if (tryVPTERNLOG(
Node))
5339 tryVPTESTM(
Node, N0, N1))
5342 tryVPTESTM(
Node, N1, N0))
5348 CurDAG->RemoveDeadNode(
Node);
5351 if (matchBitExtract(
Node))
5359 if (tryShrinkShlLogicImm(
Node))
5363 if (tryVPTERNLOG(
Node))
5378 if (!CurDAG->shouldOptForSize())
5382 if (NVT != MVT::i8 && NVT != MVT::i16 && NVT != MVT::i32 && NVT != MVT::i64)
5388 auto *Cst = dyn_cast<ConstantSDNode>(N1);
5392 int64_t Val = Cst->getSExtValue();
5396 if (!isInt<8>(Val) && !isInt<32>(Val))
5400 if (Opcode ==
ISD::ADD && (Val == 1 || Val == -1))
5404 if (!shouldAvoidImmediateInstFormsForSize(N1.
getNode()))
5408 unsigned ROpc, MOpc;
5517 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5518 if (tryFoldLoad(
Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5520 SDVTList VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5521 MachineSDNode *CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5525 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N0)->getMemOperand()});
5527 CurDAG->RemoveDeadNode(
Node);
5532 CurDAG->SelectNodeTo(
Node, ROpc, NVT, MVT::i32, N0, N1);
5545 unsigned LoReg, ROpc, MOpc;
5550 ROpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8r : X86::MUL8r;
5551 MOpc = Opcode ==
X86ISD::SMUL ? X86::IMUL8m : X86::MUL8m;
5570 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5571 bool FoldedLoad = tryFoldLoad(
Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5574 FoldedLoad = tryFoldLoad(
Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5579 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5588 VTs = CurDAG->getVTList(NVT, MVT::i32, MVT::Other);
5590 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32, MVT::Other);
5594 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5599 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
5605 VTs = CurDAG->getVTList(NVT, MVT::i32);
5607 VTs = CurDAG->getVTList(NVT, NVT, MVT::i32);
5609 CNode = CurDAG->getMachineNode(ROpc, dl, VTs, {N1, InGlue});
5614 CurDAG->RemoveDeadNode(
Node);
5624 unsigned LoReg, HiReg;
5626 bool UseMULX = !IsSigned && Subtarget->hasBMI2();
5631 Opc = UseMULXHi ? X86::MULX32Hrr
5633 : IsSigned ?
X86::IMUL32r
5635 MOpc = UseMULXHi ? X86::MULX32Hrm
5637 : IsSigned ?
X86::IMUL32m
5639 LoReg = UseMULX ? X86::EDX : X86::EAX;
5643 Opc = UseMULXHi ? X86::MULX64Hrr
5645 : IsSigned ?
X86::IMUL64r
5647 MOpc = UseMULXHi ? X86::MULX64Hrm
5649 : IsSigned ?
X86::IMUL64m
5651 LoReg = UseMULX ? X86::RDX : X86::RAX;
5656 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5657 bool foldedLoad = tryFoldLoad(
Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5660 foldedLoad = tryFoldLoad(
Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5665 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, LoReg,
5674 SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
5675 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5678 }
else if (UseMULX) {
5679 SDVTList VTs = CurDAG->getVTList(NVT, NVT, MVT::Other);
5680 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5685 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5686 CNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
5692 ReplaceUses(N1.
getValue(1), Chain);
5694 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
5696 SDValue Ops[] = { N1, InGlue };
5698 SDVTList VTs = CurDAG->getVTList(NVT);
5699 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
5701 }
else if (UseMULX) {
5702 SDVTList VTs = CurDAG->getVTList(NVT, NVT);
5703 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
5707 SDVTList VTs = CurDAG->getVTList(MVT::Glue);
5708 SDNode *CNode = CurDAG->getMachineNode(Opc, dl, VTs, Ops);
5716 assert(LoReg &&
"Register for low half is not defined!");
5717 ResLo = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg,
5728 assert(HiReg &&
"Register for high half is not defined!");
5729 ResHi = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, HiReg,
5738 CurDAG->RemoveDeadNode(
Node);
5747 unsigned ROpc, MOpc;
5752 case MVT::i8: ROpc = X86::DIV8r; MOpc = X86::DIV8m;
break;
5753 case MVT::i16: ROpc = X86::DIV16r; MOpc = X86::DIV16m;
break;
5754 case MVT::i32: ROpc = X86::DIV32r; MOpc = X86::DIV32m;
break;
5755 case MVT::i64: ROpc = X86::DIV64r; MOpc = X86::DIV64m;
break;
5760 case MVT::i8: ROpc = X86::IDIV8r; MOpc = X86::IDIV8m;
break;
5761 case MVT::i16: ROpc = X86::IDIV16r; MOpc = X86::IDIV16m;
break;
5762 case MVT::i32: ROpc = X86::IDIV32r; MOpc = X86::IDIV32m;
break;
5763 case MVT::i64: ROpc = X86::IDIV64r; MOpc = X86::IDIV64m;
break;
5767 unsigned LoReg, HiReg, ClrReg;
5768 unsigned SExtOpcode;
5772 LoReg = X86::AL; ClrReg = HiReg = X86::AH;
5776 LoReg = X86::AX; HiReg = X86::DX;
5778 SExtOpcode = X86::CWD;
5781 LoReg = X86::EAX; ClrReg = HiReg = X86::EDX;
5782 SExtOpcode = X86::CDQ;
5785 LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
5786 SExtOpcode = X86::CQO;
5790 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
5791 bool foldedLoad = tryFoldLoad(
Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
5792 bool signBitIsZero = CurDAG->SignBitIsZero(N0);
5795 if (NVT == MVT::i8) {
5798 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Chain;
5800 if (tryFoldLoad(
Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
5802 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rm8
5804 Move = CurDAG->getMachineNode(Opc, dl, MVT::i16, MVT::Other, Ops);
5806 ReplaceUses(N0.
getValue(1), Chain);
5808 CurDAG->setNodeMemRefs(Move, {cast<LoadSDNode>(N0)->getMemOperand()});
5810 unsigned Opc = (
isSigned && !signBitIsZero) ? X86::MOVSX16rr8
5812 Move = CurDAG->getMachineNode(Opc, dl, MVT::i16, N0);
5813 Chain = CurDAG->getEntryNode();
5815 Chain = CurDAG->getCopyToReg(Chain, dl, X86::AX,
SDValue(Move, 0),
5820 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
5821 LoReg, N0,
SDValue()).getValue(1);
5825 SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Glue, InGlue),0);
5828 SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
5830 CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, std::nullopt), 0);
5834 SDValue(CurDAG->getMachineNode(
5835 TargetOpcode::EXTRACT_SUBREG, dl, MVT::i16, ClrNode,
5836 CurDAG->getTargetConstant(X86::sub_16bit, dl,
5844 SDValue(CurDAG->getMachineNode(
5845 TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
5846 CurDAG->getTargetConstant(0, dl, MVT::i64), ClrNode,
5847 CurDAG->getTargetConstant(X86::sub_32bit, dl,
5855 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
5856 ClrNode, InGlue).getValue(1);
5864 CurDAG->getMachineNode(MOpc, dl, MVT::Other, MVT::Glue, Ops);
5869 CurDAG->setNodeMemRefs(CNode, {cast<LoadSDNode>(N1)->getMemOperand()});
5872 SDValue(CurDAG->getMachineNode(ROpc, dl, MVT::Glue, N1, InGlue), 0);
5882 if (HiReg == X86::AH && !
SDValue(
Node, 1).use_empty()) {
5883 SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
5884 unsigned AHExtOpcode =
5885 isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
5887 SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
5888 MVT::Glue, AHCopy, InGlue);
5893 CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
5901 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
5902 LoReg, NVT, InGlue);
5903 InGlue =
Result.getValue(2);
5910 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
5911 HiReg, NVT, InGlue);
5912 InGlue =
Result.getValue(2);
5917 CurDAG->RemoveDeadNode(
Node);
5926 SDValue N0 =
Node->getOperand(IsStrictCmp ? 1 : 0);
5927 SDValue N1 =
Node->getOperand(IsStrictCmp ? 2 : 1);
5933 if (Subtarget->canUseCMOV())
5942 Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
5945 Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
5948 Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
5953 IsStrictCmp ?
Node->getOperand(0) : CurDAG->getEntryNode();
5956 SDVTList VTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
5957 Chain =
SDValue(CurDAG->getMachineNode(Opc, dl, VTs, {N0, N1, Chain}), 0);
5960 Glue =
SDValue(CurDAG->getMachineNode(Opc, dl, MVT::Glue, N0, N1), 0);
5965 SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, Glue), 0);
5969 CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
5973 assert(Subtarget->canUseLAHFSAHF() &&
5974 "Target doesn't support SAHF or FCOMI?");
5975 SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract,
SDValue());
5978 CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.
getValue(1)), 0);
5984 CurDAG->RemoveDeadNode(
Node);
6005 unsigned TestOpc = CmpVT == MVT::i64 ? X86::TEST64rr
6008 NewNode = CurDAG->getMachineNode(TestOpc, dl, MVT::i32, BEXTR, BEXTR);
6010 CurDAG->RemoveDeadNode(
Node);
6024 auto *MaskC = dyn_cast<ConstantSDNode>(N0.
getOperand(1));
6042 unsigned TestOpcode;
6050 if (LeadingZeros == 0 && SavesBytes) {
6055 ShiftAmt = TrailingZeros;
6057 TestOpcode = X86::TEST64rr;
6058 }
else if (TrailingZeros == 0 && SavesBytes) {
6063 ShiftAmt = LeadingZeros;
6065 TestOpcode = X86::TEST64rr;
6066 }
else if (MaskC->hasOneUse() && !isInt<32>(Mask)) {
6069 unsigned PopCount = 64 - LeadingZeros - TrailingZeros;
6070 if (PopCount == 8) {
6072 ShiftAmt = TrailingZeros;
6073 SubRegIdx = X86::sub_8bit;
6075 TestOpcode = X86::TEST8rr;
6076 }
else if (PopCount == 16) {
6078 ShiftAmt = TrailingZeros;
6079 SubRegIdx = X86::sub_16bit;
6080 SubRegVT = MVT::i16;
6081 TestOpcode = X86::TEST16rr;
6082 }
else if (PopCount == 32) {
6084 ShiftAmt = TrailingZeros;
6085 SubRegIdx = X86::sub_32bit;
6086 SubRegVT = MVT::i32;
6087 TestOpcode = X86::TEST32rr;
6091 SDValue ShiftC = CurDAG->getTargetConstant(ShiftAmt, dl, MVT::i64);
6093 CurDAG->getMachineNode(ShiftOpcode, dl, MVT::i64, MVT::i32,
6096 if (SubRegIdx != 0) {
6098 CurDAG->getTargetExtractSubreg(SubRegIdx, dl, SubRegVT, Shift);
6101 CurDAG->getMachineNode(TestOpcode, dl, MVT::i32, Shift, Shift);
6109 unsigned ROpc, MOpc;
6116 if (isUInt<8>(Mask) &&
6117 (!(Mask & 0x80) || CmpVT == MVT::i8 ||
6121 SubRegOp = X86::sub_8bit;
6122 ROpc = X86::TEST8ri;
6123 MOpc = X86::TEST8mi;
6124 }
else if (OptForMinSize && isUInt<16>(Mask) &&
6125 (!(Mask & 0x8000) || CmpVT == MVT::i16 ||
6132 SubRegOp = X86::sub_16bit;
6133 ROpc = X86::TEST16ri;
6134 MOpc = X86::TEST16mi;
6135 }
else if (isUInt<32>(Mask) && N0.
getValueType() != MVT::i16 &&
6136 ((!(Mask & 0x80000000) &&
6139 (CmpVT != MVT::i16 || !(Mask & 0x8000))) ||
6140 CmpVT == MVT::i32 ||
6148 SubRegOp = X86::sub_32bit;
6149 ROpc = X86::TEST32ri;
6150 MOpc = X86::TEST32mi;
6156 SDValue Imm = CurDAG->getTargetConstant(Mask, dl, VT);
6161 SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
6162 if (tryFoldLoad(
Node, N0.
getNode(), Reg, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
6164 if (!LoadN->isSimple()) {
6166 if ((MOpc == X86::TEST8mi && NumVolBits != 8) ||
6167 (MOpc == X86::TEST16mi && NumVolBits != 16) ||
6168 (MOpc == X86::TEST32mi && NumVolBits != 32))
6172 SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4,
Imm,
6173 Reg.getOperand(0) };
6174 NewNode = CurDAG->getMachineNode(MOpc, dl, MVT::i32, MVT::Other, Ops);
6176 ReplaceUses(
Reg.getValue(1),
SDValue(NewNode, 1));
6178 CurDAG->setNodeMemRefs(NewNode,
6179 {cast<LoadSDNode>(Reg)->getMemOperand()});
6183 Reg = CurDAG->getTargetExtractSubreg(SubRegOp, dl, VT, Reg);
6185 NewNode = CurDAG->getMachineNode(ROpc, dl, MVT::i32, Reg, Imm);
6188 ReplaceNode(
Node, NewNode);
6194 if (!Subtarget->hasSSE42())
6200 bool MayFoldLoad = !NeedIndex || !NeedMask;
6205 Subtarget->hasAVX() ? X86::VPCMPISTRMrri : X86::PCMPISTRMrri;
6207 Subtarget->hasAVX() ? X86::VPCMPISTRMrmi : X86::PCMPISTRMrmi;
6208 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8,
Node);
6211 if (NeedIndex || !NeedMask) {
6213 Subtarget->hasAVX() ? X86::VPCMPISTRIrri : X86::PCMPISTRIrri;
6215 Subtarget->hasAVX() ? X86::VPCMPISTRIrmi : X86::PCMPISTRIrmi;
6216 CNode = emitPCMPISTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32,
Node);
6222 CurDAG->RemoveDeadNode(
Node);
6226 if (!Subtarget->hasSSE42())
6230 SDValue InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EAX,
6231 Node->getOperand(1),
6233 InGlue = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EDX,
6234 Node->getOperand(3), InGlue).getValue(1);
6239 bool MayFoldLoad = !NeedIndex || !NeedMask;
6244 Subtarget->hasAVX() ? X86::VPCMPESTRMrri : X86::PCMPESTRMrri;
6246 Subtarget->hasAVX() ? X86::VPCMPESTRMrmi : X86::PCMPESTRMrmi;
6248 emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::v16i8,
Node, InGlue);
6251 if (NeedIndex || !NeedMask) {
6253 Subtarget->hasAVX() ? X86::VPCMPESTRIrri : X86::PCMPESTRIrri;
6255 Subtarget->hasAVX() ? X86::VPCMPESTRIrmi : X86::PCMPESTRIrmi;
6256 CNode = emitPCMPESTR(ROpc, MOpc, MayFoldLoad, dl, MVT::i32,
Node, InGlue);
6261 CurDAG->RemoveDeadNode(
Node);
6273 if (foldLoadStoreIntoMemOperand(
Node))
6278 MVT VT =
Node->getSimpleValueType(0);
6280 if (Subtarget->hasSBBDepBreaking()) {
6285 CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
6290 unsigned Opc = VT == MVT::i64 ? X86::SETB_C64r : X86::SETB_C32r;
6291 MVT SetVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
6293 CurDAG->getMachineNode(Opc, dl, SetVT, EFLAGS, EFLAGS.
getValue(1)),
6302 if (VT == MVT::i8 || VT == MVT::i16) {
6303 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6304 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6308 CurDAG->RemoveDeadNode(
Node);
6322 MVT VT =
Node->getSimpleValueType(0);
6323 if (VT == MVT::i8 || VT == MVT::i16) {
6324 int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
6325 Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
6330 CurDAG->RemoveDeadNode(
Node);
6336 auto *Mgt = cast<X86MaskedGatherSDNode>(
Node);
6337 SDValue IndexOp = Mgt->getIndex();
6340 MVT ValueVT =
Node->getSimpleValueType(0);
6341 MVT MaskVT =
Mask.getSimpleValueType();
6358 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6359 Opc = IsFP ? X86::VGATHERDPSZ128rm : X86::VPGATHERDDZ128rm;
6360 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6361 Opc = IsFP ? X86::VGATHERDPSZ256rm : X86::VPGATHERDDZ256rm;
6362 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6363 Opc = IsFP ? X86::VGATHERDPSZrm : X86::VPGATHERDDZrm;
6364 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6365 Opc = IsFP ? X86::VGATHERDPDZ128rm : X86::VPGATHERDQZ128rm;
6366 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6367 Opc = IsFP ? X86::VGATHERDPDZ256rm : X86::VPGATHERDQZ256rm;
6368 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6369 Opc = IsFP ? X86::VGATHERDPDZrm : X86::VPGATHERDQZrm;
6370 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6371 Opc = IsFP ? X86::VGATHERQPSZ128rm : X86::VPGATHERQDZ128rm;
6372 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6373 Opc = IsFP ? X86::VGATHERQPSZ256rm : X86::VPGATHERQDZ256rm;
6374 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6375 Opc = IsFP ? X86::VGATHERQPSZrm : X86::VPGATHERQDZrm;
6376 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6377 Opc = IsFP ? X86::VGATHERQPDZ128rm : X86::VPGATHERQQZ128rm;
6378 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6379 Opc = IsFP ? X86::VGATHERQPDZ256rm : X86::VPGATHERQQZ256rm;
6380 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6381 Opc = IsFP ? X86::VGATHERQPDZrm : X86::VPGATHERQQZrm;
6383 assert(
EVT(MaskVT) ==
EVT(ValueVT).changeVectorElementTypeToInteger() &&
6384 "Unexpected mask VT!");
6385 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6386 Opc = IsFP ? X86::VGATHERDPSrm : X86::VPGATHERDDrm;
6387 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6388 Opc = IsFP ? X86::VGATHERDPSYrm : X86::VPGATHERDDYrm;
6389 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6390 Opc = IsFP ? X86::VGATHERDPDrm : X86::VPGATHERDQrm;
6391 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6392 Opc = IsFP ? X86::VGATHERDPDYrm : X86::VPGATHERDQYrm;
6393 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6394 Opc = IsFP ? X86::VGATHERQPSrm : X86::VPGATHERQDrm;
6395 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6396 Opc = IsFP ? X86::VGATHERQPSYrm : X86::VPGATHERQDYrm;
6397 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6398 Opc = IsFP ? X86::VGATHERQPDrm : X86::VPGATHERQQrm;
6399 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6400 Opc = IsFP ? X86::VGATHERQPDYrm : X86::VPGATHERQQYrm;
6407 if (!selectVectorAddr(Mgt, Mgt->getBasePtr(), IndexOp, Mgt->getScale(),
6411 SDValue PassThru = Mgt->getPassThru();
6412 SDValue Chain = Mgt->getChain();
6414 SDVTList VTs = CurDAG->getVTList(ValueVT, MaskVT, MVT::Other);
6419 Index, Disp, Segment, Chain};
6420 NewNode = CurDAG->getMachineNode(Opc,
SDLoc(dl), VTs, Ops);
6423 Disp, Segment,
Mask, Chain};
6424 NewNode = CurDAG->getMachineNode(Opc,
SDLoc(dl), VTs, Ops);
6426 CurDAG->setNodeMemRefs(NewNode, {Mgt->getMemOperand()});
6429 CurDAG->RemoveDeadNode(
Node);
6433 auto *Sc = cast<X86MaskedScatterSDNode>(
Node);
6435 SDValue IndexOp = Sc->getIndex();
6437 MVT ValueVT =
Value.getSimpleValueType();
6452 if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 32)
6453 Opc = IsFP ? X86::VSCATTERDPSZ128mr : X86::VPSCATTERDDZ128mr;
6454 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 32)
6455 Opc = IsFP ? X86::VSCATTERDPSZ256mr : X86::VPSCATTERDDZ256mr;
6456 else if (IndexVT == MVT::v16i32 && NumElts == 16 && EltSize == 32)
6457 Opc = IsFP ? X86::VSCATTERDPSZmr : X86::VPSCATTERDDZmr;
6458 else if (IndexVT == MVT::v4i32 && NumElts == 2 && EltSize == 64)
6459 Opc = IsFP ? X86::VSCATTERDPDZ128mr : X86::VPSCATTERDQZ128mr;
6460 else if (IndexVT == MVT::v4i32 && NumElts == 4 && EltSize == 64)
6461 Opc = IsFP ? X86::VSCATTERDPDZ256mr : X86::VPSCATTERDQZ256mr;
6462 else if (IndexVT == MVT::v8i32 && NumElts == 8 && EltSize == 64)
6463 Opc = IsFP ? X86::VSCATTERDPDZmr : X86::VPSCATTERDQZmr;
6464 else if (IndexVT == MVT::v2i64 && NumElts == 4 && EltSize == 32)
6465 Opc = IsFP ? X86::VSCATTERQPSZ128mr : X86::VPSCATTERQDZ128mr;
6466 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 32)
6467 Opc = IsFP ? X86::VSCATTERQPSZ256mr : X86::VPSCATTERQDZ256mr;
6468 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 32)
6469 Opc = IsFP ? X86::VSCATTERQPSZmr : X86::VPSCATTERQDZmr;
6470 else if (IndexVT == MVT::v2i64 && NumElts == 2 && EltSize == 64)
6471 Opc = IsFP ? X86::VSCATTERQPDZ128mr : X86::VPSCATTERQQZ128mr;
6472 else if (IndexVT == MVT::v4i64 && NumElts == 4 && EltSize == 64)
6473 Opc = IsFP ? X86::VSCATTERQPDZ256mr : X86::VPSCATTERQQZ256mr;
6474 else if (IndexVT == MVT::v8i64 && NumElts == 8 && EltSize == 64)
6475 Opc = IsFP ? X86::VSCATTERQPDZmr : X86::VPSCATTERQQZmr;
6480 if (!selectVectorAddr(Sc, Sc->getBasePtr(), IndexOp, Sc->getScale(),
6485 SDValue Chain = Sc->getChain();
6487 SDVTList VTs = CurDAG->getVTList(
Mask.getValueType(), MVT::Other);
6491 CurDAG->setNodeMemRefs(NewNode, {Sc->getMemOperand()});
6493 CurDAG->RemoveDeadNode(
Node);
6499 cast<SrcValueSDNode>(
Node->getOperand(1))->getValue());
6501 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6503 TargetOpcode::PREALLOCATED_SETUP, dl, MVT::Other, CallIdValue, Chain);
6505 CurDAG->RemoveDeadNode(
Node);
6511 cast<SrcValueSDNode>(
Node->getOperand(1))->getValue());
6513 SDValue CallIdValue = CurDAG->getTargetConstant(CallId, dl, MVT::i32);
6516 Ops[0] = CallIdValue;
6520 TargetOpcode::PREALLOCATED_ARG, dl,
6521 CurDAG->getVTList(TLI->
getPointerTy(CurDAG->getDataLayout()),
6526 CurDAG->RemoveDeadNode(
Node);
6533 if (!Subtarget->hasWIDEKL())
6537 switch (
Node->getOpcode()) {
6541 Opcode = X86::AESENCWIDE128KL;
6544 Opcode = X86::AESDECWIDE128KL;
6547 Opcode = X86::AESENCWIDE256KL;
6550 Opcode = X86::AESDECWIDE256KL;
6561 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM0,
Node->getOperand(2),
6563 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM1,
Node->getOperand(3),
6565 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM2,
Node->getOperand(4),
6567 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM3,
Node->getOperand(5),
6569 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM4,
Node->getOperand(6),
6571 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM5,
Node->getOperand(7),
6573 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM6,
Node->getOperand(8),
6575 Chain = CurDAG->getCopyToReg(Chain, dl, X86::XMM7,
Node->getOperand(9),
6579 Opcode, dl,
Node->getVTList(),
6580 {Base, Scale, Index, Disp, Segment, Chain, Chain.getValue(1)});
6581 CurDAG->setNodeMemRefs(Res, cast<MemSDNode>(
Node)->getMemOperand());
6582 ReplaceNode(
Node, Res);
6590bool X86DAGToDAGISel::SelectInlineAsmMemoryOperand(
6592 std::vector<SDValue> &OutOps) {
6593 SDValue Op0, Op1, Op2, Op3, Op4;
6594 switch (ConstraintID) {
6597 case InlineAsm::ConstraintCode::o:
6598 case InlineAsm::ConstraintCode::v:
6599 case InlineAsm::ConstraintCode::m:
6600 case InlineAsm::ConstraintCode::X:
6601 case InlineAsm::ConstraintCode::p:
6602 if (!selectAddr(
nullptr,
Op, Op0, Op1, Op2, Op3, Op4))
6607 OutOps.push_back(Op0);
6608 OutOps.push_back(Op1);
6609 OutOps.push_back(Op2);
6610 OutOps.push_back(Op3);
6611 OutOps.push_back(Op4);
6617 std::make_unique<X86DAGToDAGISel>(TM, TM.getOptLevel())) {}
6623 return new X86DAGToDAGISelLegacy(TM, OptLevel);
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
amdgpu 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")
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 isDispSafeForFrameIndex(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.
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...
This class provides iterator support for SDUse operands that use a specific SDNode.
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
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
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
static use_iterator use_end()
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)
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.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ PREALLOCATED_SETUP
PREALLOCATED_SETUP - This has 2 operands: an input chain and a SRCVALUE with the preallocated call Va...
@ PREALLOCATED_ARG
PREALLOCATED_ARG - This has 3 operands: an input chain, a SRCVALUE with the preallocated call Value,...
@ BRIND
BRIND - Indirect branch.
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ LOCAL_RECOVER
LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
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.
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ FST
This instruction implements a truncating store from FP stack slots.
@ CMPM
Vector comparison generating mask bits for fp and integer signed and unsigned data types.
@ CMP
X86 compare and logical compare instructions.
@ BLENDV
Dynamic (non-constant condition) vector blend where only the sign bits of the condition elements are ...
@ STRICT_FCMP
X86 strict FP compare instructions.
@ 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.
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.