27#include "llvm/IR/IntrinsicsS390.h"
37#define DEBUG_TYPE "systemz-lower"
43 cl::desc(
"Verify that narrow int args are properly extended per the "
50 : Op0(Op0In), Op1(Op1In), Chain(ChainIn),
51 Opcode(0), ICmpType(0), CCValid(0), CCMask(0) {}
101 if (Subtarget.hasHighWord())
107 if (Subtarget.hasVector()) {
116 if (Subtarget.hasVectorEnhancements1())
121 if (Subtarget.hasVector()) {
130 if (Subtarget.hasVector())
157 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
158 I <= MVT::LAST_FP_VALUETYPE;
184 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
185 I <= MVT::LAST_INTEGER_VALUETYPE;
216 if (Subtarget.hasPopulationCount())
242 (!Subtarget.hasFPExtension() && VT == MVT::i32) ?
Promote :
Custom;
263 if (!Subtarget.hasVectorEnhancements3()) {
290 if (Subtarget.hasVectorEnhancements3()) {
333 {MVT::i8, MVT::i16, MVT::i32},
Legal);
335 {MVT::i8, MVT::i16},
Legal);
356 if (Subtarget.hasMiscellaneousExtensions4()) {
363 if (Subtarget.hasMiscellaneousExtensions3()) {
456 if (VT != MVT::v2i64 || Subtarget.hasVectorEnhancements3()) {
461 if (Subtarget.hasVectorEnhancements3() &&
462 VT != MVT::v16i8 && VT != MVT::v8i16) {
472 if (Subtarget.hasVectorEnhancements1())
506 if (Subtarget.hasVector()) {
528 if (Subtarget.hasVectorEnhancements2()) {
554 for (
MVT VT : {MVT::f32, MVT::f64, MVT::f128}) {
558 for (
auto Op : {ISD::LOAD, ISD::ATOMIC_LOAD, ISD::STORE, ISD::ATOMIC_STORE})
568 for (
unsigned I = MVT::FIRST_FP_VALUETYPE;
569 I <= MVT::LAST_FP_VALUETYPE;
577 if (Subtarget.hasFPExtension()) {
605 if (Subtarget.hasFPExtension()) {
621 if (Subtarget.hasVector()) {
669 if (Subtarget.hasVectorEnhancements1()) {
676 if (Subtarget.hasVectorEnhancements1()) {
732 for (
auto VT : { MVT::f32, MVT::f64, MVT::f128,
733 MVT::v4f32, MVT::v2f64 }) {
742 if (!Subtarget.hasVectorEnhancements1()) {
748 if (Subtarget.hasVectorEnhancements1())
758 if (Subtarget.hasVectorEnhancements1()) {
770 if (!Subtarget.hasVector()) {
781 if (Subtarget.isTargetzOS()) {
842 return Subtarget.hasSoftFloat();
867 return Subtarget.hasVectorEnhancements1();
880 if (!Subtarget.hasVector() ||
881 (isFP128 && !Subtarget.hasVectorEnhancements1()))
890 uint64_t Byte = IntBits.lshr(
I * 8).trunc(8).getZExtValue();
897 Opcode = SystemZISD::BYTE_MASK;
903 if (SplatBitSize > 64)
910 OpVals.push_back(((
unsigned) SignedValue));
911 Opcode = SystemZISD::REPLICATE;
918 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start, End)) {
922 OpVals.push_back(Start - (64 - SplatBitSize));
923 OpVals.push_back(End - (64 - SplatBitSize));
924 Opcode = SystemZISD::ROTATE_MASK;
936 uint64_t SplatBitsZ = SplatBits.getZExtValue();
937 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
949 return TryValue(SplatBitsZ | Middle);
958 assert(IntBits.getBitWidth() == 128 &&
"Unsupported APInt.");
964 unsigned HalfSize = Width / 2;
969 if (HighValue != LowValue || 8 > HalfSize)
972 SplatBits = HighValue;
976 SplatBitSize = Width;
984 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
988 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
993 bool ForCodeSize)
const {
995 if (Imm.isZero() || Imm.isNegZero())
1016 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1018 Register MainDstReg =
MRI.createVirtualRegister(RC);
1019 Register RestoreDstReg =
MRI.createVirtualRegister(RC);
1022 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1075 const int64_t FPOffset = 0;
1084 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
1096 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1097 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1100 .
addReg(SpecialRegs->getFramePointerRegister())
1108 .
addReg(SpecialRegs->getStackPointerRegister())
1116 Register BCReg =
MRI.createVirtualRegister(PtrRC);
1119 .
addReg(SpecialRegs->getStackPointerRegister())
1120 .
addImm(TFL->getBackchainOffset(*MF))
1131 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1135 MIB.
addRegMask(RegInfo->getNoPreservedMask());
1156 MI.eraseFromParent();
1172 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1175 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1182 const int64_t FPOffset = 0;
1194 SpecialRegs->getFramePointerRegister())
1216 SpecialRegs->getStackPointerRegister())
1225 .
addReg(SpecialRegs->getStackPointerRegister())
1226 .
addImm(TFL->getBackchainOffset(*MF))
1232 MI.eraseFromParent();
1262 if (Subtarget.hasInterlockedAccess1() &&
1295 EVT VT =
Y.getValueType();
1298 if (VT == MVT::i32 || VT == MVT::i64)
1299 return Subtarget.hasMiscellaneousExtensions3();
1302 if (VT.
isVector() || VT == MVT::i128)
1303 return Subtarget.hasVector();
1331 bool MVC = Ty->isIntegerTy(8);
1337static AddressingMode
1340 switch (
II->getIntrinsicID()) {
1342 case Intrinsic::memset:
1343 case Intrinsic::memmove:
1344 case Intrinsic::memcpy:
1351 if (SingleUser->getParent() ==
I->getParent()) {
1354 if (
C->getBitWidth() <= 64 &&
1364 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1378 I->getOperand(0)->getType());
1380 bool IsVectorAccess = MemAccessTy->isVectorTy();
1385 Value *DataOp =
I->getOperand(0);
1387 IsVectorAccess =
true;
1393 User *LoadUser = *
I->user_begin();
1395 IsVectorAccess =
true;
1398 if (IsFPAccess || IsVectorAccess)
1417 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1427 return AM.
Scale == 0;
1434 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1435 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1436 const AttributeList &FuncAttributes)
const {
1437 const int MVCFastLen = 16;
1439 if (Limit != ~
unsigned(0)) {
1441 if (
Op.isMemcpy() &&
Op.allowOverlap() &&
Op.size() <= MVCFastLen)
1443 if (
Op.isMemset() &&
Op.size() - 1 <= MVCFastLen)
1445 if (
Op.isZeroMemset())
1450 DstAS, SrcAS, FuncAttributes);
1455 const AttributeList &FuncAttributes)
const {
1456 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1460 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1462 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1464 return FromBits > ToBits;
1472 return FromBits > ToBits;
1481 if (Constraint.
size() == 1) {
1482 switch (Constraint[0]) {
1508 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1509 switch (Constraint[1]) {
1520 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1530 Value *CallOperandVal = Info.CallOperandVal;
1533 if (!CallOperandVal)
1537 switch (*Constraint) {
1556 if (Subtarget.hasVector())
1587 if (
C->getZExtValue() == 0x7fffffff)
1597static std::pair<unsigned, const TargetRegisterClass *>
1599 const unsigned *Map,
unsigned Size) {
1600 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1601 if (isdigit(Constraint[2])) {
1606 return std::make_pair(Map[Index], RC);
1608 return std::make_pair(0U,
nullptr);
1611std::pair<unsigned, const TargetRegisterClass *>
1614 if (Constraint.
size() == 1) {
1616 switch (Constraint[0]) {
1621 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1623 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1624 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1628 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1629 else if (VT == MVT::i128)
1630 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1631 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1634 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1639 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1641 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1643 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1644 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1649 if (Subtarget.hasVector()) {
1651 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1653 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1655 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1656 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1665 auto getVTSizeInBits = [&VT]() {
1673 if (Constraint[1] ==
'r') {
1674 if (getVTSizeInBits() == 32)
1677 if (getVTSizeInBits() == 128)
1683 if (Constraint[1] ==
'f') {
1685 return std::make_pair(
1687 if (getVTSizeInBits() == 16)
1690 if (getVTSizeInBits() == 32)
1693 if (getVTSizeInBits() == 128)
1699 if (Constraint[1] ==
'v') {
1700 if (!Subtarget.hasVector())
1701 return std::make_pair(
1703 if (getVTSizeInBits() == 16)
1706 if (getVTSizeInBits() == 32)
1709 if (getVTSizeInBits() == 64)
1715 if (Constraint[1] ==
'@') {
1716 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1717 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1730 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1731 : SystemZ::NoRegister)
1733 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1740 const Constant *PersonalityFn)
const {
1741 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1745 const Constant *PersonalityFn)
const {
1746 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1761 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1765 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1766 OpInfo.ConstraintVT.getSizeInBits() < 8)
1781 if (Constraint.
size() == 1) {
1782 switch (Constraint[0]) {
1787 Op.getValueType()));
1794 Op.getValueType()));
1801 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1808 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1813 if (
C->getZExtValue() == 0x7fffffff)
1815 Op.getValueType()));
1826#include "SystemZGenCallingConv.inc"
1830 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1836 Type *ToType)
const {
1899 if (BitCastToType == MVT::v2i64)
1926 MVT::Untyped,
Hi,
Lo);
1950 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
1952 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1963 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
1964 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1975template <
class ArgTy>
1978 MVT &PartVT,
unsigned &NumParts) {
1979 if (!Args[
I].Flags.isSplit())
1983 PartVT = ArgLocs[
I].getValVT();
1985 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
1986 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
1987 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
1989 if (Args[PartIdx].Flags.isSplitEnd())
2013 unsigned NumFixedGPRs = 0;
2014 unsigned NumFixedFPRs = 0;
2015 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2028 RC = &SystemZ::GR32BitRegClass;
2032 RC = &SystemZ::GR64BitRegClass;
2036 RC = &SystemZ::FP16BitRegClass;
2040 RC = &SystemZ::FP32BitRegClass;
2044 RC = &SystemZ::FP64BitRegClass;
2048 RC = &SystemZ::FP128BitRegClass;
2056 RC = &SystemZ::VR128BitRegClass;
2070 if (Subtarget.isTargetXPLINK64()) {
2073 ArgSPOffset += XPRegs.getCallFrameSize();
2084 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2088 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2108 unsigned SplitBaseOffs = Ins[
I].PartOffset;
2109 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2112 unsigned PartOffset = Ins[
I].PartOffset - SplitBaseOffs;
2117 assert(PartOffset &&
"Offset should be non-zero.");
2124 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2130 Subtarget.getSpecialRegisters());
2136 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2141 if (IsVarArg && Subtarget.isTargetELF()) {
2154 int64_t RegSaveOffset =
2169 &SystemZ::FP64BitRegClass);
2181 if (Subtarget.isTargetXPLINK64()) {
2186 Subtarget.getSpecialRegisters());
2187 MRI.addLiveIn(Regs->getADARegister(), ADAvReg);
2199 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2206 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2208 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2215 unsigned Offset,
bool LoadAdr =
false) {
2238 bool LoadAddr =
false;
2260 unsigned ADADelta = 0;
2261 unsigned EPADelta = 8;
2267 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2268 G->getGlobal()->hasPrivateLinkage());
2275 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2321 if (Subtarget.isTargetXPLINK64())
2325 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2329 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2348 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2356 unsigned NumParts = 1;
2360 SlotVT = Outs[
I].VT;
2368 assert(Outs[
I].PartOffset == 0);
2369 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2372 unsigned PartOffset = Outs[
I].PartOffset;
2378 assert(PartOffset &&
"Offset should be non-zero.");
2380 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2382 ArgValue = SpillSlot;
2399 if (!StackPtr.getNode())
2406 else if (VA.
getLocVT() == MVT::f16)
2419 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2423 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2429 if (!MemOpChains.
empty())
2437 if (Subtarget.isTargetXPLINK64()) {
2442 ->getAddressOfCalleeRegister();
2445 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2452 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2455 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2456 }
else if (IsTailCall) {
2459 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2464 for (
const auto &[Reg,
N] : RegsToPass) {
2471 Ops.push_back(Chain);
2472 Ops.push_back(Callee);
2476 for (
const auto &[Reg,
N] : RegsToPass)
2481 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2482 assert(Mask &&
"Missing call preserved mask for calling convention");
2487 Ops.push_back(Glue);
2496 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2506 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2513 VA.getLocVT(), Glue);
2530 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2532 Args.reserve(
Ops.size());
2538 Entry.IsZExt = !Entry.IsSExt;
2539 Args.push_back(Entry);
2550 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2561 const Type *RetTy)
const {
2564 for (
auto &Out : Outs)
2565 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2569 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2570 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2582 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2590 if (RetLocs.
empty())
2591 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2600 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2622 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2629 unsigned &CCValid) {
2630 unsigned Id =
Op.getConstantOperandVal(1);
2632 case Intrinsic::s390_tbegin:
2633 Opcode = SystemZISD::TBEGIN;
2637 case Intrinsic::s390_tbegin_nofloat:
2638 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2642 case Intrinsic::s390_tend:
2643 Opcode = SystemZISD::TEND;
2656 unsigned Id =
Op.getConstantOperandVal(0);
2658 case Intrinsic::s390_vpkshs:
2659 case Intrinsic::s390_vpksfs:
2660 case Intrinsic::s390_vpksgs:
2661 Opcode = SystemZISD::PACKS_CC;
2665 case Intrinsic::s390_vpklshs:
2666 case Intrinsic::s390_vpklsfs:
2667 case Intrinsic::s390_vpklsgs:
2668 Opcode = SystemZISD::PACKLS_CC;
2672 case Intrinsic::s390_vceqbs:
2673 case Intrinsic::s390_vceqhs:
2674 case Intrinsic::s390_vceqfs:
2675 case Intrinsic::s390_vceqgs:
2676 case Intrinsic::s390_vceqqs:
2677 Opcode = SystemZISD::VICMPES;
2681 case Intrinsic::s390_vchbs:
2682 case Intrinsic::s390_vchhs:
2683 case Intrinsic::s390_vchfs:
2684 case Intrinsic::s390_vchgs:
2685 case Intrinsic::s390_vchqs:
2686 Opcode = SystemZISD::VICMPHS;
2690 case Intrinsic::s390_vchlbs:
2691 case Intrinsic::s390_vchlhs:
2692 case Intrinsic::s390_vchlfs:
2693 case Intrinsic::s390_vchlgs:
2694 case Intrinsic::s390_vchlqs:
2695 Opcode = SystemZISD::VICMPHLS;
2699 case Intrinsic::s390_vtm:
2700 Opcode = SystemZISD::VTM;
2704 case Intrinsic::s390_vfaebs:
2705 case Intrinsic::s390_vfaehs:
2706 case Intrinsic::s390_vfaefs:
2707 Opcode = SystemZISD::VFAE_CC;
2711 case Intrinsic::s390_vfaezbs:
2712 case Intrinsic::s390_vfaezhs:
2713 case Intrinsic::s390_vfaezfs:
2714 Opcode = SystemZISD::VFAEZ_CC;
2718 case Intrinsic::s390_vfeebs:
2719 case Intrinsic::s390_vfeehs:
2720 case Intrinsic::s390_vfeefs:
2721 Opcode = SystemZISD::VFEE_CC;
2725 case Intrinsic::s390_vfeezbs:
2726 case Intrinsic::s390_vfeezhs:
2727 case Intrinsic::s390_vfeezfs:
2728 Opcode = SystemZISD::VFEEZ_CC;
2732 case Intrinsic::s390_vfenebs:
2733 case Intrinsic::s390_vfenehs:
2734 case Intrinsic::s390_vfenefs:
2735 Opcode = SystemZISD::VFENE_CC;
2739 case Intrinsic::s390_vfenezbs:
2740 case Intrinsic::s390_vfenezhs:
2741 case Intrinsic::s390_vfenezfs:
2742 Opcode = SystemZISD::VFENEZ_CC;
2746 case Intrinsic::s390_vistrbs:
2747 case Intrinsic::s390_vistrhs:
2748 case Intrinsic::s390_vistrfs:
2749 Opcode = SystemZISD::VISTR_CC;
2753 case Intrinsic::s390_vstrcbs:
2754 case Intrinsic::s390_vstrchs:
2755 case Intrinsic::s390_vstrcfs:
2756 Opcode = SystemZISD::VSTRC_CC;
2760 case Intrinsic::s390_vstrczbs:
2761 case Intrinsic::s390_vstrczhs:
2762 case Intrinsic::s390_vstrczfs:
2763 Opcode = SystemZISD::VSTRCZ_CC;
2767 case Intrinsic::s390_vstrsb:
2768 case Intrinsic::s390_vstrsh:
2769 case Intrinsic::s390_vstrsf:
2770 Opcode = SystemZISD::VSTRS_CC;
2774 case Intrinsic::s390_vstrszb:
2775 case Intrinsic::s390_vstrszh:
2776 case Intrinsic::s390_vstrszf:
2777 Opcode = SystemZISD::VSTRSZ_CC;
2781 case Intrinsic::s390_vfcedbs:
2782 case Intrinsic::s390_vfcesbs:
2783 Opcode = SystemZISD::VFCMPES;
2787 case Intrinsic::s390_vfchdbs:
2788 case Intrinsic::s390_vfchsbs:
2789 Opcode = SystemZISD::VFCMPHS;
2793 case Intrinsic::s390_vfchedbs:
2794 case Intrinsic::s390_vfchesbs:
2795 Opcode = SystemZISD::VFCMPHES;
2799 case Intrinsic::s390_vftcidb:
2800 case Intrinsic::s390_vftcisb:
2801 Opcode = SystemZISD::VFTCI;
2805 case Intrinsic::s390_tdc:
2806 Opcode = SystemZISD::TDC;
2819 unsigned NumOps =
Op.getNumOperands();
2822 Ops.push_back(
Op.getOperand(0));
2824 Ops.push_back(
Op.getOperand(
I));
2826 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2840 unsigned NumOps =
Op.getNumOperands();
2846 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2847 "Unhandled intrinsic with f16 operand.");
2850 Ops.push_back(CurrOper);
2864 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2865 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2866 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2892 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2895 int64_t
Value = ConstOp1->getSExtValue();
2911 if (!
C.Op0.hasOneUse() ||
2912 C.Op0.getOpcode() != ISD::LOAD ||
2918 unsigned NumBits = Load->getMemoryVT().getSizeInBits();
2919 if ((NumBits != 8 && NumBits != 16) ||
2920 NumBits != Load->getMemoryVT().getStoreSizeInBits())
2926 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2929 uint64_t Mask = (1 << NumBits) - 1;
2932 int64_t SignedValue = ConstOp1->getSExtValue();
2939 }
else if (NumBits == 8) {
2965 if (
C.Op0.getValueType() != MVT::i32 ||
2966 Load->getExtensionType() != ExtType) {
2968 Load->getBasePtr(), Load->getPointerInfo(),
2969 Load->getMemoryVT(), Load->getAlign(),
2970 Load->getMemOperand()->getFlags());
2976 if (
C.Op1.getValueType() != MVT::i32 ||
2977 Value != ConstOp1->getZExtValue())
2987 if (Load->getMemoryVT() == MVT::i8)
2990 switch (Load->getExtensionType()) {
3007 if (
C.Op0.getValueType() == MVT::i128)
3009 if (
C.Op0.getValueType() == MVT::f128)
3021 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3050 unsigned Opcode0 =
C.Op0.getOpcode();
3057 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3072 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3073 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3095 if (C1 && C1->isZero()) {
3097 if (
N->getOpcode() == ISD::FNEG) {
3114 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3117 if (C1 && C1->getZExtValue() == 32) {
3118 SDValue ShlOp0 =
C.Op0.getOperand(0);
3137 C.Op0.getOperand(0).getOpcode() == ISD::LOAD &&
3140 C.Op1->getAsZExtVal() == 0) {
3142 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3143 C.Op0.getValueSizeInBits().getFixedValue()) {
3144 unsigned Type = L->getExtensionType();
3147 C.Op0 =
C.Op0.getOperand(0);
3161 uint64_t Amount = Shift->getZExtValue();
3162 if (Amount >=
N.getValueSizeInBits())
3177 unsigned ICmpType) {
3178 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3200 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3206 if (EffectivelyUnsigned && CmpVal <
Low) {
3214 if (CmpVal == Mask) {
3220 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3226 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3234 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3240 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3269 if (
C.Op0.getValueType() == MVT::i128) {
3275 if (Mask && Mask->getAPIntValue() == 0) {
3276 C.Opcode = SystemZISD::VTM;
3277 C.Op1 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8,
C.Op0.getOperand(1));
3278 C.Op0 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8,
C.Op0.getOperand(0));
3293 uint64_t CmpVal = ConstOp1->getZExtValue();
3300 NewC.Op0 =
C.Op0.getOperand(0);
3301 NewC.Op1 =
C.Op0.getOperand(1);
3305 MaskVal = Mask->getZExtValue();
3325 MaskVal = -(CmpVal & -CmpVal);
3334 unsigned NewCCMask, ShiftVal;
3338 (MaskVal >> ShiftVal != 0) &&
3339 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3341 MaskVal >> ShiftVal,
3345 MaskVal >>= ShiftVal;
3349 (MaskVal << ShiftVal != 0) &&
3350 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3352 MaskVal << ShiftVal,
3356 MaskVal <<= ShiftVal;
3365 C.Opcode = SystemZISD::TM;
3367 if (Mask && Mask->getZExtValue() == MaskVal)
3372 C.CCMask = NewCCMask;
3378 if (
C.Opcode != SystemZISD::ICMP)
3380 if (
C.Op0.getValueType() != MVT::i128)
3391 Src = Src.getOperand(0);
3394 unsigned Opcode = 0;
3395 if (Src.hasOneUse()) {
3396 switch (Src.getOpcode()) {
3397 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3398 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3399 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3400 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3401 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3402 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3408 C.Op0 = Src->getOperand(0);
3409 C.Op1 = Src->getOperand(1);
3413 C.CCMask ^=
C.CCValid;
3425 C.Opcode = SystemZISD::VICMPES;
3426 C.Op0 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v2i64,
C.Op0);
3427 C.Op1 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v2i64,
C.Op1);
3437 bool Swap =
false, Invert =
false;
3449 C.Opcode = SystemZISD::UCMP128HI;
3451 C.Opcode = SystemZISD::SCMP128HI;
3456 C.CCMask ^=
C.CCValid;
3467 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3470 if ((~Known.
Zero).getZExtValue() & ~Mask->getZExtValue())
3473 C.Op0 =
C.Op0.getOperand(0);
3485 C.CCValid = CCValid;
3488 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3491 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3495 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3498 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3502 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3505 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3508 C.CCMask &= CCValid;
3516 bool IsSignaling =
false) {
3519 unsigned Opcode, CCValid;
3531 Comparison
C(CmpOp0, CmpOp1, Chain);
3533 if (
C.Op0.getValueType().isFloatingPoint()) {
3536 C.Opcode = SystemZISD::FCMP;
3537 else if (!IsSignaling)
3538 C.Opcode = SystemZISD::STRICT_FCMP;
3540 C.Opcode = SystemZISD::STRICT_FCMPS;
3545 C.Opcode = SystemZISD::ICMP;
3580 if (!
C.Op1.getNode()) {
3582 switch (
C.Op0.getOpcode()) {
3593 if (
C.Opcode == SystemZISD::ICMP)
3594 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3596 if (
C.Opcode == SystemZISD::TM) {
3599 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3602 if (
C.Opcode == SystemZISD::VICMPES ||
3603 C.Opcode == SystemZISD::VICMPHS ||
3604 C.Opcode == SystemZISD::VICMPHLS ||
3605 C.Opcode == SystemZISD::VFCMPES ||
3606 C.Opcode == SystemZISD::VFCMPHS ||
3607 C.Opcode == SystemZISD::VFCMPHES) {
3608 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3615 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3617 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3626 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3627 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3652 unsigned CCValid,
unsigned CCMask) {
3657 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3735 int Mask[] = { Start, -1, Start + 1, -1 };
3739 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3741 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3755 !Subtarget.hasVectorEnhancements1()) {
3761 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3774 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3777 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3778 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3780 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3793 bool IsSignaling)
const {
3796 assert (!IsSignaling || Chain);
3799 bool Invert =
false;
3807 assert(IsFP &&
"Unexpected integer comparison");
3809 DL, VT, CmpOp1, CmpOp0, Chain);
3811 DL, VT, CmpOp0, CmpOp1, Chain);
3815 LT.getValue(1),
GE.getValue(1));
3824 assert(IsFP &&
"Unexpected integer comparison");
3826 DL, VT, CmpOp1, CmpOp0, Chain);
3828 DL, VT, CmpOp0, CmpOp1, Chain);
3832 LT.getValue(1),
GT.getValue(1));
3853 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3857 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3862 Chain =
Cmp.getValue(1);
3870 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3883 EVT VT =
Op.getValueType();
3885 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3894 bool IsSignaling)
const {
3900 EVT VT =
Op.getNode()->getValueType(0);
3902 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3903 Chain, IsSignaling);
3925 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
3959 C.CCMask ^=
C.CCValid;
3967 Op = SystemZISD::VICMPE;
3971 Op = SystemZISD::VICMPHL;
3973 Op = SystemZISD::VICMPH;
4012 C.Op1->getAsZExtVal() == 0) {
4019 if (Subtarget.hasVectorEnhancements3() &&
4020 C.Opcode == SystemZISD::ICMP &&
4021 C.Op0.getValueType() == MVT::i128 &&
4031 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4037 const GlobalValue *GV =
Node->getGlobal();
4043 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4046 uint64_t Anchor =
Offset & ~uint64_t(0xfff);
4065 }
else if (Subtarget.isTargetELF()) {
4070 }
else if (Subtarget.isTargetzOS()) {
4101 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4106 Ops.push_back(Chain);
4108 Node->getValueType(0),
4117 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4118 const uint32_t *
Mask =
4120 assert(Mask &&
"Missing call preserved mask for calling convention");
4124 Ops.push_back(Glue);
4127 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4135SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4159 const GlobalValue *GV =
Node->getGlobal();
4167 SDValue TP = lowerThreadPointer(
DL, DAG);
4174 SystemZConstantPoolValue *CPV =
4183 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4189 SystemZConstantPoolValue *CPV =
4198 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4203 SystemZMachineFunctionInfo* MFI =
4232 SystemZConstantPoolValue *CPV =
4266 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4275 if (
CP->isMachineConstantPoolEntry())
4283 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4288 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4290 MachineFrameInfo &MFI = MF.getFrameInfo();
4294 unsigned Depth =
Op.getConstantOperandVal(0);
4301 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4306 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4312 MachinePointerInfo());
4327 unsigned Depth =
Op.getConstantOperandVal(0);
4332 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4335 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4336 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4337 int Offset = TFL->getReturnAddressOffset(MF);
4341 MachinePointerInfo());
4346 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4348 &SystemZ::GR64BitRegClass);
4356 EVT InVT =
In.getValueType();
4357 EVT ResVT =
Op.getValueType();
4365 LoadN->getBasePtr(), LoadN->getMemOperand());
4371 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4373 if (Subtarget.hasHighWord()) {
4377 MVT::i64,
SDValue(U64, 0), In);
4385 DL, MVT::f32, Out64);
4387 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4390 MVT::f64,
SDValue(U64, 0), In);
4392 if (Subtarget.hasHighWord())
4405 if (Subtarget.isTargetXPLINK64())
4406 return lowerVASTART_XPLINK(
Op, DAG);
4408 return lowerVASTART_ELF(
Op, DAG);
4414 SystemZMachineFunctionInfo *FuncInfo =
4415 MF.
getInfo<SystemZMachineFunctionInfo>();
4425 MachinePointerInfo(SV));
4431 SystemZMachineFunctionInfo *FuncInfo =
4432 MF.
getInfo<SystemZMachineFunctionInfo>();
4441 const unsigned NumFields = 4;
4452 for (
unsigned I = 0;
I < NumFields; ++
I) {
4457 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4458 MachinePointerInfo(SV,
Offset));
4476 Align(8),
false,
false,
4477 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4478 MachinePointerInfo(SrcSV));
4482SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4484 if (Subtarget.isTargetXPLINK64())
4485 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4487 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4491SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4493 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4503 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4506 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4507 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4513 if (ExtraAlignSpace)
4517 bool IsSigned =
false;
4518 bool DoesNotReturn =
false;
4519 bool IsReturnValueUsed =
false;
4520 EVT VT =
Op.getValueType();
4530 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4542 if (ExtraAlignSpace) {
4554SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4556 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4559 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4568 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4571 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4572 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4583 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4584 MachinePointerInfo());
4587 if (ExtraAlignSpace)
4594 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4595 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4611 if (RequiredAlign > StackAlign) {
4621 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4622 MachinePointerInfo());
4628SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4632 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4637 unsigned Opcode)
const {
4638 EVT VT =
Op.getValueType();
4644 assert(Subtarget.hasMiscellaneousExtensions2());
4649 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4655 EVT VT =
Op.getValueType();
4663 else if (Subtarget.hasMiscellaneousExtensions2())
4668 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4703 EVT VT =
Op.getValueType();
4716 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4724 EVT VT =
Op.getValueType();
4744 EVT VT =
Op.getValueType();
4751 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4756 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4768 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4770 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4807 MVT::i64, HighOp, Low32);
4813 SDNode *
N =
Op.getNode();
4818 if (
N->getValueType(0) == MVT::i128) {
4819 unsigned BaseOp = 0;
4820 unsigned FlagOp = 0;
4821 bool IsBorrow =
false;
4822 switch (
Op.getOpcode()) {
4826 FlagOp = SystemZISD::VACC;
4830 FlagOp = SystemZISD::VSCBI;
4845 unsigned BaseOp = 0;
4846 unsigned CCValid = 0;
4847 unsigned CCMask = 0;
4849 switch (
Op.getOpcode()) {
4852 BaseOp = SystemZISD::SADDO;
4857 BaseOp = SystemZISD::SSUBO;
4862 BaseOp = SystemZISD::UADDO;
4867 BaseOp = SystemZISD::USUBO;
4873 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4877 if (
N->getValueType(1) == MVT::i1)
4903 SDNode *
N =
Op.getNode();
4904 MVT VT =
N->getSimpleValueType(0);
4915 if (VT == MVT::i128) {
4916 unsigned BaseOp = 0;
4917 unsigned FlagOp = 0;
4918 bool IsBorrow =
false;
4919 switch (
Op.getOpcode()) {
4922 BaseOp = SystemZISD::VAC;
4923 FlagOp = SystemZISD::VACCC;
4926 BaseOp = SystemZISD::VSBI;
4927 FlagOp = SystemZISD::VSBCBI;
4946 unsigned BaseOp = 0;
4947 unsigned CCValid = 0;
4948 unsigned CCMask = 0;
4950 switch (
Op.getOpcode()) {
4956 BaseOp = SystemZISD::ADDCARRY;
4964 BaseOp = SystemZISD::SUBCARRY;
4975 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
4979 if (
N->getValueType(1) == MVT::i1)
4987 EVT VT =
Op.getValueType();
4989 Op =
Op.getOperand(0);
5012 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5024 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5037 if (NumSignificantBits == 0)
5043 BitSize = std::min(BitSize, OrigBitSize);
5052 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5054 if (BitSize != OrigBitSize)
5086 return DAG.
getNode(ISD::MEMBARRIER,
DL, MVT::Other,
Op.getOperand(0));
5091 EVT RegVT =
Op.getValueType();
5093 return lowerATOMIC_LDST_I128(
Op, DAG);
5094 return lowerLoadF16(
Op, DAG);
5100 if (
Node->getMemoryVT().getSizeInBits() == 128)
5101 return lowerATOMIC_LDST_I128(
Op, DAG);
5102 return lowerStoreF16(
Op, DAG);
5109 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5110 "Only custom lowering i128 or f128.");
5123 EVT WideVT = MVT::i32;
5146 unsigned Opcode)
const {
5150 EVT NarrowVT =
Node->getMemoryVT();
5151 EVT WideVT = MVT::i32;
5152 if (NarrowVT == WideVT)
5159 MachineMemOperand *MMO =
Node->getMemOperand();
5163 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5165 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5170 SDValue AlignedAddr, BitShift, NegBitShift;
5178 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5181 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5182 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5187 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5188 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5208 EVT MemVT =
Node->getMemoryVT();
5209 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5211 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5212 assert(Subtarget.hasInterlockedAccess1() &&
5213 "Should have been expanded by AtomicExpand pass.");
5218 return DAG.
getAtomic(ISD::ATOMIC_LOAD_ADD,
DL, MemVT,
5219 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5220 Node->getMemOperand());
5223 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5234 MachineMemOperand *MMO =
Node->getMemOperand();
5237 if (
Node->getMemoryVT() == MVT::i128) {
5246 EVT NarrowVT =
Node->getMemoryVT();
5247 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5248 if (NarrowVT == WideVT) {
5249 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5250 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5252 DL, Tys,
Ops, NarrowVT, MMO);
5266 SDValue AlignedAddr, BitShift, NegBitShift;
5270 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5271 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5274 VTList,
Ops, NarrowVT, MMO);
5288SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5311 auto *Regs = Subtarget.getSpecialRegisters();
5314 "in GHC calling convention");
5316 Regs->getStackPointerRegister(),
Op.getValueType());
5322 auto *Regs = Subtarget.getSpecialRegisters();
5323 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5327 "in GHC calling convention");
5334 if (StoreBackchain) {
5336 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5337 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5338 MachinePointerInfo());
5341 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5344 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5345 MachinePointerInfo());
5352 bool IsData =
Op.getConstantOperandVal(4);
5355 return Op.getOperand(0);
5358 bool IsWrite =
Op.getConstantOperandVal(2);
5365 Node->getMemoryVT(),
Node->getMemOperand());
5369SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5371 unsigned Opcode, CCValid;
5373 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5384SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5386 unsigned Opcode, CCValid;
5389 if (
Op->getNumValues() == 1)
5391 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5396 unsigned Id =
Op.getConstantOperandVal(0);
5398 case Intrinsic::thread_pointer:
5399 return lowerThreadPointer(SDLoc(
Op), DAG);
5401 case Intrinsic::s390_vpdi:
5402 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5403 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5405 case Intrinsic::s390_vperm:
5406 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5407 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5409 case Intrinsic::s390_vuphb:
5410 case Intrinsic::s390_vuphh:
5411 case Intrinsic::s390_vuphf:
5412 case Intrinsic::s390_vuphg:
5413 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5416 case Intrinsic::s390_vuplhb:
5417 case Intrinsic::s390_vuplhh:
5418 case Intrinsic::s390_vuplhf:
5419 case Intrinsic::s390_vuplhg:
5420 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5423 case Intrinsic::s390_vuplb:
5424 case Intrinsic::s390_vuplhw:
5425 case Intrinsic::s390_vuplf:
5426 case Intrinsic::s390_vuplg:
5427 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5430 case Intrinsic::s390_vupllb:
5431 case Intrinsic::s390_vupllh:
5432 case Intrinsic::s390_vupllf:
5433 case Intrinsic::s390_vupllg:
5434 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5437 case Intrinsic::s390_vsumb:
5438 case Intrinsic::s390_vsumh:
5439 case Intrinsic::s390_vsumgh:
5440 case Intrinsic::s390_vsumgf:
5441 case Intrinsic::s390_vsumqf:
5442 case Intrinsic::s390_vsumqg:
5443 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5444 Op.getOperand(1),
Op.getOperand(2));
5446 case Intrinsic::s390_vaq:
5448 Op.getOperand(1),
Op.getOperand(2));
5449 case Intrinsic::s390_vaccb:
5450 case Intrinsic::s390_vacch:
5451 case Intrinsic::s390_vaccf:
5452 case Intrinsic::s390_vaccg:
5453 case Intrinsic::s390_vaccq:
5454 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5455 Op.getOperand(1),
Op.getOperand(2));
5456 case Intrinsic::s390_vacq:
5457 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5458 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5459 case Intrinsic::s390_vacccq:
5460 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5461 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5463 case Intrinsic::s390_vsq:
5465 Op.getOperand(1),
Op.getOperand(2));
5466 case Intrinsic::s390_vscbib:
5467 case Intrinsic::s390_vscbih:
5468 case Intrinsic::s390_vscbif:
5469 case Intrinsic::s390_vscbig:
5470 case Intrinsic::s390_vscbiq:
5471 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5472 Op.getOperand(1),
Op.getOperand(2));
5473 case Intrinsic::s390_vsbiq:
5474 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5475 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5476 case Intrinsic::s390_vsbcbiq:
5477 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5478 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5480 case Intrinsic::s390_vmhb:
5481 case Intrinsic::s390_vmhh:
5482 case Intrinsic::s390_vmhf:
5483 case Intrinsic::s390_vmhg:
5484 case Intrinsic::s390_vmhq:
5486 Op.getOperand(1),
Op.getOperand(2));
5487 case Intrinsic::s390_vmlhb:
5488 case Intrinsic::s390_vmlhh:
5489 case Intrinsic::s390_vmlhf:
5490 case Intrinsic::s390_vmlhg:
5491 case Intrinsic::s390_vmlhq:
5493 Op.getOperand(1),
Op.getOperand(2));
5495 case Intrinsic::s390_vmahb:
5496 case Intrinsic::s390_vmahh:
5497 case Intrinsic::s390_vmahf:
5498 case Intrinsic::s390_vmahg:
5499 case Intrinsic::s390_vmahq:
5500 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5501 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5502 case Intrinsic::s390_vmalhb:
5503 case Intrinsic::s390_vmalhh:
5504 case Intrinsic::s390_vmalhf:
5505 case Intrinsic::s390_vmalhg:
5506 case Intrinsic::s390_vmalhq:
5507 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5508 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5510 case Intrinsic::s390_vmeb:
5511 case Intrinsic::s390_vmeh:
5512 case Intrinsic::s390_vmef:
5513 case Intrinsic::s390_vmeg:
5514 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5515 Op.getOperand(1),
Op.getOperand(2));
5516 case Intrinsic::s390_vmleb:
5517 case Intrinsic::s390_vmleh:
5518 case Intrinsic::s390_vmlef:
5519 case Intrinsic::s390_vmleg:
5520 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5521 Op.getOperand(1),
Op.getOperand(2));
5522 case Intrinsic::s390_vmob:
5523 case Intrinsic::s390_vmoh:
5524 case Intrinsic::s390_vmof:
5525 case Intrinsic::s390_vmog:
5526 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5527 Op.getOperand(1),
Op.getOperand(2));
5528 case Intrinsic::s390_vmlob:
5529 case Intrinsic::s390_vmloh:
5530 case Intrinsic::s390_vmlof:
5531 case Intrinsic::s390_vmlog:
5532 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5533 Op.getOperand(1),
Op.getOperand(2));
5535 case Intrinsic::s390_vmaeb:
5536 case Intrinsic::s390_vmaeh:
5537 case Intrinsic::s390_vmaef:
5538 case Intrinsic::s390_vmaeg:
5540 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5541 Op.getOperand(1),
Op.getOperand(2)),
5543 case Intrinsic::s390_vmaleb:
5544 case Intrinsic::s390_vmaleh:
5545 case Intrinsic::s390_vmalef:
5546 case Intrinsic::s390_vmaleg:
5548 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5549 Op.getOperand(1),
Op.getOperand(2)),
5551 case Intrinsic::s390_vmaob:
5552 case Intrinsic::s390_vmaoh:
5553 case Intrinsic::s390_vmaof:
5554 case Intrinsic::s390_vmaog:
5556 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5557 Op.getOperand(1),
Op.getOperand(2)),
5559 case Intrinsic::s390_vmalob:
5560 case Intrinsic::s390_vmaloh:
5561 case Intrinsic::s390_vmalof:
5562 case Intrinsic::s390_vmalog:
5564 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5565 Op.getOperand(1),
Op.getOperand(2)),
5586 { SystemZISD::MERGE_HIGH, 8,
5587 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5589 { SystemZISD::MERGE_HIGH, 4,
5590 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5592 { SystemZISD::MERGE_HIGH, 2,
5593 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5595 { SystemZISD::MERGE_HIGH, 1,
5596 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5598 { SystemZISD::MERGE_LOW, 8,
5599 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5601 { SystemZISD::MERGE_LOW, 4,
5602 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5604 { SystemZISD::MERGE_LOW, 2,
5605 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5607 { SystemZISD::MERGE_LOW, 1,
5608 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5610 { SystemZISD::PACK, 4,
5611 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5613 { SystemZISD::PACK, 2,
5614 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5616 { SystemZISD::PACK, 1,
5617 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5619 { SystemZISD::PERMUTE_DWORDS, 4,
5620 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5622 { SystemZISD::PERMUTE_DWORDS, 1,
5623 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5637 OpNo0 = OpNo1 = OpNos[1];
5638 }
else if (OpNos[1] < 0) {
5639 OpNo0 = OpNo1 = OpNos[0];
5657 unsigned &OpNo0,
unsigned &OpNo1) {
5658 int OpNos[] = { -1, -1 };
5671 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5673 OpNos[ModelOpNo] = RealOpNo;
5681 unsigned &OpNo0,
unsigned &OpNo1) {
5698 int Elt = Bytes[From];
5701 Transform[From] = -1;
5703 while (
P.Bytes[To] != Elt) {
5708 Transform[From] = To;
5732 Bytes.
resize(NumElements * BytesPerElement, -1);
5733 for (
unsigned I = 0;
I < NumElements; ++
I) {
5734 int Index = VSN->getMaskElt(
I);
5736 for (
unsigned J = 0; J < BytesPerElement; ++J)
5737 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5741 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5744 Bytes.
resize(NumElements * BytesPerElement, -1);
5745 for (
unsigned I = 0;
I < NumElements; ++
I)
5746 for (
unsigned J = 0; J < BytesPerElement; ++J)
5747 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5758 unsigned BytesPerElement,
int &
Base) {
5760 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5761 if (Bytes[Start +
I] >= 0) {
5762 unsigned Elem = Bytes[Start +
I];
5766 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5768 }
else if (
unsigned(
Base) != Elem -
I)
5781 unsigned &StartIndex,
unsigned &OpNo0,
5783 int OpNos[] = { -1, -1 };
5785 for (
unsigned I = 0;
I < 16; ++
I) {
5786 int Index = Bytes[
I];
5792 Shift = ExpectedShift;
5793 else if (Shift != ExpectedShift)
5797 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5799 OpNos[ModelOpNo] = RealOpNo;
5812 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5813 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5818 Op0 = DAG.
getNode(ISD::BITCAST,
DL, InVT, Op0);
5819 Op1 = DAG.
getNode(ISD::BITCAST,
DL, InVT, Op1);
5821 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5823 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5824 }
else if (
P.Opcode == SystemZISD::PACK) {
5827 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5835 if (
N->getOpcode() == ISD::BITCAST)
5836 N =
N->getOperand(0);
5839 return Op->getZExtValue() == 0;
5845 for (
unsigned I = 0;
I < Num ;
I++)
5857 for (
unsigned I = 0;
I < 2; ++
I)
5861 unsigned StartIndex, OpNo0, OpNo1;
5863 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5870 if (ZeroVecIdx != UINT32_MAX) {
5871 bool MaskFirst =
true;
5876 if (OpNo == ZeroVecIdx &&
I == 0) {
5881 if (OpNo != ZeroVecIdx && Byte == 0) {
5888 if (ZeroIdx != -1) {
5891 if (Bytes[
I] >= 0) {
5894 if (OpNo == ZeroVecIdx)
5906 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5909 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
5921 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
5927struct GeneralShuffle {
5928 GeneralShuffle(EVT vt)
5929 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
5933 void tryPrepareForUnpack();
5934 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
5949 unsigned UnpackFromEltSize;
5956void GeneralShuffle::addUndef() {
5958 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
5959 Bytes.push_back(-1);
5968bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
5974 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
5979 if (FromBytesPerElement < BytesPerElement)
5983 (FromBytesPerElement - BytesPerElement));
5986 while (
Op.getNode()) {
5987 if (
Op.getOpcode() == ISD::BITCAST)
5988 Op =
Op.getOperand(0);
6004 }
else if (
Op.isUndef()) {
6013 for (; OpNo <
Ops.size(); ++OpNo)
6014 if (
Ops[OpNo] ==
Op)
6016 if (OpNo ==
Ops.size())
6021 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6022 Bytes.push_back(
Base +
I);
6031 if (
Ops.size() == 0)
6035 tryPrepareForUnpack();
6038 if (
Ops.size() == 1)
6050 unsigned Stride = 1;
6051 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6052 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6062 else if (OpNo ==
I + Stride)
6073 if (NewBytes[J] >= 0) {
6075 "Invalid double permute");
6078 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6084 if (NewBytes[J] >= 0)
6100 unsigned OpNo0, OpNo1;
6104 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6109 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6116 dbgs() << Msg.c_str() <<
" { ";
6117 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6118 dbgs() << Bytes[
I] <<
" ";
6126void GeneralShuffle::tryPrepareForUnpack() {
6128 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6133 if (
Ops.size() > 2 &&
6138 UnpackFromEltSize = 1;
6139 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6140 bool MatchUnpack =
true;
6143 unsigned ToEltSize = UnpackFromEltSize * 2;
6144 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6147 if (Bytes[Elt] != -1) {
6149 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6150 MatchUnpack =
false;
6156 if (
Ops.size() == 2) {
6158 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6160 if (SrcBytes[i] == -1)
6162 if (SrcBytes[i] % 16 !=
int(i))
6163 CanUseUnpackHigh =
false;
6165 CanUseUnpackLow =
false;
6166 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6167 UnpackFromEltSize = UINT_MAX;
6171 if (!CanUseUnpackHigh)
6177 if (UnpackFromEltSize > 4)
6180 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6181 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6183 dumpBytes(Bytes,
"Original Bytes vector:"););
6192 Elt += UnpackFromEltSize;
6193 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6194 Bytes[
B] = Bytes[Elt];
6202 Ops.erase(&
Ops[ZeroVecOpNo]);
6204 if (Bytes[
I] >= 0) {
6206 if (OpNo > ZeroVecOpNo)
6217 if (!unpackWasPrepared())
6219 unsigned InBits = UnpackFromEltSize * 8;
6223 unsigned OutBits = InBits * 2;
6226 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6227 : SystemZISD::UNPACKL_HIGH,
6228 DL, OutVT, PackedOp);
6233 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6234 if (!
Op.getOperand(
I).isUndef())
6250 if (
Value.isUndef())
6262 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6265 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6266 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6287 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6303 GeneralShuffle GS(VT);
6305 bool FoundOne =
false;
6306 for (
unsigned I = 0;
I < NumElements; ++
I) {
6309 Op =
Op.getOperand(0);
6312 unsigned Elem =
Op.getConstantOperandVal(1);
6313 if (!GS.add(
Op.getOperand(0), Elem))
6316 }
else if (
Op.isUndef()) {
6330 if (!ResidueOps.
empty()) {
6331 while (ResidueOps.
size() < NumElements)
6333 for (
auto &
Op : GS.Ops) {
6334 if (!
Op.getNode()) {
6340 return GS.getNode(DAG,
SDLoc(BVN));
6343bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6347 if (
AL->getOpcode() == ISD::ATOMIC_LOAD)
6349 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6360 unsigned int NumElements = Elems.
size();
6361 unsigned int Count = 0;
6362 for (
auto Elem : Elems) {
6363 if (!Elem.isUndef()) {
6366 else if (Elem != Single) {
6386 if (
Single.getNode() && (
Count > 1 || isVectorElementLoad(Single)))
6387 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Single);
6390 bool AllLoads =
true;
6391 for (
auto Elem : Elems)
6392 if (!isVectorElementLoad(Elem)) {
6398 if (VT == MVT::v2i64 && !AllLoads)
6402 if (VT == MVT::v2f64 && !AllLoads)
6412 if (VT == MVT::v4f32 && !AllLoads) {
6421 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6423 Op01 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v2i64, Op01);
6424 Op23 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v2i64, Op23);
6426 DL, MVT::v2i64, Op01, Op23);
6434 unsigned NumConstants = 0;
6435 for (
unsigned I = 0;
I < NumElements; ++
I) {
6449 if (NumConstants > 0) {
6450 for (
unsigned I = 0;
I < NumElements; ++
I)
6461 std::map<const SDNode*, unsigned> UseCounts;
6462 SDNode *LoadMaxUses =
nullptr;
6463 for (
unsigned I = 0;
I < NumElements; ++
I)
6464 if (isVectorElementLoad(Elems[
I])) {
6465 SDNode *Ld = Elems[
I].getNode();
6466 unsigned Count = ++UseCounts[Ld];
6467 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6470 if (LoadMaxUses !=
nullptr) {
6471 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6475 unsigned I1 = NumElements / 2 - 1;
6476 unsigned I2 = NumElements - 1;
6477 bool Def1 = !Elems[
I1].isUndef();
6478 bool Def2 = !Elems[I2].isUndef();
6492 for (
unsigned I = 0;
I < NumElements; ++
I)
6493 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6503 EVT VT =
Op.getValueType();
6505 if (BVN->isConstant()) {
6506 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6524 for (
unsigned I = 0;
I < NumElements; ++
I)
6526 return buildVector(DAG,
DL, VT,
Ops);
6533 EVT VT =
Op.getValueType();
6536 if (VSN->isSplat()) {
6538 unsigned Index = VSN->getSplatIndex();
6540 "Splat index should be defined and in first operand");
6546 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6550 GeneralShuffle
GS(VT);
6551 for (
unsigned I = 0;
I < NumElements; ++
I) {
6552 int Elt = VSN->getMaskElt(
I);
6555 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6556 unsigned(Elt) % NumElements))
6559 return GS.getNode(DAG, SDLoc(VSN));
6578 EVT VT =
Op.getValueType();
6583 if (VT == MVT::v2f64 &&
6597 DAG.
getNode(ISD::BITCAST,
DL, IntVecVT, Op0),
6598 DAG.
getNode(ISD::BITCAST,
DL, IntVT, Op1), Op2);
6599 return DAG.
getNode(ISD::BITCAST,
DL, VT, Res);
6603SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6609 EVT VT =
Op.getValueType();
6614 uint64_t
Index = CIndexN->getZExtValue();
6624 DAG.
getNode(ISD::BITCAST,
DL, IntVecVT, Op0), Op1);
6625 return DAG.
getNode(ISD::BITCAST,
DL, VT, Res);
6628SDValue SystemZTargetLowering::
6631 EVT OutVT =
Op.getValueType();
6635 unsigned StartOffset = 0;
6642 ArrayRef<int> ShuffleMask = SVN->
getMask();
6647 if (ToBits == 64 && OutNumElts == 2) {
6648 int NumElem = ToBits / FromBits;
6649 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6655 int StartOffsetCandidate = -1;
6656 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6657 if (ShuffleMask[Elt] == -1)
6659 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6660 if (StartOffsetCandidate == -1)
6661 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6662 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6665 StartOffsetCandidate = -1;
6668 if (StartOffsetCandidate != -1) {
6669 StartOffset = StartOffsetCandidate;
6678 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6679 if (StartOffset >= OutNumElts) {
6680 Opcode = SystemZISD::UNPACK_LOW;
6681 StartOffset -= OutNumElts;
6683 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6684 }
while (FromBits != ToBits);
6689SDValue SystemZTargetLowering::
6693 EVT OutVT =
Op.getValueType();
6697 unsigned NumInPerOut = InNumElts / OutNumElts;
6702 SmallVector<int, 16>
Mask(InNumElts);
6703 unsigned ZeroVecElt = InNumElts;
6704 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6705 unsigned MaskElt = PackedElt * NumInPerOut;
6706 unsigned End = MaskElt + NumInPerOut - 1;
6707 for (; MaskElt < End; MaskElt++)
6708 Mask[MaskElt] = ZeroVecElt++;
6709 Mask[MaskElt] = PackedElt;
6712 return DAG.
getNode(ISD::BITCAST,
DL, OutVT, Shuf);
6716 unsigned ByScalar)
const {
6721 EVT VT =
Op.getValueType();
6726 APInt SplatBits, SplatUndef;
6727 unsigned SplatBitSize;
6731 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6732 ElemBitSize,
true) &&
6733 SplatBitSize == ElemBitSize) {
6736 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6739 BitVector UndefElements;
6745 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6752 if (VSN->isSplat()) {
6753 SDValue VSNOp0 = VSN->getOperand(0);
6754 unsigned Index = VSN->getSplatIndex();
6756 "Splat index should be defined and in first operand");
6763 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6781 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6782 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6785 if (ShiftAmt > 120) {
6789 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6793 SmallVector<int, 16>
Mask(16);
6794 for (
unsigned Elt = 0; Elt < 16; Elt++)
6795 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6797 if ((ShiftAmt & 7) == 0)
6801 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6819 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6820 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6823 if (ShiftAmt > 120) {
6827 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6831 SmallVector<int, 16>
Mask(16);
6832 for (
unsigned Elt = 0; Elt < 16; Elt++)
6833 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6835 if ((ShiftAmt & 7) == 0)
6839 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
6851 MVT DstVT =
Op.getSimpleValueType();
6854 unsigned SrcAS =
N->getSrcAddressSpace();
6856 assert(SrcAS !=
N->getDestAddressSpace() &&
6857 "addrspacecast must be between different address spaces");
6865 }
else if (DstVT == MVT::i32) {
6879 if (
In.getSimpleValueType() != MVT::f16)
6886 SDValue Chain,
bool IsStrict)
const {
6887 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
6890 std::tie(Result, Chain) =
6899 bool IsStrict =
Op->isStrictFPOpcode();
6901 MVT VT =
Op.getSimpleValueType();
6902 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6910 if (!Subtarget.hasFPExtension() && !IsSigned)
6921 if (VT == MVT::i128) {
6924 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6934 bool IsStrict =
Op->isStrictFPOpcode();
6936 MVT VT =
Op.getSimpleValueType();
6937 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6942 if (VT == MVT::f16) {
6949 if (!Subtarget.hasFPExtension() && !IsSigned)
6952 if (InVT == MVT::i128) {
6955 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6964 assert(
Op.getSimpleValueType() == MVT::i64 &&
6965 "Expexted to convert i64 to f16.");
6977 assert(
Op.getSimpleValueType() == MVT::f16 &&
6978 "Expected to convert f16 to i64.");
6991 EVT RegVT =
Op.getValueType();
6992 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
6999 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7001 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7002 AtomicLd->getMemOperand());
7021 return DAG.
getAtomic(ISD::ATOMIC_STORE,
DL, MVT::i16, AtomicSt->getChain(),
7022 Shft, AtomicSt->getBasePtr(),
7023 AtomicSt->getMemOperand());
7033 MVT ResultVT =
Op.getSimpleValueType();
7035 unsigned Check =
Op.getConstantOperandVal(1);
7037 unsigned TDCMask = 0;
7074 MachinePointerInfo MPI =
7080 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7084 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7089 switch (
Op.getOpcode()) {
7091 return lowerFRAMEADDR(
Op, DAG);
7093 return lowerRETURNADDR(
Op, DAG);
7095 return lowerBR_CC(
Op, DAG);
7097 return lowerSELECT_CC(
Op, DAG);
7099 return lowerSETCC(
Op, DAG);
7101 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7103 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7115 return lowerBITCAST(
Op, DAG);
7117 return lowerVASTART(
Op, DAG);
7119 return lowerVACOPY(
Op, DAG);
7120 case ISD::DYNAMIC_STACKALLOC:
7121 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7122 case ISD::GET_DYNAMIC_AREA_OFFSET:
7123 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7125 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7127 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7129 return lowerSMUL_LOHI(
Op, DAG);
7131 return lowerUMUL_LOHI(
Op, DAG);
7133 return lowerSDIVREM(
Op, DAG);
7135 return lowerUDIVREM(
Op, DAG);
7140 return lowerXALUO(
Op, DAG);
7143 return lowerUADDSUBO_CARRY(
Op, DAG);
7145 return lowerOR(
Op, DAG);
7147 return lowerCTPOP(
Op, DAG);
7148 case ISD::VECREDUCE_ADD:
7149 return lowerVECREDUCE_ADD(
Op, DAG);
7150 case ISD::ATOMIC_FENCE:
7151 return lowerATOMIC_FENCE(
Op, DAG);
7152 case ISD::ATOMIC_SWAP:
7153 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7154 case ISD::ATOMIC_STORE:
7155 return lowerATOMIC_STORE(
Op, DAG);
7156 case ISD::ATOMIC_LOAD:
7157 return lowerATOMIC_LOAD(
Op, DAG);
7158 case ISD::ATOMIC_LOAD_ADD:
7159 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7160 case ISD::ATOMIC_LOAD_SUB:
7161 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7162 case ISD::ATOMIC_LOAD_AND:
7163 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7164 case ISD::ATOMIC_LOAD_OR:
7165 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7166 case ISD::ATOMIC_LOAD_XOR:
7167 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7168 case ISD::ATOMIC_LOAD_NAND:
7169 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7170 case ISD::ATOMIC_LOAD_MIN:
7171 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7172 case ISD::ATOMIC_LOAD_MAX:
7173 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7174 case ISD::ATOMIC_LOAD_UMIN:
7175 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7176 case ISD::ATOMIC_LOAD_UMAX:
7177 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7178 case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
7179 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7180 case ISD::STACKSAVE:
7181 return lowerSTACKSAVE(
Op, DAG);
7182 case ISD::STACKRESTORE:
7183 return lowerSTACKRESTORE(
Op, DAG);
7185 return lowerPREFETCH(
Op, DAG);
7187 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7189 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7191 return lowerBUILD_VECTOR(
Op, DAG);
7193 return lowerVECTOR_SHUFFLE(
Op, DAG);
7195 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7197 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7199 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7201 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7203 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7205 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7207 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7209 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7210 case ISD::ADDRSPACECAST:
7213 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7215 return lowerFSHL(
Op, DAG);
7217 return lowerFSHR(
Op, DAG);
7218 case ISD::FP_EXTEND:
7220 return lowerFP_EXTEND(
Op, DAG);
7225 return lower_FP_TO_INT(
Op, DAG);
7230 return lower_INT_TO_FP(
Op, DAG);
7232 return lowerLoadF16(
Op, DAG);
7234 return lowerStoreF16(
Op, DAG);
7236 return lowerIS_FPCLASS(
Op, DAG);
7238 return lowerGET_ROUNDING(
Op, DAG);
7239 case ISD::READCYCLECOUNTER:
7240 return lowerREADCYCLECOUNTER(
Op, DAG);
7262 &SystemZ::FP128BitRegClass);
7271 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7286 &SystemZ::FP128BitRegClass);
7303 switch (
N->getOpcode()) {
7304 case ISD::ATOMIC_LOAD: {
7307 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7310 DL, Tys,
Ops, MVT::i128, MMO);
7313 if (
N->getValueType(0) == MVT::f128)
7319 case ISD::ATOMIC_STORE: {
7327 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7330 DL, Tys,
Ops, MVT::i128, MMO);
7336 MVT::Other, Res), 0);
7340 case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: {
7348 DL, Tys,
Ops, MVT::i128, MMO);
7357 case ISD::BITCAST: {
7362 EVT SrcVT = Src.getValueType();
7363 EVT ResVT =
N->getValueType(0);
7364 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7366 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7367 if (Subtarget.hasVector()) {
7375 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7377 Subtarget.hasVector()
7391 bool IsStrict =
N->isStrictFPOpcode();
7393 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7394 EVT ResVT =
N->getValueType(0);
7396 if (ResVT == MVT::f16) {
7419 bool IsStrict =
N->isStrictFPOpcode();
7421 EVT ResVT =
N->getValueType(0);
7422 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7425 if (InVT == MVT::f16) {
7431 std::tie(InF32, Chain) =
7456bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7457 if (!Subtarget.hasVector())
7471 DAGCombinerInfo &DCI,
7479 unsigned Opcode =
Op.getOpcode();
7480 if (Opcode == ISD::BITCAST)
7482 Op =
Op.getOperand(0);
7484 canTreatAsByteVector(
Op.getValueType())) {
7493 BytesPerElement,
First))
7500 if (Byte % BytesPerElement != 0)
7503 Index = Byte / BytesPerElement;
7507 canTreatAsByteVector(
Op.getValueType())) {
7510 EVT OpVT =
Op.getValueType();
7512 if (OpBytesPerElement < BytesPerElement)
7516 unsigned End = (
Index + 1) * BytesPerElement;
7517 if (End % OpBytesPerElement != 0)
7520 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7521 if (!
Op.getValueType().isInteger()) {
7524 DCI.AddToWorklist(
Op.getNode());
7529 DCI.AddToWorklist(
Op.getNode());
7536 canTreatAsByteVector(
Op.getValueType()) &&
7537 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7539 EVT ExtVT =
Op.getValueType();
7540 EVT OpVT =
Op.getOperand(0).getValueType();
7543 unsigned Byte =
Index * BytesPerElement;
7544 unsigned SubByte =
Byte % ExtBytesPerElement;
7545 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7546 if (SubByte < MinSubByte ||
7547 SubByte + BytesPerElement > ExtBytesPerElement)
7550 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7552 Byte += SubByte - MinSubByte;
7553 if (Byte % BytesPerElement != 0)
7555 Op =
Op.getOperand(0);
7562 if (
Op.getValueType() != VecVT) {
7564 DCI.AddToWorklist(
Op.getNode());
7574SDValue SystemZTargetLowering::combineTruncateExtract(
7583 if (canTreatAsByteVector(VecVT)) {
7587 if (BytesPerElement % TruncBytes == 0) {
7593 unsigned Scale = BytesPerElement / TruncBytes;
7594 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7601 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7602 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7610SDValue SystemZTargetLowering::combineZERO_EXTEND(
7611 SDNode *
N, DAGCombinerInfo &DCI)
const {
7613 SelectionDAG &DAG = DCI.DAG;
7615 EVT VT =
N->getValueType(0);
7616 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7619 if (TrueOp && FalseOp) {
7629 DCI.CombineTo(N0.
getNode(), TruncSelect);
7672 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7690SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7691 SDNode *
N, DAGCombinerInfo &DCI)
const {
7695 SelectionDAG &DAG = DCI.DAG;
7697 EVT VT =
N->getValueType(0);
7711SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7712 SDNode *
N, DAGCombinerInfo &DCI)
const {
7716 SelectionDAG &DAG = DCI.DAG;
7718 EVT VT =
N->getValueType(0);
7725 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7726 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7742SDValue SystemZTargetLowering::combineMERGE(
7743 SDNode *
N, DAGCombinerInfo &DCI)
const {
7744 SelectionDAG &DAG = DCI.DAG;
7745 unsigned Opcode =
N->getOpcode();
7753 if (Op1 ==
N->getOperand(0))
7758 if (ElemBytes <= 4) {
7759 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7760 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7765 Op1 = DAG.
getNode(ISD::BITCAST, SDLoc(
N), InVT, Op1);
7766 DCI.AddToWorklist(Op1.
getNode());
7769 DCI.AddToWorklist(
Op.getNode());
7770 return DAG.
getNode(ISD::BITCAST, SDLoc(
N), VT,
Op);
7778 LoPart = HiPart =
nullptr;
7783 if (
Use.getResNo() != 0)
7788 bool IsLoPart =
true;
7813 LoPart = HiPart =
nullptr;
7818 if (
Use.getResNo() != 0)
7824 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7827 switch (
User->getConstantOperandVal(1)) {
7828 case SystemZ::subreg_l64:
7833 case SystemZ::subreg_h64:
7845SDValue SystemZTargetLowering::combineLOAD(
7846 SDNode *
N, DAGCombinerInfo &DCI)
const {
7847 SelectionDAG &DAG = DCI.DAG;
7848 EVT LdVT =
N->getValueType(0);
7852 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7853 if (PtrVT != LoadNodeVT) {
7857 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7858 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7859 LN->getMemOperand());
7869 SDNode *LoPart, *HiPart;
7877 LD->getPointerInfo(),
LD->getBaseAlign(),
7878 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7880 DCI.CombineTo(HiPart, EltLoad,
true);
7887 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
7888 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7890 DCI.CombineTo(LoPart, EltLoad,
true);
7897 DCI.AddToWorklist(Chain.
getNode());
7912 for (SDUse &Use :
N->uses()) {
7913 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
7917 }
else if (
Use.getResNo() == 0)
7920 if (!Replicate || OtherUses.
empty())
7926 for (SDNode *U : OtherUses) {
7929 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
7935bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
7936 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
7938 if (Subtarget.hasVectorEnhancements2())
7939 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
7951 for (
unsigned i = 0; i < NumElts; ++i) {
7952 if (M[i] < 0)
continue;
7953 if ((
unsigned) M[i] != NumElts - 1 - i)
7961 for (
auto *U : StoredVal->
users()) {
7963 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8022SDValue SystemZTargetLowering::combineSTORE(
8023 SDNode *
N, DAGCombinerInfo &DCI)
const {
8024 SelectionDAG &DAG = DCI.DAG;
8027 EVT MemVT = SN->getMemoryVT();
8031 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8032 if (PtrVT != StoreNodeVT) {
8036 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8037 SN->getPointerInfo(), SN->getBaseAlign(),
8038 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8046 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8048 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8049 DCI.AddToWorklist(
Value.getNode());
8053 SN->getBasePtr(), SN->getMemoryVT(),
8054 SN->getMemOperand());
8058 if (!SN->isTruncatingStore() &&
8074 Ops, MemVT, SN->getMemOperand());
8077 if (!SN->isTruncatingStore() &&
8080 Subtarget.hasVectorEnhancements2()) {
8082 ArrayRef<int> ShuffleMask = SVN->
getMask();
8090 Ops, MemVT, SN->getMemOperand());
8095 if (!SN->isTruncatingStore() &&
8096 Op1.
getOpcode() == ISD::READCYCLECOUNTER &&
8098 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8102 Ops, MemVT, SN->getMemOperand());
8112 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8113 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8115 SN->getChain(),
DL, LoPart,
8117 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8118 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8136 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8138 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8142 APInt Val =
C->getAPIntValue();
8145 assert(SN->isTruncatingStore() &&
8146 "Non-truncating store and immediate value does not fit?");
8147 Val = Val.
trunc(TotBytes * 8);
8150 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8151 if (VCI.isVectorConstantLegal(Subtarget) &&
8152 VCI.Opcode == SystemZISD::REPLICATE) {
8160 auto FindReplicatedReg = [&](
SDValue MulOp) {
8161 EVT MulVT = MulOp.getValueType();
8162 if (MulOp->getOpcode() ==
ISD::MUL &&
8163 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8167 WordVT =
LHS->getOperand(0).getValueType();
8174 SystemZVectorConstantInfo VCI(
8176 if (VCI.isVectorConstantLegal(Subtarget) &&
8177 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8178 WordVT == VCI.VecVT.getScalarType())
8190 FindReplicatedReg(SplatVal);
8195 FindReplicatedReg(Op1);
8200 "Bad type handling");
8204 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8205 SN->getBasePtr(), SN->getMemOperand());
8212SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8213 SDNode *
N, DAGCombinerInfo &DCI)
const {
8214 SelectionDAG &DAG = DCI.DAG;
8217 N->getOperand(0).hasOneUse() &&
8218 Subtarget.hasVectorEnhancements2()) {
8220 ArrayRef<int> ShuffleMask = SVN->
getMask();
8233 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8237 DCI.CombineTo(
N, ESLoad);
8241 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8251SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8252 SDNode *
N, DAGCombinerInfo &DCI)
const {
8253 SelectionDAG &DAG = DCI.DAG;
8255 if (!Subtarget.hasVector())
8260 if (
Op.getOpcode() == ISD::BITCAST &&
8261 Op.getValueType().isVector() &&
8262 Op.getOperand(0).getValueType().isVector() &&
8263 Op.getValueType().getVectorNumElements() ==
8264 Op.getOperand(0).getValueType().getVectorNumElements())
8265 Op =
Op.getOperand(0);
8269 EVT VecVT =
Op.getValueType();
8272 Op.getOperand(0),
N->getOperand(1));
8273 DCI.AddToWorklist(
Op.getNode());
8275 if (EltVT !=
N->getValueType(0)) {
8276 DCI.AddToWorklist(
Op.getNode());
8277 Op = DAG.
getNode(ISD::BITCAST, SDLoc(
N),
N->getValueType(0),
Op);
8286 if (canTreatAsByteVector(VecVT))
8287 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8288 IndexN->getZExtValue(), DCI,
false);
8293SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8294 SDNode *
N, DAGCombinerInfo &DCI)
const {
8295 SelectionDAG &DAG = DCI.DAG;
8297 if (
N->getOperand(0) ==
N->getOperand(1))
8298 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8308 if (Chain1 == Chain2)
8316SDValue SystemZTargetLowering::combineFP_ROUND(
8317 SDNode *
N, DAGCombinerInfo &DCI)
const {
8319 if (!Subtarget.hasVector())
8328 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8329 SelectionDAG &DAG = DCI.DAG;
8331 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8337 for (
auto *U : Vec->
users()) {
8338 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8340 U->getOperand(0) == Vec &&
8342 U->getConstantOperandVal(1) == 1) {
8344 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8348 if (
N->isStrictFPOpcode()) {
8352 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8353 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8356 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8358 DCI.AddToWorklist(VRound.
getNode());
8362 DCI.AddToWorklist(Extract1.
getNode());
8368 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8371 N->getVTList(), Extract0, Chain);
8380SDValue SystemZTargetLowering::combineFP_EXTEND(
8381 SDNode *
N, DAGCombinerInfo &DCI)
const {
8383 if (!Subtarget.hasVector())
8392 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8393 SelectionDAG &DAG = DCI.DAG;
8395 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8401 for (
auto *U : Vec->
users()) {
8402 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8404 U->getOperand(0) == Vec &&
8406 U->getConstantOperandVal(1) == 2) {
8408 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8412 if (
N->isStrictFPOpcode()) {
8416 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8417 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8420 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8422 DCI.AddToWorklist(VExtend.
getNode());
8426 DCI.AddToWorklist(Extract1.
getNode());
8432 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8435 N->getVTList(), Extract0, Chain);
8444SDValue SystemZTargetLowering::combineINT_TO_FP(
8445 SDNode *
N, DAGCombinerInfo &DCI)
const {
8448 SelectionDAG &DAG = DCI.DAG;
8450 unsigned Opcode =
N->getOpcode();
8451 EVT OutVT =
N->getValueType(0);
8455 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8461 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8462 OutScalarBits <= 64) {
8466 unsigned ExtOpcode =
8469 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8474SDValue SystemZTargetLowering::combineFCOPYSIGN(
8475 SDNode *
N, DAGCombinerInfo &DCI)
const {
8476 SelectionDAG &DAG = DCI.DAG;
8477 EVT VT =
N->getValueType(0);
8490SDValue SystemZTargetLowering::combineBSWAP(
8491 SDNode *
N, DAGCombinerInfo &DCI)
const {
8492 SelectionDAG &DAG = DCI.DAG;
8495 N->getOperand(0).hasOneUse() &&
8496 canLoadStoreByteSwapped(
N->getValueType(0))) {
8505 EVT LoadVT =
N->getValueType(0);
8506 if (LoadVT == MVT::i16)
8511 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8515 if (
N->getValueType(0) == MVT::i16)
8520 DCI.CombineTo(
N, ResVal);
8524 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8532 if (
Op.getOpcode() == ISD::BITCAST &&
8533 Op.getValueType().isVector() &&
8534 Op.getOperand(0).getValueType().isVector() &&
8535 Op.getValueType().getVectorNumElements() ==
8536 Op.getOperand(0).getValueType().getVectorNumElements())
8537 Op =
Op.getOperand(0);
8549 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8551 EVT VecVT =
N->getValueType(0);
8554 Vec = DAG.
getNode(ISD::BITCAST, SDLoc(
N), VecVT, Vec);
8555 DCI.AddToWorklist(Vec.
getNode());
8558 Elt = DAG.
getNode(ISD::BITCAST, SDLoc(
N), EltVT, Elt);
8559 DCI.AddToWorklist(Elt.
getNode());
8562 DCI.AddToWorklist(Vec.
getNode());
8564 DCI.AddToWorklist(Elt.
getNode());
8572 if (SV &&
Op.hasOneUse()) {
8580 EVT VecVT =
N->getValueType(0);
8582 Op0 = DAG.
getNode(ISD::BITCAST, SDLoc(
N), VecVT, Op0);
8583 DCI.AddToWorklist(Op0.
getNode());
8586 Op1 = DAG.
getNode(ISD::BITCAST, SDLoc(
N), VecVT, Op1);
8587 DCI.AddToWorklist(Op1.
getNode());
8590 DCI.AddToWorklist(Op0.
getNode());
8592 DCI.AddToWorklist(Op1.
getNode());
8600SDValue SystemZTargetLowering::combineSETCC(
8601 SDNode *
N, DAGCombinerInfo &DCI)
const {
8602 SelectionDAG &DAG = DCI.DAG;
8608 EVT VT =
N->getValueType(0);
8618 Src.getValueType().isFixedLengthVector() &&
8619 Src.getValueType().getScalarType() == MVT::i1) {
8620 EVT CmpVT = Src.getOperand(0).getValueType();
8640 case SystemZISD::IPM:
8645 case SystemZISD::SELECT_CCMASK: {
8647 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8648 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8651 return std::make_pair(OpCC, OpCCValid);
8656 int CCValidVal = CCValid->getZExtValue();
8657 return std::make_pair(Op4CCReg, CCValidVal);
8668 return std::make_pair(Op0CC, Op0CCValid);
8684 return {Val, Val, Val, Val};
8685 case SystemZISD::IPM: {
8690 for (
auto CC : {0, 1, 2, 3})
8693 return ShiftedCCVals;
8695 case SystemZISD::SELECT_CCMASK: {
8699 if (!CCValid || !CCMask)
8702 int CCValidVal = CCValid->getZExtValue();
8703 int CCMaskVal = CCMask->getZExtValue();
8713 if (TrueSDVals.empty() || FalseSDVals.empty())
8716 for (
auto &CCVal : {0, 1, 2, 3})
8717 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8719 : FalseSDVals[CCVal]);
8720 return MergedSDVals;
8737 if (Op0SDVals.empty() || Op1SDVals.empty())
8740 for (
auto CCVal : {0, 1, 2, 3})
8742 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8743 return BinaryOpSDVals;
8754 auto *CCNode = CCReg.
getNode();
8758 if (CCNode->getOpcode() == SystemZISD::TM) {
8761 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8764 if (!Op0Node || !Op1Node)
8766 auto Op0APVal = Op0Node->getAPIntValue();
8767 auto Op1APVal = Op1Node->getAPIntValue();
8768 auto Result = Op0APVal & Op1APVal;
8769 bool AllOnes = Result == Op1APVal;
8770 bool AllZeros = Result == 0;
8771 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits()] != 0;
8772 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8776 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8781 if (Op0SDVals.empty() || Op1SDVals.empty())
8784 for (
auto CC : {0, 1, 2, 3}) {
8785 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8789 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8791 NewCCMask &= Op0CCValid;
8794 CCValid = Op0CCValid;
8797 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8804 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8808 if (Op0SDVals.empty() || Op1SDVals.empty())
8812 auto CmpTypeVal = CmpType->getZExtValue();
8813 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8817 if (!Op0Node || !Op1Node)
8819 auto Op0APVal = Op0Node->getAPIntValue();
8820 auto Op1APVal = Op1Node->getAPIntValue();
8822 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8823 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8826 for (
auto CC : {0, 1, 2, 3}) {
8827 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8831 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8833 NewCCMask &= Op0CCValid;
8836 CCValid = Op0CCValid;
8847 const Value *Rhs)
const {
8848 const auto isFlagOutOpCC = [](
const Value *V) {
8850 const Value *RHSVal;
8857 if (CB->isInlineAsm()) {
8859 return IA && IA->getConstraintString().contains(
"{@cc}");
8870 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
8873 return {-1, -1, -1};
8877 DAGCombinerInfo &DCI)
const {
8883 if (!CCValid || !CCMask)
8886 int CCValidVal = CCValid->getZExtValue();
8887 int CCMaskVal = CCMask->getZExtValue();
8894 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
8895 CCMaskVal != CCValidVal)
8896 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
8900 N->getOperand(3), CCReg);
8904SDValue SystemZTargetLowering::combineSELECT_CCMASK(
8905 SDNode *
N, DAGCombinerInfo &DCI)
const {
8911 if (!CCValid || !CCMask)
8914 int CCValidVal = CCValid->getZExtValue();
8915 int CCMaskVal = CCMask->getZExtValue();
8918 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
8922 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
8923 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
8925 if (Val.getOperand(4) != CCReg)
8932 int CCMaskVal = CCMask->getZExtValue();
8933 for (
auto &CC : {0, 1, 2, 3})
8934 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
8948 if (TrueSDVals.empty())
8949 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
8950 if (FalseSDVals.empty())
8951 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
8952 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
8953 SmallSet<SDValue, 4> MergedSDValsSet;
8955 for (
auto CC : {0, 1, 2, 3}) {
8956 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
8957 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
8961 if (MergedSDValsSet.
size() == 1)
8962 return *MergedSDValsSet.
begin();
8963 if (MergedSDValsSet.
size() == 2) {
8964 auto BeginIt = MergedSDValsSet.
begin();
8965 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
8966 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
8969 for (
auto CC : {0, 1, 2, 3}) {
8971 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
8972 ? (TrueSDVals[CC] == NewTrueVal)
8973 : (FalseSDVals[CC] == NewTrueVal);
8975 CCMaskVal = NewCCMask;
8976 CCMaskVal &= CCValidVal;
8979 IsCombinedCCReg =
true;
8987 if (CCMaskVal == CCValidVal)
8990 if (IsCombinedCCReg)
8992 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
8999SDValue SystemZTargetLowering::combineGET_CCMASK(
9000 SDNode *
N, DAGCombinerInfo &DCI)
const {
9005 if (!CCValid || !CCMask)
9007 int CCValidVal = CCValid->getZExtValue();
9008 int CCMaskVal = CCMask->getZExtValue();
9013 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9018 if (!SelectCCValid || !SelectCCMask)
9020 int SelectCCValidVal = SelectCCValid->getZExtValue();
9021 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9025 if (!TrueVal || !FalseVal)
9029 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9030 SelectCCMaskVal ^= SelectCCValidVal;
9034 if (SelectCCValidVal & ~CCValidVal)
9036 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9039 return Select->getOperand(4);
9042SDValue SystemZTargetLowering::combineIntDIVREM(
9043 SDNode *
N, DAGCombinerInfo &DCI)
const {
9044 SelectionDAG &DAG = DCI.DAG;
9045 EVT VT =
N->getValueType(0);
9062SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9063 SDNode *
N, DAGCombinerInfo &DCI)
const {
9064 SelectionDAG &DAG = DCI.DAG;
9068 "SRL or SRA node is required here!");
9070 if (!Subtarget.hasVector())
9080 SDValue ShiftOperand =
N->getOperand(0);
9100 if (!IsSignExt && !IsZeroExt)
9108 unsigned ActiveBits = IsSignExt
9109 ?
Constant->getAPIntValue().getSignificantBits()
9110 :
Constant->getAPIntValue().getActiveBits();
9111 if (ActiveBits > NarrowVTSize)
9127 unsigned ActiveBits = IsSignExt
9128 ?
Constant->getAPIntValue().getSignificantBits()
9129 :
Constant->getAPIntValue().getActiveBits();
9130 if (ActiveBits > NarrowVTSize)
9147 "Cannot have a multiply node with two different operand types.");
9149 "Cannot have an add node with two different operand types.");
9160 if (ShiftAmt != NarrowVTSize)
9164 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9165 NarrowVT == MVT::v4i32 ||
9166 (Subtarget.hasVectorEnhancements3() &&
9167 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9173 MulhRightOp, MulhAddOp);
9174 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9185 EVT VT =
Op.getValueType();
9194 Op =
Op.getOperand(0);
9195 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9199 bool CanUseEven =
true, CanUseOdd =
true;
9200 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9201 if (ShuffleMask[Elt] == -1)
9203 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9205 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9208 Op =
Op.getOperand(0);
9210 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9212 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9218 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9222 Op =
Op.getOperand(0);
9224 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9226 unsigned Elem =
Op.getConstantOperandVal(1);
9227 Op =
Op.getOperand(0);
9229 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9231 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9238SDValue SystemZTargetLowering::combineMUL(
9239 SDNode *
N, DAGCombinerInfo &DCI)
const {
9240 SelectionDAG &DAG = DCI.DAG;
9247 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9248 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9253SDValue SystemZTargetLowering::combineINTRINSIC(
9254 SDNode *
N, DAGCombinerInfo &DCI)
const {
9255 SelectionDAG &DAG = DCI.DAG;
9257 unsigned Id =
N->getConstantOperandVal(1);
9261 case Intrinsic::s390_vll:
9262 case Intrinsic::s390_vlrl:
9264 if (
C->getZExtValue() >= 15)
9265 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9266 N->getOperand(3), MachinePointerInfo());
9269 case Intrinsic::s390_vstl:
9270 case Intrinsic::s390_vstrl:
9272 if (
C->getZExtValue() >= 15)
9273 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9274 N->getOperand(4), MachinePointerInfo());
9282 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9289 switch(
N->getOpcode()) {
9294 case SystemZISD::MERGE_HIGH:
9295 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9296 case ISD::LOAD:
return combineLOAD(
N, DCI);
9297 case ISD::STORE:
return combineSTORE(
N, DCI);
9300 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9304 case ISD::FP_EXTEND:
return combineFP_EXTEND(
N, DCI);
9310 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9311 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9314 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9315 case ISD::MUL:
return combineMUL(
N, DCI);
9319 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9331 EVT VT =
Op.getValueType();
9334 unsigned Opcode =
Op.getOpcode();
9336 unsigned Id =
Op.getConstantOperandVal(0);
9338 case Intrinsic::s390_vpksh:
9339 case Intrinsic::s390_vpksf:
9340 case Intrinsic::s390_vpksg:
9341 case Intrinsic::s390_vpkshs:
9342 case Intrinsic::s390_vpksfs:
9343 case Intrinsic::s390_vpksgs:
9344 case Intrinsic::s390_vpklsh:
9345 case Intrinsic::s390_vpklsf:
9346 case Intrinsic::s390_vpklsg:
9347 case Intrinsic::s390_vpklshs:
9348 case Intrinsic::s390_vpklsfs:
9349 case Intrinsic::s390_vpklsgs:
9351 SrcDemE = DemandedElts;
9354 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9357 case Intrinsic::s390_vuphb:
9358 case Intrinsic::s390_vuphh:
9359 case Intrinsic::s390_vuphf:
9360 case Intrinsic::s390_vuplhb:
9361 case Intrinsic::s390_vuplhh:
9362 case Intrinsic::s390_vuplhf:
9363 SrcDemE =
APInt(NumElts * 2, 0);
9366 case Intrinsic::s390_vuplb:
9367 case Intrinsic::s390_vuplhw:
9368 case Intrinsic::s390_vuplf:
9369 case Intrinsic::s390_vupllb:
9370 case Intrinsic::s390_vupllh:
9371 case Intrinsic::s390_vupllf:
9372 SrcDemE =
APInt(NumElts * 2, 0);
9375 case Intrinsic::s390_vpdi: {
9377 SrcDemE =
APInt(NumElts, 0);
9378 if (!DemandedElts[OpNo - 1])
9380 unsigned Mask =
Op.getConstantOperandVal(3);
9381 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9383 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9386 case Intrinsic::s390_vsldb: {
9388 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9389 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9390 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9391 unsigned NumSrc0Els = 16 - FirstIdx;
9392 SrcDemE =
APInt(NumElts, 0);
9394 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9397 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9402 case Intrinsic::s390_vperm:
9411 case SystemZISD::JOIN_DWORDS:
9413 SrcDemE =
APInt(1, 1);
9415 case SystemZISD::SELECT_CCMASK:
9416 SrcDemE = DemandedElts;
9427 const APInt &DemandedElts,
9442 const APInt &DemandedElts,
9444 unsigned Depth)
const {
9448 unsigned Tmp0, Tmp1;
9453 EVT VT =
Op.getValueType();
9454 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9457 "KnownBits does not match VT in bitwidth");
9460 "DemandedElts does not match VT number of elements");
9462 unsigned Opcode =
Op.getOpcode();
9464 bool IsLogical =
false;
9465 unsigned Id =
Op.getConstantOperandVal(0);
9467 case Intrinsic::s390_vpksh:
9468 case Intrinsic::s390_vpksf:
9469 case Intrinsic::s390_vpksg:
9470 case Intrinsic::s390_vpkshs:
9471 case Intrinsic::s390_vpksfs:
9472 case Intrinsic::s390_vpksgs:
9473 case Intrinsic::s390_vpklsh:
9474 case Intrinsic::s390_vpklsf:
9475 case Intrinsic::s390_vpklsg:
9476 case Intrinsic::s390_vpklshs:
9477 case Intrinsic::s390_vpklsfs:
9478 case Intrinsic::s390_vpklsgs:
9479 case Intrinsic::s390_vpdi:
9480 case Intrinsic::s390_vsldb:
9481 case Intrinsic::s390_vperm:
9484 case Intrinsic::s390_vuplhb:
9485 case Intrinsic::s390_vuplhh:
9486 case Intrinsic::s390_vuplhf:
9487 case Intrinsic::s390_vupllb:
9488 case Intrinsic::s390_vupllh:
9489 case Intrinsic::s390_vupllf:
9492 case Intrinsic::s390_vuphb:
9493 case Intrinsic::s390_vuphh:
9494 case Intrinsic::s390_vuphf:
9495 case Intrinsic::s390_vuplb:
9496 case Intrinsic::s390_vuplhw:
9497 case Intrinsic::s390_vuplf: {
9512 case SystemZISD::JOIN_DWORDS:
9513 case SystemZISD::SELECT_CCMASK:
9516 case SystemZISD::REPLICATE: {
9539 if (
LHS == 1)
return 1;
9542 if (
RHS == 1)
return 1;
9543 unsigned Common = std::min(
LHS,
RHS);
9544 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9545 EVT VT =
Op.getValueType();
9547 if (SrcBitWidth > VTBits) {
9548 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9549 if (Common > SrcExtraBits)
9550 return (Common - SrcExtraBits);
9553 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9560 unsigned Depth)
const {
9561 if (
Op.getResNo() != 0)
9563 unsigned Opcode =
Op.getOpcode();
9565 unsigned Id =
Op.getConstantOperandVal(0);
9567 case Intrinsic::s390_vpksh:
9568 case Intrinsic::s390_vpksf:
9569 case Intrinsic::s390_vpksg:
9570 case Intrinsic::s390_vpkshs:
9571 case Intrinsic::s390_vpksfs:
9572 case Intrinsic::s390_vpksgs:
9573 case Intrinsic::s390_vpklsh:
9574 case Intrinsic::s390_vpklsf:
9575 case Intrinsic::s390_vpklsg:
9576 case Intrinsic::s390_vpklshs:
9577 case Intrinsic::s390_vpklsfs:
9578 case Intrinsic::s390_vpklsgs:
9579 case Intrinsic::s390_vpdi:
9580 case Intrinsic::s390_vsldb:
9581 case Intrinsic::s390_vperm:
9583 case Intrinsic::s390_vuphb:
9584 case Intrinsic::s390_vuphh:
9585 case Intrinsic::s390_vuphf:
9586 case Intrinsic::s390_vuplb:
9587 case Intrinsic::s390_vuplhw:
9588 case Intrinsic::s390_vuplf: {
9592 EVT VT =
Op.getValueType();
9602 case SystemZISD::SELECT_CCMASK:
9616 switch (
Op->getOpcode()) {
9617 case SystemZISD::PCREL_WRAPPER:
9618 case SystemZISD::PCREL_OFFSET:
9629 "Unexpected stack alignment");
9632 unsigned StackProbeSize =
9635 StackProbeSize &= ~(StackAlign - 1);
9636 return StackProbeSize ? StackProbeSize : StackAlign;
9653 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9659 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9675 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9677 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9683 if (miI ==
MBB->end()) {
9685 if (Succ->isLiveIn(SystemZ::CC))
9696 switch (
MI.getOpcode()) {
9697 case SystemZ::Select32:
9698 case SystemZ::Select64:
9699 case SystemZ::Select128:
9700 case SystemZ::SelectF32:
9701 case SystemZ::SelectF64:
9702 case SystemZ::SelectF128:
9703 case SystemZ::SelectVR32:
9704 case SystemZ::SelectVR64:
9705 case SystemZ::SelectVR128:
9737 for (
auto *
MI : Selects) {
9738 Register DestReg =
MI->getOperand(0).getReg();
9739 Register TrueReg =
MI->getOperand(1).getReg();
9740 Register FalseReg =
MI->getOperand(2).getReg();
9745 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9748 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9749 TrueReg = It->second.first;
9751 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9752 FalseReg = It->second.second;
9755 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9760 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9771 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9772 assert(TFL->hasReservedCallFrame(MF) &&
9773 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9778 uint32_t NumBytes =
MI.getOperand(0).getImm();
9783 MI.eraseFromParent();
9792 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9794 unsigned CCValid =
MI.getOperand(3).getImm();
9795 unsigned CCMask =
MI.getOperand(4).getImm();
9800 SmallVector<MachineInstr*, 8> Selects;
9801 SmallVector<MachineInstr*, 8> DbgValues;
9807 assert(NextMI.getOperand(3).getImm() == CCValid &&
9808 "Bad CCValid operands since CC was not redefined.");
9809 if (NextMI.getOperand(4).getImm() == CCMask ||
9810 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9816 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9817 NextMI.usesCustomInsertionHook())
9820 for (
auto *SelMI : Selects)
9821 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9825 if (NextMI.isDebugInstr()) {
9827 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9830 }
else if (User || ++
Count > 20)
9834 MachineInstr *LastMI = Selects.back();
9835 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9837 MachineBasicBlock *StartMBB =
MBB;
9867 for (
auto *SelMI : Selects)
9868 SelMI->eraseFromParent();
9871 for (
auto *DbgMI : DbgValues)
9872 MBB->
splice(InsertPos, StartMBB, DbgMI);
9883 unsigned StoreOpcode,
9884 unsigned STOCOpcode,
9885 bool Invert)
const {
9886 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9889 MachineOperand
Base =
MI.getOperand(1);
9890 int64_t Disp =
MI.getOperand(2).getImm();
9891 Register IndexReg =
MI.getOperand(3).getReg();
9892 unsigned CCValid =
MI.getOperand(4).getImm();
9893 unsigned CCMask =
MI.getOperand(5).getImm();
9896 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
9900 MachineMemOperand *MMO =
nullptr;
9901 for (
auto *
I :
MI.memoperands())
9910 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
9922 MI.eraseFromParent();
9930 MachineBasicBlock *StartMBB =
MBB;
9936 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
9963 MI.eraseFromParent();
9973 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9981 MachineBasicBlock *StartMBB =
MBB;
9999 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10018 Register Temp =
MRI.createVirtualRegister(&SystemZ::VR128BitRegClass);
10026 MI.eraseFromParent();
10037 bool Invert)
const {
10039 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10046 int64_t Disp =
MI.getOperand(2).getImm();
10048 Register BitShift =
MI.getOperand(4).getReg();
10049 Register NegBitShift =
MI.getOperand(5).getReg();
10050 unsigned BitSize =
MI.getOperand(6).getImm();
10054 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10055 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10056 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10059 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10060 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10061 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10062 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10063 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10066 MachineBasicBlock *StartMBB =
MBB;
10094 Register Tmp =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10099 }
else if (BinOpcode)
10122 MI.eraseFromParent();
10133 unsigned KeepOldMask)
const {
10135 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10141 int64_t Disp =
MI.getOperand(2).getImm();
10143 Register BitShift =
MI.getOperand(4).getReg();
10144 Register NegBitShift =
MI.getOperand(5).getReg();
10145 unsigned BitSize =
MI.getOperand(6).getImm();
10149 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10150 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10151 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10154 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10155 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10156 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10157 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10158 Register RotatedAltVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10159 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10162 MachineBasicBlock *StartMBB =
MBB;
10226 MI.eraseFromParent();
10236 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10242 int64_t Disp =
MI.getOperand(2).getImm();
10243 Register CmpVal =
MI.getOperand(3).getReg();
10244 Register OrigSwapVal =
MI.getOperand(4).getReg();
10245 Register BitShift =
MI.getOperand(5).getReg();
10246 Register NegBitShift =
MI.getOperand(6).getReg();
10247 int64_t BitSize =
MI.getOperand(7).getImm();
10250 const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass;
10253 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10254 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10255 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10256 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10259 Register OrigOldVal =
MRI.createVirtualRegister(RC);
10261 Register SwapVal =
MRI.createVirtualRegister(RC);
10262 Register StoreVal =
MRI.createVirtualRegister(RC);
10263 Register OldValRot =
MRI.createVirtualRegister(RC);
10264 Register RetryOldVal =
MRI.createVirtualRegister(RC);
10265 Register RetrySwapVal =
MRI.createVirtualRegister(RC);
10268 MachineBasicBlock *StartMBB =
MBB;
10340 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10343 MI.eraseFromParent();
10351 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10356 .
add(
MI.getOperand(1))
10357 .
addImm(SystemZ::subreg_h64)
10358 .
add(
MI.getOperand(2))
10359 .
addImm(SystemZ::subreg_l64);
10360 MI.eraseFromParent();
10369 bool ClearEven)
const {
10371 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10377 Register In128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10381 Register NewIn128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10382 Register Zero64 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10393 MI.eraseFromParent();
10400 unsigned Opcode,
bool IsMemset)
const {
10402 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10407 uint64_t DestDisp =
MI.getOperand(1).getImm();
10412 auto foldDisplIfNeeded = [&](MachineOperand &
Base, uint64_t &Disp) ->
void {
10414 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10415 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10425 SrcDisp =
MI.getOperand(3).getImm();
10427 SrcBase = DestBase;
10428 SrcDisp = DestDisp++;
10429 foldDisplIfNeeded(DestBase, DestDisp);
10432 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10433 bool IsImmForm = LengthMO.
isImm();
10434 bool IsRegForm = !IsImmForm;
10437 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10439 MachineOperand DBase, uint64_t DDisp,
10440 MachineOperand
SBase, uint64_t SDisp,
10441 unsigned Length) ->
void {
10445 if (ByteMO.
isImm())
10460 bool NeedsLoop =
false;
10461 uint64_t ImmLength = 0;
10462 Register LenAdjReg = SystemZ::NoRegister;
10464 ImmLength = LengthMO.
getImm();
10465 ImmLength += IsMemset ? 2 : 1;
10466 if (ImmLength == 0) {
10467 MI.eraseFromParent();
10470 if (Opcode == SystemZ::CLC) {
10471 if (ImmLength > 3 * 256)
10481 }
else if (ImmLength > 6 * 256)
10489 LenAdjReg = LengthMO.
getReg();
10494 MachineBasicBlock *EndMBB =
10495 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10501 MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10503 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10513 auto loadZeroAddress = [&]() -> MachineOperand {
10514 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10518 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10519 DestBase = loadZeroAddress();
10520 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10521 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10523 MachineBasicBlock *StartMBB =
nullptr;
10524 MachineBasicBlock *LoopMBB =
nullptr;
10525 MachineBasicBlock *NextMBB =
nullptr;
10526 MachineBasicBlock *DoneMBB =
nullptr;
10527 MachineBasicBlock *AllDoneMBB =
nullptr;
10531 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10533 const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass;
10534 Register ThisSrcReg =
MRI.createVirtualRegister(RC);
10536 (HaveSingleBase ? ThisSrcReg :
MRI.createVirtualRegister(RC));
10537 Register NextSrcReg =
MRI.createVirtualRegister(RC);
10539 (HaveSingleBase ? NextSrcReg :
MRI.createVirtualRegister(RC));
10540 RC = &SystemZ::GR64BitRegClass;
10541 Register ThisCountReg =
MRI.createVirtualRegister(RC);
10542 Register NextCountReg =
MRI.createVirtualRegister(RC);
10568 MBB = MemsetOneCheckMBB;
10579 MBB = MemsetOneMBB;
10611 if (EndMBB && !ImmLength)
10633 if (!HaveSingleBase)
10640 if (Opcode == SystemZ::MVC)
10667 if (!HaveSingleBase)
10689 Register RemSrcReg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10690 Register RemDestReg = HaveSingleBase ? RemSrcReg
10691 :
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10695 if (!HaveSingleBase)
10703 MachineInstrBuilder EXRL_MIB =
10711 if (Opcode != SystemZ::MVC) {
10721 while (ImmLength > 0) {
10722 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10725 foldDisplIfNeeded(DestBase, DestDisp);
10726 foldDisplIfNeeded(SrcBase, SrcDisp);
10727 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10728 DestDisp += ThisLength;
10729 SrcDisp += ThisLength;
10730 ImmLength -= ThisLength;
10733 if (EndMBB && ImmLength > 0) {
10749 MI.eraseFromParent();
10758 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10762 uint64_t End1Reg =
MI.getOperand(0).getReg();
10763 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10764 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10765 uint64_t CharReg =
MI.getOperand(3).getReg();
10767 const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass;
10768 uint64_t This1Reg =
MRI.createVirtualRegister(RC);
10769 uint64_t This2Reg =
MRI.createVirtualRegister(RC);
10770 uint64_t End2Reg =
MRI.createVirtualRegister(RC);
10772 MachineBasicBlock *StartMBB =
MBB;
10808 MI.eraseFromParent();
10815 bool NoFloat)
const {
10817 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10818 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10821 MI.setDesc(
TII->get(Opcode));
10825 uint64_t Control =
MI.getOperand(2).getImm();
10826 static const unsigned GPRControlBit[16] = {
10827 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10828 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
10830 Control |= GPRControlBit[15];
10831 if (TFI->
hasFP(MF))
10832 Control |= GPRControlBit[11];
10833 MI.getOperand(2).setImm(Control);
10836 for (
int I = 0;
I < 16;
I++) {
10837 if ((Control & GPRControlBit[
I]) == 0) {
10844 if (!NoFloat && (Control & 4) != 0) {
10845 if (Subtarget.hasVector()) {
10863 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10866 Register SrcReg =
MI.getOperand(0).getReg();
10869 const TargetRegisterClass *RC =
MRI->getRegClass(SrcReg);
10870 Register DstReg =
MRI->createVirtualRegister(RC);
10877 MI.eraseFromParent();
10886 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10889 Register DstReg =
MI.getOperand(0).getReg();
10890 Register SizeReg =
MI.getOperand(2).getReg();
10892 MachineBasicBlock *StartMBB =
MBB;
10902 Register PHIReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10903 Register IncReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10968 MI.eraseFromParent();
10972SDValue SystemZTargetLowering::
10975 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
10983 switch (
MI.getOpcode()) {
10984 case SystemZ::ADJCALLSTACKDOWN:
10985 case SystemZ::ADJCALLSTACKUP:
10986 return emitAdjCallStack(
MI,
MBB);
10988 case SystemZ::Select32:
10989 case SystemZ::Select64:
10990 case SystemZ::Select128:
10991 case SystemZ::SelectF32:
10992 case SystemZ::SelectF64:
10993 case SystemZ::SelectF128:
10994 case SystemZ::SelectVR32:
10995 case SystemZ::SelectVR64:
10996 case SystemZ::SelectVR128:
10997 return emitSelect(
MI,
MBB);
10999 case SystemZ::CondStore8Mux:
11000 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11001 case SystemZ::CondStore8MuxInv:
11002 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11003 case SystemZ::CondStore16Mux:
11004 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11005 case SystemZ::CondStore16MuxInv:
11006 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11007 case SystemZ::CondStore32Mux:
11008 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11009 case SystemZ::CondStore32MuxInv:
11010 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11011 case SystemZ::CondStore8:
11012 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11013 case SystemZ::CondStore8Inv:
11014 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11015 case SystemZ::CondStore16:
11016 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11017 case SystemZ::CondStore16Inv:
11018 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11019 case SystemZ::CondStore32:
11020 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11021 case SystemZ::CondStore32Inv:
11022 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11023 case SystemZ::CondStore64:
11024 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11025 case SystemZ::CondStore64Inv:
11026 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11027 case SystemZ::CondStoreF32:
11028 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11029 case SystemZ::CondStoreF32Inv:
11030 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11031 case SystemZ::CondStoreF64:
11032 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11033 case SystemZ::CondStoreF64Inv:
11034 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11036 case SystemZ::SCmp128Hi:
11037 return emitICmp128Hi(
MI,
MBB,
false);
11038 case SystemZ::UCmp128Hi:
11039 return emitICmp128Hi(
MI,
MBB,
true);
11041 case SystemZ::PAIR128:
11042 return emitPair128(
MI,
MBB);
11043 case SystemZ::AEXT128:
11044 return emitExt128(
MI,
MBB,
false);
11045 case SystemZ::ZEXT128:
11046 return emitExt128(
MI,
MBB,
true);
11048 case SystemZ::ATOMIC_SWAPW:
11049 return emitAtomicLoadBinary(
MI,
MBB, 0);
11051 case SystemZ::ATOMIC_LOADW_AR:
11052 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11053 case SystemZ::ATOMIC_LOADW_AFI:
11054 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11056 case SystemZ::ATOMIC_LOADW_SR:
11057 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11059 case SystemZ::ATOMIC_LOADW_NR:
11060 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11061 case SystemZ::ATOMIC_LOADW_NILH:
11062 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11064 case SystemZ::ATOMIC_LOADW_OR:
11065 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11066 case SystemZ::ATOMIC_LOADW_OILH:
11067 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11069 case SystemZ::ATOMIC_LOADW_XR:
11070 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11071 case SystemZ::ATOMIC_LOADW_XILF:
11072 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11074 case SystemZ::ATOMIC_LOADW_NRi:
11075 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11076 case SystemZ::ATOMIC_LOADW_NILHi:
11077 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11079 case SystemZ::ATOMIC_LOADW_MIN:
11081 case SystemZ::ATOMIC_LOADW_MAX:
11083 case SystemZ::ATOMIC_LOADW_UMIN:
11085 case SystemZ::ATOMIC_LOADW_UMAX:
11088 case SystemZ::ATOMIC_CMP_SWAPW:
11089 return emitAtomicCmpSwapW(
MI,
MBB);
11090 case SystemZ::MVCImm:
11091 case SystemZ::MVCReg:
11092 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11093 case SystemZ::NCImm:
11094 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11095 case SystemZ::OCImm:
11096 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11097 case SystemZ::XCImm:
11098 case SystemZ::XCReg:
11099 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11100 case SystemZ::CLCImm:
11101 case SystemZ::CLCReg:
11102 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11103 case SystemZ::MemsetImmImm:
11104 case SystemZ::MemsetImmReg:
11105 case SystemZ::MemsetRegImm:
11106 case SystemZ::MemsetRegReg:
11107 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11108 case SystemZ::CLSTLoop:
11109 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11110 case SystemZ::MVSTLoop:
11111 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11112 case SystemZ::SRSTLoop:
11113 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11114 case SystemZ::TBEGIN:
11115 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11116 case SystemZ::TBEGIN_nofloat:
11117 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11118 case SystemZ::TBEGINC:
11119 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11120 case SystemZ::LTEBRCompare_Pseudo:
11121 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11122 case SystemZ::LTDBRCompare_Pseudo:
11123 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11124 case SystemZ::LTXBRCompare_Pseudo:
11125 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11127 case SystemZ::PROBED_ALLOCA:
11128 return emitProbedAlloca(
MI,
MBB);
11129 case SystemZ::EH_SjLj_SetJmp:
11131 case SystemZ::EH_SjLj_LongJmp:
11134 case TargetOpcode::STACKMAP:
11135 case TargetOpcode::PATCHPOINT:
11146SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11147 if (VT == MVT::Untyped)
11148 return &SystemZ::ADDR128BitRegClass;
11174 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11194 EVT VT =
Op.getValueType();
11195 Op =
Op.getOperand(0);
11196 EVT OpVT =
Op.getValueType();
11198 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11209 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11229 const AttributeList &Attrs =
F->getAttributes();
11230 if (Attrs.hasRetAttrs())
11231 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11232 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11233 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11236 OS << *FT->getParamType(
I);
11238 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11245bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11246 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11247 if (Itr == IsInternalCache.end())
11248 Itr = IsInternalCache
11249 .insert(std::pair<const Function *, bool>(
11252 return Itr->second;
11255void SystemZTargetLowering::
11263 bool IsInternal =
false;
11264 const Function *CalleeFn =
nullptr;
11267 IsInternal = isInternal(CalleeFn);
11268 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11269 errs() <<
"ERROR: Missing extension attribute of passed "
11270 <<
"value in call to function:\n" <<
"Callee: ";
11271 if (CalleeFn !=
nullptr)
11275 errs() <<
"Caller: ";
11281void SystemZTargetLowering::
11289 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11290 errs() <<
"ERROR: Missing extension attribute of returned "
11291 <<
"value from function:\n";
11299bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11301 if (!Subtarget.isTargetELF())
11310 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11311 MVT VT = Outs[i].VT;
11312 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11315 "Unexpected integer argument VT.");
11316 if (VT == MVT::i32 &&
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
static bool isZeroVector(SDValue N)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
Function Alias Analysis Results
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isSelectPseudo(MachineInstr &MI)
static bool isUndef(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file defines the SmallSet class.
static SDValue getI128Select(SelectionDAG &DAG, const SDLoc &DL, Comparison C, SDValue TrueOp, SDValue FalseOp)
static SmallVector< SDValue, 4 > simplifyAssumingCCVal(SDValue &Val, SDValue &CC, SelectionDAG &DAG)
static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void printFunctionArgExts(const Function *F, raw_fd_ostream &OS)
static void adjustForLTGFR(Comparison &C)
static void adjustSubwordCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue joinDwords(SelectionDAG &DAG, const SDLoc &DL, SDValue Op0, SDValue Op1)
static cl::opt< bool > EnableIntArgExtCheck("argext-abi-check", cl::init(false), cl::desc("Verify that narrow int args are properly extended per the " "SystemZ ABI."))
static bool isOnlyUsedByStores(SDValue StoredVal, SelectionDAG &DAG)
static void lowerGR128Binary(SelectionDAG &DAG, const SDLoc &DL, EVT VT, unsigned Opcode, SDValue Op0, SDValue Op1, SDValue &Even, SDValue &Odd)
static void adjustForRedundantAnd(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG)
static SDValue buildScalarToVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Value)
static SDValue lowerI128ToGR128(SelectionDAG &DAG, SDValue In)
static bool isSimpleShift(SDValue N, unsigned &ShiftVal)
static bool isI128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static bool chooseShuffleOpNos(int *OpNos, unsigned &OpNo0, unsigned &OpNo1)
static uint32_t findZeroVectorIdx(SDValue *Ops, unsigned Num)
static bool isVectorElementSwap(ArrayRef< int > M, EVT VT)
static void getCSAddressAndShifts(SDValue Addr, SelectionDAG &DAG, SDLoc DL, SDValue &AlignedAddr, SDValue &BitShift, SDValue &NegBitShift)
static bool isShlDoublePermute(const SmallVectorImpl< int > &Bytes, unsigned &StartIndex, unsigned &OpNo0, unsigned &OpNo1)
static SDValue getPermuteNode(SelectionDAG &DAG, const SDLoc &DL, const Permute &P, SDValue Op0, SDValue Op1)
static SDNode * emitIntrinsicWithCCAndChain(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static SDValue getCCResult(SelectionDAG &DAG, SDValue CCReg)
static bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static void lowerMUL_LOHI32(SelectionDAG &DAG, const SDLoc &DL, unsigned Extend, SDValue Op0, SDValue Op1, SDValue &Hi, SDValue &Lo)
static bool isF128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static void createPHIsForSelects(SmallVector< MachineInstr *, 8 > &Selects, MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB, MachineBasicBlock *SinkMBB)
static SDValue getGeneralPermuteNode(SelectionDAG &DAG, const SDLoc &DL, SDValue *Ops, const SmallVectorImpl< int > &Bytes)
static unsigned getVectorComparisonOrInvert(ISD::CondCode CC, CmpMode Mode, bool &Invert)
static unsigned CCMaskForCondCode(ISD::CondCode CC)
static void adjustICmpTruncate(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void adjustForFNeg(Comparison &C)
static bool isScalarToVector(SDValue Op)
static SDValue emitSETCC(SelectionDAG &DAG, const SDLoc &DL, SDValue CCReg, unsigned CCValid, unsigned CCMask)
static bool matchPermute(const SmallVectorImpl< int > &Bytes, const Permute &P, unsigned &OpNo0, unsigned &OpNo1)
static bool isAddCarryChain(SDValue Carry)
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static MachineOperand earlyUseOperand(MachineOperand Op)
static bool canUseSiblingCall(const CCState &ArgCCInfo, SmallVectorImpl< CCValAssign > &ArgLocs, SmallVectorImpl< ISD::OutputArg > &Outs)
static bool getzOSCalleeAndADA(SelectionDAG &DAG, SDValue &Callee, SDValue &ADA, SDLoc &DL, SDValue &Chain)
static SDValue convertToF16(SDValue Op, SelectionDAG &DAG)
static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask, SelectionDAG &DAG)
static bool shouldSwapCmpOperands(const Comparison &C)
static bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType)
static SDValue getADAEntry(SelectionDAG &DAG, SDValue Val, SDLoc DL, unsigned Offset, bool LoadAdr=false)
static SDNode * emitIntrinsicWithCC(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static void adjustForSubtraction(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool getVPermMask(SDValue ShuffleOp, SmallVectorImpl< int > &Bytes)
static const Permute PermuteForms[]
static std::pair< SDValue, int > findCCUse(const SDValue &Val)
static bool isI128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static bool isSubBorrowChain(SDValue Carry)
static void adjustICmp128(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool analyzeArgSplit(const SmallVectorImpl< ArgTy > &Args, SmallVector< CCValAssign, 16 > &ArgLocs, unsigned I, MVT &PartVT, unsigned &NumParts)
static APInt getDemandedSrcElements(SDValue Op, const APInt &DemandedElts, unsigned OpNo)
static SDValue getAbsolute(SelectionDAG &DAG, const SDLoc &DL, SDValue Op, bool IsNegative)
static unsigned computeNumSignBitsBinOp(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static SDValue expandBitCastI128ToF128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static SDValue tryBuildVectorShuffle(SelectionDAG &DAG, BuildVectorSDNode *BVN)
static SDValue convertFromF16(SDValue Op, SDLoc DL, SelectionDAG &DAG)
static unsigned getVectorComparison(ISD::CondCode CC, CmpMode Mode)
static SDValue lowerGR128ToI128(SelectionDAG &DAG, SDValue In)
static SDValue MergeInputChains(SDNode *N1, SDNode *N2)
static SDValue expandBitCastF128ToI128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, uint64_t Mask, uint64_t CmpVal, unsigned ICmpType)
static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static SDValue expandV4F32ToV2F64(SelectionDAG &DAG, int Start, const SDLoc &DL, SDValue Op, SDValue Chain)
static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond, const SDLoc &DL, SDValue Chain=SDValue(), bool IsSignaling=false)
static bool checkCCKill(MachineInstr &MI, MachineBasicBlock *MBB)
static Register forceReg(MachineInstr &MI, MachineOperand &Base, const SystemZInstrInfo *TII)
static bool is32Bit(EVT VT)
static std::pair< unsigned, const TargetRegisterClass * > parseRegisterNumber(StringRef Constraint, const TargetRegisterClass *RC, const unsigned *Map, unsigned Size)
static unsigned detectEvenOddMultiplyOperand(const SelectionDAG &DAG, const SystemZSubtarget &Subtarget, SDValue &Op)
static bool matchDoublePermute(const SmallVectorImpl< int > &Bytes, const Permute &P, SmallVectorImpl< int > &Transform)
static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode, SDValue Call, unsigned CCValid, uint64_t CC, ISD::CondCode Cond)
static bool isAbsolute(SDValue CmpOp, SDValue Pos, SDValue Neg)
static AddressingMode getLoadStoreAddrMode(bool HasVector, Type *Ty)
static SDValue buildMergeScalars(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Op0, SDValue Op1)
static void computeKnownBitsBinOp(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static bool getShuffleInput(const SmallVectorImpl< int > &Bytes, unsigned Start, unsigned BytesPerElement, int &Base)
static AddressingMode supportedAddressingMode(Instruction *I, bool HasVector)
static bool isF128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static void adjustZeroCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
uint64_t getZExtValue() const
Get zero extended value.
void setBitsFrom(unsigned loBit)
Set the top bits starting from loBit.
unsigned getActiveBits() const
Compute the number of active bits in the value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isSingleWord() const
Determine if this APInt just has one word to store value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
an instruction that atomically reads a memory location, combines it with another value,...
BinOp getOperation() const
This class holds the attributes for a particular argument, parameter, function, or return value.
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
LLVM Basic Block Representation.
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
LLVM_ABI bool isConstant() const
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
uint64_t getZExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
bool hasAddressTaken(const User **=nullptr, bool IgnoreCallbackUses=false, bool IgnoreAssumeLikeCalls=true, bool IngoreLLVMUsed=false, bool IgnoreARCAttachedCall=false, bool IgnoreCastedDirectCall=false) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
bool hasInternalLinkage() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
static auto integer_fixedlen_vector_valuetypes()
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setAdjustsStack(bool V)
void setFrameAddressIsTaken(bool T)
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
reverse_iterator rbegin()
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
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.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineFunctionProperties & getProperties() const
Get the function properties.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
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
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
void setFlags(SDNodeFlags NewFlags)
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
LLVM_ABI SDValue getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS)
Return an AddrSpaceCastSDNode.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getAtomicLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT MemVT, EVT VT, SDValue Chain, SDValue Ptr, MachineMemOperand *MMO)
LLVM_ABI SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
LLVM_ABI bool isConstantIntBuildVectorOrConstantInt(SDValue N, bool AllowOpaques=true) const
Test whether the given value is a constant int or similar node.
LLVM_ABI SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getSplatVector(EVT VT, const SDLoc &DL, SDValue Op)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI std::pair< SDValue, SDValue > getStrictFPExtendOrRound(SDValue Op, SDValue Chain, const SDLoc &DL, EVT VT)
Convert Op, which must be a STRICT operation of float type, to the float type VT, by either extending...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of float type, to the float type VT, by either extending or rounding (by tr...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
ArrayRef< int > getMask() const
const_iterator begin() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A SystemZ-specific class detailing special use registers particular for calling conventions.
virtual int getStackPointerBias()=0
virtual int getReturnFunctionAddressRegister()=0
virtual int getCallFrameSize()=0
virtual int getStackPointerRegister()=0
static SystemZConstantPoolValue * Create(const GlobalValue *GV, SystemZCP::SystemZCPModifier Modifier)
unsigned getVarArgsFrameIndex() const
void setVarArgsFrameIndex(unsigned FI)
void setRegSaveFrameIndex(unsigned FI)
void incNumLocalDynamicTLSAccesses()
Register getVarArgsFirstGPR() const
void setADAVirtualRegister(Register Reg)
void setVarArgsFirstGPR(Register GPR)
Register getADAVirtualRegister() const
void setSizeOfFnParams(unsigned Size)
void setVarArgsFirstFPR(Register FPR)
unsigned getRegSaveFrameIndex() const
Register getVarArgsFirstFPR() const
const SystemZInstrInfo * getInstrInfo() const override
SystemZCallingConventionRegisters * getSpecialRegisters() const
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
bool hasInlineStackProbe(const MachineFunction &MF) const override
Returns true if stack probing through inline assembly is requested.
bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes) const override
Determines the optimal series of memory ops to replace the memset / memcpy.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
AtomicExpansionKind shouldCastAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be cast by the IR-level AtomicExpand pass.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &, EVT) const override
Return the ValueType of the result of SETCC operations.
bool allowTruncateForTailCall(Type *, Type *) const override
Return true if a truncation from FromTy to ToTy is permitted when deciding whether a call is in tail ...
SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag, const SDLoc &DL, const AsmOperandInfo &Constraint, SelectionDAG &DAG) const override
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CondMergingParams getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs) const override
bool useSoftFloat() const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
std::pair< SDValue, SDValue > makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName, EVT RetVT, ArrayRef< SDValue > Ops, CallingConv::ID CallConv, bool IsSigned, SDLoc DL, bool DoesNotReturn, bool IsReturnValueUsed) const
bool mayBeEmittedAsTailCall(const CallInst *CI) const override
Return true if the target may be able emit the call instruction as a tail call.
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
SystemZTargetLowering(const TargetMachine &TM, const SystemZSubtarget &STI)
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
bool isLegalICmpImmediate(int64_t Imm) const override
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
TargetLowering::ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
TargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts, MVT PartVT, EVT ValueVT, std::optional< CallingConv::ID > CC) const override
Target-specific combining of register parts into its original value.
bool isTruncateFree(Type *, Type *) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
SDValue useLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, MVT VT, SDValue Arg, SDLoc DL, SDValue Chain, bool IsStrict) const
unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const override
Determine the number of bits in the operation that are sign bits.
void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
bool isLegalAddImmediate(int64_t Imm) const override
Return true if the specified immediate is legal add immediate, that is the target has add instruction...
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, bool PoisonOnly, unsigned Depth) const override
Return true if this function can prove that Op is never poison and, if PoisonOnly is false,...
AtomicExpansionKind shouldCastAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be cast by the IR-level AtomicExpand pass into.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
unsigned getStackProbeSize(const MachineFunction &MF) const
XPLINK64 calling convention specific use registers Particular to z/OS when in 64 bit mode.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setAtomicLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Let target indicate that an extending atomic load of the specified type is legal.
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support 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...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
virtual bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes) const
Determines the optimal series of memory ops to replace the memset / memcpy.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
unsigned getPointerSize(unsigned AS) const
Get the pointer size for this target.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
bool hasOneUse() const
Return true if there is exactly one use of this value.
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
A raw_ostream that writes to a file descriptor.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr 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.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ Fast
Attempts to make calls as fast as possible (e.g.
@ 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.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ 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...
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ SSUBO
Same for subtraction.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ 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_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ 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.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ 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 ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI bool isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are 0 o...
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
LLVM_ABI CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
@ Define
Register definition.
@ System
Synchronized with respect to all concurrently executing threads.
@ MO_ADA_DATA_SYMBOL_ADDR
@ MO_ADA_DIRECT_FUNC_DESC
@ MO_ADA_INDIRECT_FUNC_DESC
const unsigned GR64Regs[16]
const unsigned VR128Regs[32]
const unsigned VR16Regs[32]
const unsigned GR128Regs[16]
const unsigned FP32Regs[16]
const unsigned FP16Regs[16]
const unsigned GR32Regs[16]
const unsigned FP64Regs[16]
const int64_t ELFCallFrameSize
const unsigned VR64Regs[32]
const unsigned FP128Regs[16]
const unsigned VR32Regs[32]
unsigned odd128(bool Is32bit)
const unsigned CCMASK_CMP_GE
static bool isImmHH(uint64_t Val)
const unsigned CCMASK_TEND
const unsigned CCMASK_CS_EQ
const unsigned CCMASK_TBEGIN
const MCPhysReg ELFArgFPRs[ELFNumArgFPRs]
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_TM_SOME_1
const unsigned CCMASK_LOGICAL_CARRY
const unsigned TDCMASK_NORMAL_MINUS
const unsigned CCMASK_TDC
const unsigned CCMASK_FCMP
const unsigned CCMASK_TM_SOME_0
static bool isImmHL(uint64_t Val)
const unsigned TDCMASK_SUBNORMAL_MINUS
const unsigned TDCMASK_NORMAL_PLUS
const unsigned CCMASK_CMP_GT
const unsigned TDCMASK_QNAN_MINUS
const unsigned CCMASK_ANY
const unsigned CCMASK_ARITH
const unsigned CCMASK_TM_MIXED_MSB_0
const unsigned TDCMASK_SUBNORMAL_PLUS
static bool isImmLL(uint64_t Val)
const unsigned VectorBits
static bool isImmLH(uint64_t Val)
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
const unsigned TDCMASK_INFINITY_PLUS
unsigned reverseCCMask(unsigned CCMask)
const unsigned CCMASK_TM_ALL_0
const unsigned CCMASK_CMP_LE
const unsigned CCMASK_CMP_O
const unsigned CCMASK_CMP_EQ
const unsigned VectorBytes
const unsigned TDCMASK_INFINITY_MINUS
const unsigned CCMASK_ICMP
const unsigned CCMASK_VCMP_ALL
const unsigned CCMASK_VCMP_NONE
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_VCMP
const unsigned CCMASK_TM_MIXED_MSB_1
const unsigned CCMASK_TM_MSB_0
const unsigned CCMASK_ARITH_OVERFLOW
const unsigned CCMASK_CS_NE
const unsigned TDCMASK_SNAN_PLUS
const unsigned CCMASK_NONE
const unsigned CCMASK_CMP_LT
const unsigned CCMASK_CMP_NE
const unsigned TDCMASK_ZERO_PLUS
const unsigned TDCMASK_QNAN_PLUS
const unsigned TDCMASK_ZERO_MINUS
unsigned even128(bool Is32bit)
const unsigned CCMASK_TM_ALL_1
const unsigned CCMASK_LOGICAL_BORROW
const unsigned ELFNumArgFPRs
const unsigned CCMASK_CMP_UO
const unsigned CCMASK_LOGICAL
const unsigned CCMASK_TM_MSB_1
const unsigned TDCMASK_SNAN_MINUS
initializer< Ty > init(const Ty &Val)
support::ulittle32_t Word
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
FunctionAddr VTableAddr Value
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
testing::Matcher< const detail::ErrorHolder & > Failed()
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
LLVM_ABI void dumpBytes(ArrayRef< uint8_t > Bytes, raw_ostream &OS)
Convert ‘Bytes’ to a hex string and output to ‘OS’.
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.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
AddressingMode(bool LongDispl, bool IdxReg)
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
KnownBits anyextOrTrunc(unsigned BitWidth) const
Return known bits for an "any" extension or truncation of the value we're tracking.
unsigned getBitWidth() const
Get the bit width of this value.
KnownBits zext(unsigned BitWidth) const
Return known bits for a zero extension of the value we're tracking.
void resetAll()
Resets the known state of all bits.
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
KnownBits sext(unsigned BitWidth) const
Return known bits for a sign extension of the value we're tracking.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
SystemZVectorConstantInfo(APInt IntImm)
SmallVector< unsigned, 2 > OpVals
bool isVectorConstantLegal(const SystemZSubtarget &Subtarget)
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setDiscardResult(bool Value=true)
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
CallLoweringInfo & setNoReturn(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList, AttributeSet ResultAttrs={})
This structure is used to pass arguments to makeLibCall function.