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}) {
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,
2102 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2105 unsigned PartOffset = Ins[
I].PartOffset;
2110 assert(PartOffset &&
"Offset should be non-zero.");
2117 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2123 Subtarget.getSpecialRegisters());
2129 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2134 if (IsVarArg && Subtarget.isTargetELF()) {
2147 int64_t RegSaveOffset =
2162 &SystemZ::FP64BitRegClass);
2174 if (Subtarget.isTargetXPLINK64()) {
2179 Subtarget.getSpecialRegisters());
2180 MRI.addLiveIn(Regs->getADARegister(), ADAvReg);
2192 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2199 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2201 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2208 unsigned Offset,
bool LoadAdr =
false) {
2231 bool LoadAddr =
false;
2253 unsigned ADADelta = 0;
2254 unsigned EPADelta = 8;
2260 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2261 G->getGlobal()->hasPrivateLinkage());
2268 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2314 if (Subtarget.isTargetXPLINK64())
2318 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2322 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2341 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2349 unsigned NumParts = 1;
2353 SlotVT = Outs[
I].VT;
2361 assert(Outs[
I].PartOffset == 0);
2362 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2365 unsigned PartOffset = Outs[
I].PartOffset;
2371 assert(PartOffset &&
"Offset should be non-zero.");
2373 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2375 ArgValue = SpillSlot;
2392 if (!StackPtr.getNode())
2399 else if (VA.
getLocVT() == MVT::f16)
2412 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2416 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2422 if (!MemOpChains.
empty())
2430 if (Subtarget.isTargetXPLINK64()) {
2435 ->getAddressOfCalleeRegister();
2438 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2445 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2448 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2449 }
else if (IsTailCall) {
2452 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2457 for (
const auto &[Reg,
N] : RegsToPass) {
2464 Ops.push_back(Chain);
2465 Ops.push_back(Callee);
2469 for (
const auto &[Reg,
N] : RegsToPass)
2474 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2475 assert(Mask &&
"Missing call preserved mask for calling convention");
2480 Ops.push_back(Glue);
2489 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2499 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2506 VA.getLocVT(), Glue);
2523 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2525 Args.reserve(
Ops.size());
2531 Entry.IsZExt = !Entry.IsSExt;
2532 Args.push_back(Entry);
2543 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2554 const Type *RetTy)
const {
2557 for (
auto &Out : Outs)
2558 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2562 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2563 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2575 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2583 if (RetLocs.
empty())
2584 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2593 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2615 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2622 unsigned &CCValid) {
2623 unsigned Id =
Op.getConstantOperandVal(1);
2625 case Intrinsic::s390_tbegin:
2626 Opcode = SystemZISD::TBEGIN;
2630 case Intrinsic::s390_tbegin_nofloat:
2631 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2635 case Intrinsic::s390_tend:
2636 Opcode = SystemZISD::TEND;
2649 unsigned Id =
Op.getConstantOperandVal(0);
2651 case Intrinsic::s390_vpkshs:
2652 case Intrinsic::s390_vpksfs:
2653 case Intrinsic::s390_vpksgs:
2654 Opcode = SystemZISD::PACKS_CC;
2658 case Intrinsic::s390_vpklshs:
2659 case Intrinsic::s390_vpklsfs:
2660 case Intrinsic::s390_vpklsgs:
2661 Opcode = SystemZISD::PACKLS_CC;
2665 case Intrinsic::s390_vceqbs:
2666 case Intrinsic::s390_vceqhs:
2667 case Intrinsic::s390_vceqfs:
2668 case Intrinsic::s390_vceqgs:
2669 case Intrinsic::s390_vceqqs:
2670 Opcode = SystemZISD::VICMPES;
2674 case Intrinsic::s390_vchbs:
2675 case Intrinsic::s390_vchhs:
2676 case Intrinsic::s390_vchfs:
2677 case Intrinsic::s390_vchgs:
2678 case Intrinsic::s390_vchqs:
2679 Opcode = SystemZISD::VICMPHS;
2683 case Intrinsic::s390_vchlbs:
2684 case Intrinsic::s390_vchlhs:
2685 case Intrinsic::s390_vchlfs:
2686 case Intrinsic::s390_vchlgs:
2687 case Intrinsic::s390_vchlqs:
2688 Opcode = SystemZISD::VICMPHLS;
2692 case Intrinsic::s390_vtm:
2693 Opcode = SystemZISD::VTM;
2697 case Intrinsic::s390_vfaebs:
2698 case Intrinsic::s390_vfaehs:
2699 case Intrinsic::s390_vfaefs:
2700 Opcode = SystemZISD::VFAE_CC;
2704 case Intrinsic::s390_vfaezbs:
2705 case Intrinsic::s390_vfaezhs:
2706 case Intrinsic::s390_vfaezfs:
2707 Opcode = SystemZISD::VFAEZ_CC;
2711 case Intrinsic::s390_vfeebs:
2712 case Intrinsic::s390_vfeehs:
2713 case Intrinsic::s390_vfeefs:
2714 Opcode = SystemZISD::VFEE_CC;
2718 case Intrinsic::s390_vfeezbs:
2719 case Intrinsic::s390_vfeezhs:
2720 case Intrinsic::s390_vfeezfs:
2721 Opcode = SystemZISD::VFEEZ_CC;
2725 case Intrinsic::s390_vfenebs:
2726 case Intrinsic::s390_vfenehs:
2727 case Intrinsic::s390_vfenefs:
2728 Opcode = SystemZISD::VFENE_CC;
2732 case Intrinsic::s390_vfenezbs:
2733 case Intrinsic::s390_vfenezhs:
2734 case Intrinsic::s390_vfenezfs:
2735 Opcode = SystemZISD::VFENEZ_CC;
2739 case Intrinsic::s390_vistrbs:
2740 case Intrinsic::s390_vistrhs:
2741 case Intrinsic::s390_vistrfs:
2742 Opcode = SystemZISD::VISTR_CC;
2746 case Intrinsic::s390_vstrcbs:
2747 case Intrinsic::s390_vstrchs:
2748 case Intrinsic::s390_vstrcfs:
2749 Opcode = SystemZISD::VSTRC_CC;
2753 case Intrinsic::s390_vstrczbs:
2754 case Intrinsic::s390_vstrczhs:
2755 case Intrinsic::s390_vstrczfs:
2756 Opcode = SystemZISD::VSTRCZ_CC;
2760 case Intrinsic::s390_vstrsb:
2761 case Intrinsic::s390_vstrsh:
2762 case Intrinsic::s390_vstrsf:
2763 Opcode = SystemZISD::VSTRS_CC;
2767 case Intrinsic::s390_vstrszb:
2768 case Intrinsic::s390_vstrszh:
2769 case Intrinsic::s390_vstrszf:
2770 Opcode = SystemZISD::VSTRSZ_CC;
2774 case Intrinsic::s390_vfcedbs:
2775 case Intrinsic::s390_vfcesbs:
2776 Opcode = SystemZISD::VFCMPES;
2780 case Intrinsic::s390_vfchdbs:
2781 case Intrinsic::s390_vfchsbs:
2782 Opcode = SystemZISD::VFCMPHS;
2786 case Intrinsic::s390_vfchedbs:
2787 case Intrinsic::s390_vfchesbs:
2788 Opcode = SystemZISD::VFCMPHES;
2792 case Intrinsic::s390_vftcidb:
2793 case Intrinsic::s390_vftcisb:
2794 Opcode = SystemZISD::VFTCI;
2798 case Intrinsic::s390_tdc:
2799 Opcode = SystemZISD::TDC;
2812 unsigned NumOps =
Op.getNumOperands();
2815 Ops.push_back(
Op.getOperand(0));
2817 Ops.push_back(
Op.getOperand(
I));
2819 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2833 unsigned NumOps =
Op.getNumOperands();
2839 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2840 "Unhandled intrinsic with f16 operand.");
2843 Ops.push_back(CurrOper);
2857 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2858 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2859 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2885 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2888 int64_t
Value = ConstOp1->getSExtValue();
2904 if (!
C.Op0.hasOneUse() ||
2911 unsigned NumBits = Load->getMemoryVT().getSizeInBits();
2912 if ((NumBits != 8 && NumBits != 16) ||
2913 NumBits != Load->getMemoryVT().getStoreSizeInBits())
2919 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2922 uint64_t Mask = (1 << NumBits) - 1;
2925 int64_t SignedValue = ConstOp1->getSExtValue();
2932 }
else if (NumBits == 8) {
2958 if (
C.Op0.getValueType() != MVT::i32 ||
2959 Load->getExtensionType() != ExtType) {
2961 Load->getBasePtr(), Load->getPointerInfo(),
2962 Load->getMemoryVT(), Load->getAlign(),
2963 Load->getMemOperand()->getFlags());
2969 if (
C.Op1.getValueType() != MVT::i32 ||
2970 Value != ConstOp1->getZExtValue())
2980 if (Load->getMemoryVT() == MVT::i8)
2983 switch (Load->getExtensionType()) {
3000 if (
C.Op0.getValueType() == MVT::i128)
3002 if (
C.Op0.getValueType() == MVT::f128)
3014 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3043 unsigned Opcode0 =
C.Op0.getOpcode();
3050 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3065 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3066 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3088 if (C1 && C1->isZero()) {
3107 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3110 if (C1 && C1->getZExtValue() == 32) {
3111 SDValue ShlOp0 =
C.Op0.getOperand(0);
3130 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3133 C.Op1->getAsZExtVal() == 0) {
3135 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3136 C.Op0.getValueSizeInBits().getFixedValue()) {
3137 unsigned Type = L->getExtensionType();
3140 C.Op0 =
C.Op0.getOperand(0);
3154 uint64_t Amount = Shift->getZExtValue();
3155 if (Amount >=
N.getValueSizeInBits())
3170 unsigned ICmpType) {
3171 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3193 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3199 if (EffectivelyUnsigned && CmpVal <
Low) {
3207 if (CmpVal == Mask) {
3213 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3219 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3227 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3233 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3262 if (
C.Op0.getValueType() == MVT::i128) {
3268 if (Mask && Mask->getAPIntValue() == 0) {
3269 C.Opcode = SystemZISD::VTM;
3286 uint64_t CmpVal = ConstOp1->getZExtValue();
3293 NewC.Op0 =
C.Op0.getOperand(0);
3294 NewC.Op1 =
C.Op0.getOperand(1);
3298 MaskVal = Mask->getZExtValue();
3318 MaskVal = -(CmpVal & -CmpVal);
3327 unsigned NewCCMask, ShiftVal;
3331 (MaskVal >> ShiftVal != 0) &&
3332 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3334 MaskVal >> ShiftVal,
3338 MaskVal >>= ShiftVal;
3342 (MaskVal << ShiftVal != 0) &&
3343 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3345 MaskVal << ShiftVal,
3349 MaskVal <<= ShiftVal;
3358 C.Opcode = SystemZISD::TM;
3360 if (Mask && Mask->getZExtValue() == MaskVal)
3365 C.CCMask = NewCCMask;
3371 if (
C.Opcode != SystemZISD::ICMP)
3373 if (
C.Op0.getValueType() != MVT::i128)
3384 Src = Src.getOperand(0);
3387 unsigned Opcode = 0;
3388 if (Src.hasOneUse()) {
3389 switch (Src.getOpcode()) {
3390 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3391 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3392 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3393 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3394 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3395 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3401 C.Op0 = Src->getOperand(0);
3402 C.Op1 = Src->getOperand(1);
3406 C.CCMask ^=
C.CCValid;
3418 C.Opcode = SystemZISD::VICMPES;
3430 bool Swap =
false, Invert =
false;
3442 C.Opcode = SystemZISD::UCMP128HI;
3444 C.Opcode = SystemZISD::SCMP128HI;
3449 C.CCMask ^=
C.CCValid;
3460 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3463 if ((~Known.
Zero).getZExtValue() & ~Mask->getZExtValue())
3466 C.Op0 =
C.Op0.getOperand(0);
3478 C.CCValid = CCValid;
3481 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3484 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3488 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3491 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3495 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3498 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3501 C.CCMask &= CCValid;
3509 bool IsSignaling =
false) {
3512 unsigned Opcode, CCValid;
3524 Comparison
C(CmpOp0, CmpOp1, Chain);
3526 if (
C.Op0.getValueType().isFloatingPoint()) {
3529 C.Opcode = SystemZISD::FCMP;
3530 else if (!IsSignaling)
3531 C.Opcode = SystemZISD::STRICT_FCMP;
3533 C.Opcode = SystemZISD::STRICT_FCMPS;
3538 C.Opcode = SystemZISD::ICMP;
3573 if (!
C.Op1.getNode()) {
3575 switch (
C.Op0.getOpcode()) {
3586 if (
C.Opcode == SystemZISD::ICMP)
3587 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3589 if (
C.Opcode == SystemZISD::TM) {
3592 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3595 if (
C.Opcode == SystemZISD::VICMPES ||
3596 C.Opcode == SystemZISD::VICMPHS ||
3597 C.Opcode == SystemZISD::VICMPHLS ||
3598 C.Opcode == SystemZISD::VFCMPES ||
3599 C.Opcode == SystemZISD::VFCMPHS ||
3600 C.Opcode == SystemZISD::VFCMPHES) {
3601 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3608 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3610 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3619 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3620 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3645 unsigned CCValid,
unsigned CCMask) {
3650 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3728 int Mask[] = { Start, -1, Start + 1, -1 };
3732 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3734 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3748 !Subtarget.hasVectorEnhancements1()) {
3754 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3767 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3770 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3771 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3773 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3786 bool IsSignaling)
const {
3789 assert (!IsSignaling || Chain);
3792 bool Invert =
false;
3800 assert(IsFP &&
"Unexpected integer comparison");
3802 DL, VT, CmpOp1, CmpOp0, Chain);
3804 DL, VT, CmpOp0, CmpOp1, Chain);
3808 LT.getValue(1),
GE.getValue(1));
3817 assert(IsFP &&
"Unexpected integer comparison");
3819 DL, VT, CmpOp1, CmpOp0, Chain);
3821 DL, VT, CmpOp0, CmpOp1, Chain);
3825 LT.getValue(1),
GT.getValue(1));
3846 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3850 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3855 Chain =
Cmp.getValue(1);
3863 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3876 EVT VT =
Op.getValueType();
3878 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3887 bool IsSignaling)
const {
3893 EVT VT =
Op.getNode()->getValueType(0);
3895 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3896 Chain, IsSignaling);
3918 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
3952 C.CCMask ^=
C.CCValid;
3960 Op = SystemZISD::VICMPE;
3964 Op = SystemZISD::VICMPHL;
3966 Op = SystemZISD::VICMPH;
4005 C.Op1->getAsZExtVal() == 0) {
4012 if (Subtarget.hasVectorEnhancements3() &&
4013 C.Opcode == SystemZISD::ICMP &&
4014 C.Op0.getValueType() == MVT::i128 &&
4024 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4030 const GlobalValue *GV =
Node->getGlobal();
4036 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4039 uint64_t Anchor =
Offset & ~uint64_t(0xfff);
4058 }
else if (Subtarget.isTargetELF()) {
4063 }
else if (Subtarget.isTargetzOS()) {
4094 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4099 Ops.push_back(Chain);
4101 Node->getValueType(0),
4110 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4111 const uint32_t *
Mask =
4113 assert(Mask &&
"Missing call preserved mask for calling convention");
4117 Ops.push_back(Glue);
4120 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4128SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4152 const GlobalValue *GV =
Node->getGlobal();
4160 SDValue TP = lowerThreadPointer(
DL, DAG);
4167 SystemZConstantPoolValue *CPV =
4176 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4182 SystemZConstantPoolValue *CPV =
4191 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4196 SystemZMachineFunctionInfo* MFI =
4225 SystemZConstantPoolValue *CPV =
4259 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4268 if (
CP->isMachineConstantPoolEntry())
4276 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4281 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4283 MachineFrameInfo &MFI = MF.getFrameInfo();
4287 unsigned Depth =
Op.getConstantOperandVal(0);
4294 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4299 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4305 MachinePointerInfo());
4320 unsigned Depth =
Op.getConstantOperandVal(0);
4325 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4328 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4329 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4330 int Offset = TFL->getReturnAddressOffset(MF);
4334 MachinePointerInfo());
4339 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4341 &SystemZ::GR64BitRegClass);
4349 EVT InVT =
In.getValueType();
4350 EVT ResVT =
Op.getValueType();
4358 LoadN->getBasePtr(), LoadN->getMemOperand());
4364 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4366 if (Subtarget.hasHighWord()) {
4370 MVT::i64,
SDValue(U64, 0), In);
4378 DL, MVT::f32, Out64);
4380 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4383 MVT::f64,
SDValue(U64, 0), In);
4385 if (Subtarget.hasHighWord())
4398 if (Subtarget.isTargetXPLINK64())
4399 return lowerVASTART_XPLINK(
Op, DAG);
4401 return lowerVASTART_ELF(
Op, DAG);
4407 SystemZMachineFunctionInfo *FuncInfo =
4408 MF.
getInfo<SystemZMachineFunctionInfo>();
4418 MachinePointerInfo(SV));
4424 SystemZMachineFunctionInfo *FuncInfo =
4425 MF.
getInfo<SystemZMachineFunctionInfo>();
4434 const unsigned NumFields = 4;
4445 for (
unsigned I = 0;
I < NumFields; ++
I) {
4450 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4451 MachinePointerInfo(SV,
Offset));
4469 Align(8),
false,
false,
4470 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4471 MachinePointerInfo(SrcSV));
4475SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4477 if (Subtarget.isTargetXPLINK64())
4478 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4480 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4484SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4486 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4496 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4499 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4500 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4506 if (ExtraAlignSpace)
4510 bool IsSigned =
false;
4511 bool DoesNotReturn =
false;
4512 bool IsReturnValueUsed =
false;
4513 EVT VT =
Op.getValueType();
4523 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4535 if (ExtraAlignSpace) {
4547SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4549 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4552 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4561 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4564 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4565 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4576 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4577 MachinePointerInfo());
4580 if (ExtraAlignSpace)
4587 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4588 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4604 if (RequiredAlign > StackAlign) {
4614 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4615 MachinePointerInfo());
4621SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4625 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4630 unsigned Opcode)
const {
4631 EVT VT =
Op.getValueType();
4637 assert(Subtarget.hasMiscellaneousExtensions2());
4642 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4648 EVT VT =
Op.getValueType();
4656 else if (Subtarget.hasMiscellaneousExtensions2())
4661 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4696 EVT VT =
Op.getValueType();
4709 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4717 EVT VT =
Op.getValueType();
4737 EVT VT =
Op.getValueType();
4744 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4749 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4761 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4763 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4800 MVT::i64, HighOp, Low32);
4806 SDNode *
N =
Op.getNode();
4811 if (
N->getValueType(0) == MVT::i128) {
4812 unsigned BaseOp = 0;
4813 unsigned FlagOp = 0;
4814 bool IsBorrow =
false;
4815 switch (
Op.getOpcode()) {
4819 FlagOp = SystemZISD::VACC;
4823 FlagOp = SystemZISD::VSCBI;
4838 unsigned BaseOp = 0;
4839 unsigned CCValid = 0;
4840 unsigned CCMask = 0;
4842 switch (
Op.getOpcode()) {
4845 BaseOp = SystemZISD::SADDO;
4850 BaseOp = SystemZISD::SSUBO;
4855 BaseOp = SystemZISD::UADDO;
4860 BaseOp = SystemZISD::USUBO;
4866 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4870 if (
N->getValueType(1) == MVT::i1)
4896 SDNode *
N =
Op.getNode();
4897 MVT VT =
N->getSimpleValueType(0);
4908 if (VT == MVT::i128) {
4909 unsigned BaseOp = 0;
4910 unsigned FlagOp = 0;
4911 bool IsBorrow =
false;
4912 switch (
Op.getOpcode()) {
4915 BaseOp = SystemZISD::VAC;
4916 FlagOp = SystemZISD::VACCC;
4919 BaseOp = SystemZISD::VSBI;
4920 FlagOp = SystemZISD::VSBCBI;
4939 unsigned BaseOp = 0;
4940 unsigned CCValid = 0;
4941 unsigned CCMask = 0;
4943 switch (
Op.getOpcode()) {
4949 BaseOp = SystemZISD::ADDCARRY;
4957 BaseOp = SystemZISD::SUBCARRY;
4968 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
4972 if (
N->getValueType(1) == MVT::i1)
4980 EVT VT =
Op.getValueType();
4982 Op =
Op.getOperand(0);
5005 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5017 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5030 if (NumSignificantBits == 0)
5036 BitSize = std::min(BitSize, OrigBitSize);
5045 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5047 if (BitSize != OrigBitSize)
5084 EVT RegVT =
Op.getValueType();
5086 return lowerATOMIC_LDST_I128(
Op, DAG);
5087 return lowerLoadF16(
Op, DAG);
5093 if (
Node->getMemoryVT().getSizeInBits() == 128)
5094 return lowerATOMIC_LDST_I128(
Op, DAG);
5095 return lowerStoreF16(
Op, DAG);
5102 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5103 "Only custom lowering i128 or f128.");
5116 EVT WideVT = MVT::i32;
5139 unsigned Opcode)
const {
5143 EVT NarrowVT =
Node->getMemoryVT();
5144 EVT WideVT = MVT::i32;
5145 if (NarrowVT == WideVT)
5152 MachineMemOperand *MMO =
Node->getMemOperand();
5156 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5158 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5163 SDValue AlignedAddr, BitShift, NegBitShift;
5171 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5174 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5175 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5180 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5181 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5201 EVT MemVT =
Node->getMemoryVT();
5202 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5204 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5205 assert(Subtarget.hasInterlockedAccess1() &&
5206 "Should have been expanded by AtomicExpand pass.");
5212 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5213 Node->getMemOperand());
5216 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5227 MachineMemOperand *MMO =
Node->getMemOperand();
5230 if (
Node->getMemoryVT() == MVT::i128) {
5239 EVT NarrowVT =
Node->getMemoryVT();
5240 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5241 if (NarrowVT == WideVT) {
5242 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5243 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5245 DL, Tys,
Ops, NarrowVT, MMO);
5259 SDValue AlignedAddr, BitShift, NegBitShift;
5263 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5264 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5267 VTList,
Ops, NarrowVT, MMO);
5281SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5304 auto *Regs = Subtarget.getSpecialRegisters();
5307 "in GHC calling convention");
5309 Regs->getStackPointerRegister(),
Op.getValueType());
5315 auto *Regs = Subtarget.getSpecialRegisters();
5316 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5320 "in GHC calling convention");
5327 if (StoreBackchain) {
5329 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5330 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5331 MachinePointerInfo());
5334 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5337 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5338 MachinePointerInfo());
5345 bool IsData =
Op.getConstantOperandVal(4);
5348 return Op.getOperand(0);
5351 bool IsWrite =
Op.getConstantOperandVal(2);
5358 Node->getMemoryVT(),
Node->getMemOperand());
5362SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5364 unsigned Opcode, CCValid;
5366 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5377SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5379 unsigned Opcode, CCValid;
5382 if (
Op->getNumValues() == 1)
5384 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5389 unsigned Id =
Op.getConstantOperandVal(0);
5391 case Intrinsic::thread_pointer:
5392 return lowerThreadPointer(SDLoc(
Op), DAG);
5394 case Intrinsic::s390_vpdi:
5395 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5396 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5398 case Intrinsic::s390_vperm:
5399 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5400 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5402 case Intrinsic::s390_vuphb:
5403 case Intrinsic::s390_vuphh:
5404 case Intrinsic::s390_vuphf:
5405 case Intrinsic::s390_vuphg:
5406 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5409 case Intrinsic::s390_vuplhb:
5410 case Intrinsic::s390_vuplhh:
5411 case Intrinsic::s390_vuplhf:
5412 case Intrinsic::s390_vuplhg:
5413 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5416 case Intrinsic::s390_vuplb:
5417 case Intrinsic::s390_vuplhw:
5418 case Intrinsic::s390_vuplf:
5419 case Intrinsic::s390_vuplg:
5420 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5423 case Intrinsic::s390_vupllb:
5424 case Intrinsic::s390_vupllh:
5425 case Intrinsic::s390_vupllf:
5426 case Intrinsic::s390_vupllg:
5427 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5430 case Intrinsic::s390_vsumb:
5431 case Intrinsic::s390_vsumh:
5432 case Intrinsic::s390_vsumgh:
5433 case Intrinsic::s390_vsumgf:
5434 case Intrinsic::s390_vsumqf:
5435 case Intrinsic::s390_vsumqg:
5436 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5437 Op.getOperand(1),
Op.getOperand(2));
5439 case Intrinsic::s390_vaq:
5441 Op.getOperand(1),
Op.getOperand(2));
5442 case Intrinsic::s390_vaccb:
5443 case Intrinsic::s390_vacch:
5444 case Intrinsic::s390_vaccf:
5445 case Intrinsic::s390_vaccg:
5446 case Intrinsic::s390_vaccq:
5447 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5448 Op.getOperand(1),
Op.getOperand(2));
5449 case Intrinsic::s390_vacq:
5450 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5451 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5452 case Intrinsic::s390_vacccq:
5453 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5454 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5456 case Intrinsic::s390_vsq:
5458 Op.getOperand(1),
Op.getOperand(2));
5459 case Intrinsic::s390_vscbib:
5460 case Intrinsic::s390_vscbih:
5461 case Intrinsic::s390_vscbif:
5462 case Intrinsic::s390_vscbig:
5463 case Intrinsic::s390_vscbiq:
5464 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5465 Op.getOperand(1),
Op.getOperand(2));
5466 case Intrinsic::s390_vsbiq:
5467 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5468 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5469 case Intrinsic::s390_vsbcbiq:
5470 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5471 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5473 case Intrinsic::s390_vmhb:
5474 case Intrinsic::s390_vmhh:
5475 case Intrinsic::s390_vmhf:
5476 case Intrinsic::s390_vmhg:
5477 case Intrinsic::s390_vmhq:
5479 Op.getOperand(1),
Op.getOperand(2));
5480 case Intrinsic::s390_vmlhb:
5481 case Intrinsic::s390_vmlhh:
5482 case Intrinsic::s390_vmlhf:
5483 case Intrinsic::s390_vmlhg:
5484 case Intrinsic::s390_vmlhq:
5486 Op.getOperand(1),
Op.getOperand(2));
5488 case Intrinsic::s390_vmahb:
5489 case Intrinsic::s390_vmahh:
5490 case Intrinsic::s390_vmahf:
5491 case Intrinsic::s390_vmahg:
5492 case Intrinsic::s390_vmahq:
5493 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5494 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5495 case Intrinsic::s390_vmalhb:
5496 case Intrinsic::s390_vmalhh:
5497 case Intrinsic::s390_vmalhf:
5498 case Intrinsic::s390_vmalhg:
5499 case Intrinsic::s390_vmalhq:
5500 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5501 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5503 case Intrinsic::s390_vmeb:
5504 case Intrinsic::s390_vmeh:
5505 case Intrinsic::s390_vmef:
5506 case Intrinsic::s390_vmeg:
5507 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5508 Op.getOperand(1),
Op.getOperand(2));
5509 case Intrinsic::s390_vmleb:
5510 case Intrinsic::s390_vmleh:
5511 case Intrinsic::s390_vmlef:
5512 case Intrinsic::s390_vmleg:
5513 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5514 Op.getOperand(1),
Op.getOperand(2));
5515 case Intrinsic::s390_vmob:
5516 case Intrinsic::s390_vmoh:
5517 case Intrinsic::s390_vmof:
5518 case Intrinsic::s390_vmog:
5519 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5520 Op.getOperand(1),
Op.getOperand(2));
5521 case Intrinsic::s390_vmlob:
5522 case Intrinsic::s390_vmloh:
5523 case Intrinsic::s390_vmlof:
5524 case Intrinsic::s390_vmlog:
5525 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5526 Op.getOperand(1),
Op.getOperand(2));
5528 case Intrinsic::s390_vmaeb:
5529 case Intrinsic::s390_vmaeh:
5530 case Intrinsic::s390_vmaef:
5531 case Intrinsic::s390_vmaeg:
5533 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5534 Op.getOperand(1),
Op.getOperand(2)),
5536 case Intrinsic::s390_vmaleb:
5537 case Intrinsic::s390_vmaleh:
5538 case Intrinsic::s390_vmalef:
5539 case Intrinsic::s390_vmaleg:
5541 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5542 Op.getOperand(1),
Op.getOperand(2)),
5544 case Intrinsic::s390_vmaob:
5545 case Intrinsic::s390_vmaoh:
5546 case Intrinsic::s390_vmaof:
5547 case Intrinsic::s390_vmaog:
5549 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5550 Op.getOperand(1),
Op.getOperand(2)),
5552 case Intrinsic::s390_vmalob:
5553 case Intrinsic::s390_vmaloh:
5554 case Intrinsic::s390_vmalof:
5555 case Intrinsic::s390_vmalog:
5557 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5558 Op.getOperand(1),
Op.getOperand(2)),
5579 { SystemZISD::MERGE_HIGH, 8,
5580 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5582 { SystemZISD::MERGE_HIGH, 4,
5583 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5585 { SystemZISD::MERGE_HIGH, 2,
5586 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5588 { SystemZISD::MERGE_HIGH, 1,
5589 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5591 { SystemZISD::MERGE_LOW, 8,
5592 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5594 { SystemZISD::MERGE_LOW, 4,
5595 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5597 { SystemZISD::MERGE_LOW, 2,
5598 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5600 { SystemZISD::MERGE_LOW, 1,
5601 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5603 { SystemZISD::PACK, 4,
5604 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5606 { SystemZISD::PACK, 2,
5607 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5609 { SystemZISD::PACK, 1,
5610 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5612 { SystemZISD::PERMUTE_DWORDS, 4,
5613 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5615 { SystemZISD::PERMUTE_DWORDS, 1,
5616 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5630 OpNo0 = OpNo1 = OpNos[1];
5631 }
else if (OpNos[1] < 0) {
5632 OpNo0 = OpNo1 = OpNos[0];
5650 unsigned &OpNo0,
unsigned &OpNo1) {
5651 int OpNos[] = { -1, -1 };
5664 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5666 OpNos[ModelOpNo] = RealOpNo;
5674 unsigned &OpNo0,
unsigned &OpNo1) {
5691 int Elt = Bytes[From];
5694 Transform[From] = -1;
5696 while (
P.Bytes[To] != Elt) {
5701 Transform[From] = To;
5725 Bytes.
resize(NumElements * BytesPerElement, -1);
5726 for (
unsigned I = 0;
I < NumElements; ++
I) {
5727 int Index = VSN->getMaskElt(
I);
5729 for (
unsigned J = 0; J < BytesPerElement; ++J)
5730 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5734 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5737 Bytes.
resize(NumElements * BytesPerElement, -1);
5738 for (
unsigned I = 0;
I < NumElements; ++
I)
5739 for (
unsigned J = 0; J < BytesPerElement; ++J)
5740 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5751 unsigned BytesPerElement,
int &
Base) {
5753 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5754 if (Bytes[Start +
I] >= 0) {
5755 unsigned Elem = Bytes[Start +
I];
5759 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5761 }
else if (
unsigned(
Base) != Elem -
I)
5774 unsigned &StartIndex,
unsigned &OpNo0,
5776 int OpNos[] = { -1, -1 };
5778 for (
unsigned I = 0;
I < 16; ++
I) {
5779 int Index = Bytes[
I];
5785 Shift = ExpectedShift;
5786 else if (Shift != ExpectedShift)
5790 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5792 OpNos[ModelOpNo] = RealOpNo;
5805 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5806 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5814 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5816 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5817 }
else if (
P.Opcode == SystemZISD::PACK) {
5820 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5829 N =
N->getOperand(0);
5832 return Op->getZExtValue() == 0;
5838 for (
unsigned I = 0;
I < Num ;
I++)
5850 for (
unsigned I = 0;
I < 2; ++
I)
5854 unsigned StartIndex, OpNo0, OpNo1;
5856 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5863 if (ZeroVecIdx != UINT32_MAX) {
5864 bool MaskFirst =
true;
5869 if (OpNo == ZeroVecIdx &&
I == 0) {
5874 if (OpNo != ZeroVecIdx && Byte == 0) {
5881 if (ZeroIdx != -1) {
5884 if (Bytes[
I] >= 0) {
5887 if (OpNo == ZeroVecIdx)
5899 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5902 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
5914 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
5920struct GeneralShuffle {
5921 GeneralShuffle(EVT vt)
5922 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
5926 void tryPrepareForUnpack();
5927 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
5942 unsigned UnpackFromEltSize;
5949void GeneralShuffle::addUndef() {
5951 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
5952 Bytes.push_back(-1);
5961bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
5967 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
5972 if (FromBytesPerElement < BytesPerElement)
5976 (FromBytesPerElement - BytesPerElement));
5979 while (
Op.getNode()) {
5981 Op =
Op.getOperand(0);
5997 }
else if (
Op.isUndef()) {
6006 for (; OpNo <
Ops.size(); ++OpNo)
6007 if (
Ops[OpNo] ==
Op)
6009 if (OpNo ==
Ops.size())
6014 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6015 Bytes.push_back(
Base +
I);
6024 if (
Ops.size() == 0)
6028 tryPrepareForUnpack();
6031 if (
Ops.size() == 1)
6043 unsigned Stride = 1;
6044 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6045 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6055 else if (OpNo ==
I + Stride)
6066 if (NewBytes[J] >= 0) {
6068 "Invalid double permute");
6071 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6077 if (NewBytes[J] >= 0)
6093 unsigned OpNo0, OpNo1;
6097 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6102 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6109 dbgs() << Msg.c_str() <<
" { ";
6110 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6111 dbgs() << Bytes[
I] <<
" ";
6119void GeneralShuffle::tryPrepareForUnpack() {
6121 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6126 if (
Ops.size() > 2 &&
6131 UnpackFromEltSize = 1;
6132 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6133 bool MatchUnpack =
true;
6136 unsigned ToEltSize = UnpackFromEltSize * 2;
6137 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6140 if (Bytes[Elt] != -1) {
6142 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6143 MatchUnpack =
false;
6149 if (
Ops.size() == 2) {
6151 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6153 if (SrcBytes[i] == -1)
6155 if (SrcBytes[i] % 16 !=
int(i))
6156 CanUseUnpackHigh =
false;
6158 CanUseUnpackLow =
false;
6159 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6160 UnpackFromEltSize = UINT_MAX;
6164 if (!CanUseUnpackHigh)
6170 if (UnpackFromEltSize > 4)
6173 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6174 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6176 dumpBytes(Bytes,
"Original Bytes vector:"););
6185 Elt += UnpackFromEltSize;
6186 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6187 Bytes[
B] = Bytes[Elt];
6195 Ops.erase(&
Ops[ZeroVecOpNo]);
6197 if (Bytes[
I] >= 0) {
6199 if (OpNo > ZeroVecOpNo)
6210 if (!unpackWasPrepared())
6212 unsigned InBits = UnpackFromEltSize * 8;
6216 unsigned OutBits = InBits * 2;
6219 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6220 : SystemZISD::UNPACKL_HIGH,
6221 DL, OutVT, PackedOp);
6226 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6227 if (!
Op.getOperand(
I).isUndef())
6243 if (
Value.isUndef())
6255 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6258 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6259 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6280 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6296 GeneralShuffle GS(VT);
6298 bool FoundOne =
false;
6299 for (
unsigned I = 0;
I < NumElements; ++
I) {
6302 Op =
Op.getOperand(0);
6305 unsigned Elem =
Op.getConstantOperandVal(1);
6306 if (!GS.add(
Op.getOperand(0), Elem))
6309 }
else if (
Op.isUndef()) {
6323 if (!ResidueOps.
empty()) {
6324 while (ResidueOps.
size() < NumElements)
6326 for (
auto &
Op : GS.Ops) {
6327 if (!
Op.getNode()) {
6333 return GS.getNode(DAG,
SDLoc(BVN));
6336bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6342 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6353 unsigned int NumElements = Elems.
size();
6354 unsigned int Count = 0;
6355 for (
auto Elem : Elems) {
6356 if (!Elem.isUndef()) {
6359 else if (Elem != Single) {
6379 if (
Single.getNode() && (
Count > 1 || isVectorElementLoad(Single)))
6380 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Single);
6383 bool AllLoads =
true;
6384 for (
auto Elem : Elems)
6385 if (!isVectorElementLoad(Elem)) {
6391 if (VT == MVT::v2i64 && !AllLoads)
6395 if (VT == MVT::v2f64 && !AllLoads)
6405 if (VT == MVT::v4f32 && !AllLoads) {
6414 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6419 DL, MVT::v2i64, Op01, Op23);
6427 unsigned NumConstants = 0;
6428 for (
unsigned I = 0;
I < NumElements; ++
I) {
6442 if (NumConstants > 0) {
6443 for (
unsigned I = 0;
I < NumElements; ++
I)
6454 std::map<const SDNode*, unsigned> UseCounts;
6455 SDNode *LoadMaxUses =
nullptr;
6456 for (
unsigned I = 0;
I < NumElements; ++
I)
6457 if (isVectorElementLoad(Elems[
I])) {
6458 SDNode *Ld = Elems[
I].getNode();
6459 unsigned Count = ++UseCounts[Ld];
6460 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6463 if (LoadMaxUses !=
nullptr) {
6464 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6468 unsigned I1 = NumElements / 2 - 1;
6469 unsigned I2 = NumElements - 1;
6470 bool Def1 = !Elems[
I1].isUndef();
6471 bool Def2 = !Elems[I2].isUndef();
6485 for (
unsigned I = 0;
I < NumElements; ++
I)
6486 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6496 EVT VT =
Op.getValueType();
6498 if (BVN->isConstant()) {
6499 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6517 for (
unsigned I = 0;
I < NumElements; ++
I)
6519 return buildVector(DAG,
DL, VT,
Ops);
6526 EVT VT =
Op.getValueType();
6529 if (VSN->isSplat()) {
6531 unsigned Index = VSN->getSplatIndex();
6533 "Splat index should be defined and in first operand");
6539 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6543 GeneralShuffle
GS(VT);
6544 for (
unsigned I = 0;
I < NumElements; ++
I) {
6545 int Elt = VSN->getMaskElt(
I);
6548 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6549 unsigned(Elt) % NumElements))
6552 return GS.getNode(DAG, SDLoc(VSN));
6571 EVT VT =
Op.getValueType();
6576 if (VT == MVT::v2f64 &&
6596SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6602 EVT VT =
Op.getValueType();
6607 uint64_t
Index = CIndexN->getZExtValue();
6621SDValue SystemZTargetLowering::
6624 EVT OutVT =
Op.getValueType();
6628 unsigned StartOffset = 0;
6635 ArrayRef<int> ShuffleMask = SVN->
getMask();
6640 if (ToBits == 64 && OutNumElts == 2) {
6641 int NumElem = ToBits / FromBits;
6642 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6648 int StartOffsetCandidate = -1;
6649 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6650 if (ShuffleMask[Elt] == -1)
6652 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6653 if (StartOffsetCandidate == -1)
6654 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6655 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6658 StartOffsetCandidate = -1;
6661 if (StartOffsetCandidate != -1) {
6662 StartOffset = StartOffsetCandidate;
6671 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6672 if (StartOffset >= OutNumElts) {
6673 Opcode = SystemZISD::UNPACK_LOW;
6674 StartOffset -= OutNumElts;
6676 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6677 }
while (FromBits != ToBits);
6682SDValue SystemZTargetLowering::
6686 EVT OutVT =
Op.getValueType();
6690 unsigned NumInPerOut = InNumElts / OutNumElts;
6695 SmallVector<int, 16>
Mask(InNumElts);
6696 unsigned ZeroVecElt = InNumElts;
6697 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6698 unsigned MaskElt = PackedElt * NumInPerOut;
6699 unsigned End = MaskElt + NumInPerOut - 1;
6700 for (; MaskElt < End; MaskElt++)
6701 Mask[MaskElt] = ZeroVecElt++;
6702 Mask[MaskElt] = PackedElt;
6709 unsigned ByScalar)
const {
6714 EVT VT =
Op.getValueType();
6719 APInt SplatBits, SplatUndef;
6720 unsigned SplatBitSize;
6724 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6725 ElemBitSize,
true) &&
6726 SplatBitSize == ElemBitSize) {
6729 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6732 BitVector UndefElements;
6738 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6745 if (VSN->isSplat()) {
6746 SDValue VSNOp0 = VSN->getOperand(0);
6747 unsigned Index = VSN->getSplatIndex();
6749 "Splat index should be defined and in first operand");
6756 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6774 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6775 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6778 if (ShiftAmt > 120) {
6782 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6786 SmallVector<int, 16>
Mask(16);
6787 for (
unsigned Elt = 0; Elt < 16; Elt++)
6788 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6790 if ((ShiftAmt & 7) == 0)
6794 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6812 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6813 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6816 if (ShiftAmt > 120) {
6820 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6824 SmallVector<int, 16>
Mask(16);
6825 for (
unsigned Elt = 0; Elt < 16; Elt++)
6826 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6828 if ((ShiftAmt & 7) == 0)
6832 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
6844 MVT DstVT =
Op.getSimpleValueType();
6847 unsigned SrcAS =
N->getSrcAddressSpace();
6849 assert(SrcAS !=
N->getDestAddressSpace() &&
6850 "addrspacecast must be between different address spaces");
6858 }
else if (DstVT == MVT::i32) {
6872 if (
In.getSimpleValueType() != MVT::f16)
6879 SDValue Chain,
bool IsStrict)
const {
6880 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
6883 std::tie(Result, Chain) =
6892 bool IsStrict =
Op->isStrictFPOpcode();
6894 MVT VT =
Op.getSimpleValueType();
6895 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6903 if (!Subtarget.hasFPExtension() && !IsSigned)
6914 if (VT == MVT::i128) {
6917 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6927 bool IsStrict =
Op->isStrictFPOpcode();
6929 MVT VT =
Op.getSimpleValueType();
6930 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6935 if (VT == MVT::f16) {
6942 if (!Subtarget.hasFPExtension() && !IsSigned)
6945 if (InVT == MVT::i128) {
6948 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6957 assert(
Op.getSimpleValueType() == MVT::i64 &&
6958 "Expexted to convert i64 to f16.");
6970 assert(
Op.getSimpleValueType() == MVT::f16 &&
6971 "Expected to convert f16 to i64.");
6984 EVT RegVT =
Op.getValueType();
6985 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
6992 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
6994 AtomicLd->getChain(), AtomicLd->getBasePtr(),
6995 AtomicLd->getMemOperand());
7015 Shft, AtomicSt->getBasePtr(),
7016 AtomicSt->getMemOperand());
7026 MVT ResultVT =
Op.getSimpleValueType();
7028 unsigned Check =
Op.getConstantOperandVal(1);
7030 unsigned TDCMask = 0;
7067 MachinePointerInfo MPI =
7073 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7077 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7082 switch (
Op.getOpcode()) {
7084 return lowerFRAMEADDR(
Op, DAG);
7086 return lowerRETURNADDR(
Op, DAG);
7088 return lowerBR_CC(
Op, DAG);
7090 return lowerSELECT_CC(
Op, DAG);
7092 return lowerSETCC(
Op, DAG);
7094 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7096 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7108 return lowerBITCAST(
Op, DAG);
7110 return lowerVASTART(
Op, DAG);
7112 return lowerVACOPY(
Op, DAG);
7114 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7116 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7118 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7120 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7122 return lowerSMUL_LOHI(
Op, DAG);
7124 return lowerUMUL_LOHI(
Op, DAG);
7126 return lowerSDIVREM(
Op, DAG);
7128 return lowerUDIVREM(
Op, DAG);
7133 return lowerXALUO(
Op, DAG);
7136 return lowerUADDSUBO_CARRY(
Op, DAG);
7138 return lowerOR(
Op, DAG);
7140 return lowerCTPOP(
Op, DAG);
7142 return lowerVECREDUCE_ADD(
Op, DAG);
7144 return lowerATOMIC_FENCE(
Op, DAG);
7146 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7148 return lowerATOMIC_STORE(
Op, DAG);
7150 return lowerATOMIC_LOAD(
Op, DAG);
7152 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7154 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7156 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7158 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7160 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7162 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7164 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7166 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7168 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7170 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7172 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7174 return lowerSTACKSAVE(
Op, DAG);
7176 return lowerSTACKRESTORE(
Op, DAG);
7178 return lowerPREFETCH(
Op, DAG);
7180 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7182 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7184 return lowerBUILD_VECTOR(
Op, DAG);
7186 return lowerVECTOR_SHUFFLE(
Op, DAG);
7188 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7190 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7192 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7194 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7196 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7198 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7200 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7202 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7206 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7208 return lowerFSHL(
Op, DAG);
7210 return lowerFSHR(
Op, DAG);
7213 return lowerFP_EXTEND(
Op, DAG);
7218 return lower_FP_TO_INT(
Op, DAG);
7223 return lower_INT_TO_FP(
Op, DAG);
7225 return lowerLoadF16(
Op, DAG);
7227 return lowerStoreF16(
Op, DAG);
7229 return lowerIS_FPCLASS(
Op, DAG);
7231 return lowerGET_ROUNDING(
Op, DAG);
7233 return lowerREADCYCLECOUNTER(
Op, DAG);
7255 &SystemZ::FP128BitRegClass);
7264 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7279 &SystemZ::FP128BitRegClass);
7296 switch (
N->getOpcode()) {
7300 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7303 DL, Tys,
Ops, MVT::i128, MMO);
7306 if (
N->getValueType(0) == MVT::f128)
7320 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7323 DL, Tys,
Ops, MVT::i128, MMO);
7329 MVT::Other, Res), 0);
7341 DL, Tys,
Ops, MVT::i128, MMO);
7355 EVT SrcVT = Src.getValueType();
7356 EVT ResVT =
N->getValueType(0);
7357 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7359 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7360 if (Subtarget.hasVector()) {
7368 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7370 Subtarget.hasVector()
7384 bool IsStrict =
N->isStrictFPOpcode();
7386 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7387 EVT ResVT =
N->getValueType(0);
7389 if (ResVT == MVT::f16) {
7412 bool IsStrict =
N->isStrictFPOpcode();
7414 EVT ResVT =
N->getValueType(0);
7415 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7418 if (InVT == MVT::f16) {
7424 std::tie(InF32, Chain) =
7449bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7450 if (!Subtarget.hasVector())
7464 DAGCombinerInfo &DCI,
7472 unsigned Opcode =
Op.getOpcode();
7475 Op =
Op.getOperand(0);
7477 canTreatAsByteVector(
Op.getValueType())) {
7486 BytesPerElement,
First))
7493 if (Byte % BytesPerElement != 0)
7496 Index = Byte / BytesPerElement;
7500 canTreatAsByteVector(
Op.getValueType())) {
7503 EVT OpVT =
Op.getValueType();
7505 if (OpBytesPerElement < BytesPerElement)
7509 unsigned End = (
Index + 1) * BytesPerElement;
7510 if (End % OpBytesPerElement != 0)
7513 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7514 if (!
Op.getValueType().isInteger()) {
7517 DCI.AddToWorklist(
Op.getNode());
7522 DCI.AddToWorklist(
Op.getNode());
7529 canTreatAsByteVector(
Op.getValueType()) &&
7530 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7532 EVT ExtVT =
Op.getValueType();
7533 EVT OpVT =
Op.getOperand(0).getValueType();
7536 unsigned Byte =
Index * BytesPerElement;
7537 unsigned SubByte =
Byte % ExtBytesPerElement;
7538 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7539 if (SubByte < MinSubByte ||
7540 SubByte + BytesPerElement > ExtBytesPerElement)
7543 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7545 Byte += SubByte - MinSubByte;
7546 if (Byte % BytesPerElement != 0)
7548 Op =
Op.getOperand(0);
7555 if (
Op.getValueType() != VecVT) {
7557 DCI.AddToWorklist(
Op.getNode());
7567SDValue SystemZTargetLowering::combineTruncateExtract(
7576 if (canTreatAsByteVector(VecVT)) {
7580 if (BytesPerElement % TruncBytes == 0) {
7586 unsigned Scale = BytesPerElement / TruncBytes;
7587 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7594 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7595 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7603SDValue SystemZTargetLowering::combineZERO_EXTEND(
7604 SDNode *
N, DAGCombinerInfo &DCI)
const {
7606 SelectionDAG &DAG = DCI.DAG;
7608 EVT VT =
N->getValueType(0);
7609 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7612 if (TrueOp && FalseOp) {
7622 DCI.CombineTo(N0.
getNode(), TruncSelect);
7665 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7683SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7684 SDNode *
N, DAGCombinerInfo &DCI)
const {
7688 SelectionDAG &DAG = DCI.DAG;
7690 EVT VT =
N->getValueType(0);
7704SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7705 SDNode *
N, DAGCombinerInfo &DCI)
const {
7709 SelectionDAG &DAG = DCI.DAG;
7711 EVT VT =
N->getValueType(0);
7718 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7719 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7735SDValue SystemZTargetLowering::combineMERGE(
7736 SDNode *
N, DAGCombinerInfo &DCI)
const {
7737 SelectionDAG &DAG = DCI.DAG;
7738 unsigned Opcode =
N->getOpcode();
7746 if (Op1 ==
N->getOperand(0))
7751 if (ElemBytes <= 4) {
7752 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7753 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7759 DCI.AddToWorklist(Op1.
getNode());
7762 DCI.AddToWorklist(
Op.getNode());
7771 LoPart = HiPart =
nullptr;
7776 if (
Use.getResNo() != 0)
7781 bool IsLoPart =
true;
7806 LoPart = HiPart =
nullptr;
7811 if (
Use.getResNo() != 0)
7817 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7820 switch (
User->getConstantOperandVal(1)) {
7821 case SystemZ::subreg_l64:
7826 case SystemZ::subreg_h64:
7838SDValue SystemZTargetLowering::combineLOAD(
7839 SDNode *
N, DAGCombinerInfo &DCI)
const {
7840 SelectionDAG &DAG = DCI.DAG;
7841 EVT LdVT =
N->getValueType(0);
7845 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7846 if (PtrVT != LoadNodeVT) {
7850 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7851 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7852 LN->getMemOperand());
7862 SDNode *LoPart, *HiPart;
7870 LD->getPointerInfo(),
LD->getBaseAlign(),
7871 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7873 DCI.CombineTo(HiPart, EltLoad,
true);
7880 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
7881 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7883 DCI.CombineTo(LoPart, EltLoad,
true);
7890 DCI.AddToWorklist(Chain.
getNode());
7905 for (SDUse &Use :
N->uses()) {
7906 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
7910 }
else if (
Use.getResNo() == 0)
7913 if (!Replicate || OtherUses.
empty())
7919 for (SDNode *U : OtherUses) {
7922 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
7928bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
7929 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
7931 if (Subtarget.hasVectorEnhancements2())
7932 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
7944 for (
unsigned i = 0; i < NumElts; ++i) {
7945 if (M[i] < 0)
continue;
7946 if ((
unsigned) M[i] != NumElts - 1 - i)
7954 for (
auto *U : StoredVal->
users()) {
7956 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8015SDValue SystemZTargetLowering::combineSTORE(
8016 SDNode *
N, DAGCombinerInfo &DCI)
const {
8017 SelectionDAG &DAG = DCI.DAG;
8020 EVT MemVT = SN->getMemoryVT();
8024 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8025 if (PtrVT != StoreNodeVT) {
8029 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8030 SN->getPointerInfo(), SN->getBaseAlign(),
8031 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8039 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8041 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8042 DCI.AddToWorklist(
Value.getNode());
8046 SN->getBasePtr(), SN->getMemoryVT(),
8047 SN->getMemOperand());
8051 if (!SN->isTruncatingStore() &&
8067 Ops, MemVT, SN->getMemOperand());
8070 if (!SN->isTruncatingStore() &&
8073 Subtarget.hasVectorEnhancements2()) {
8075 ArrayRef<int> ShuffleMask = SVN->
getMask();
8083 Ops, MemVT, SN->getMemOperand());
8088 if (!SN->isTruncatingStore() &&
8091 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8095 Ops, MemVT, SN->getMemOperand());
8105 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8106 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8108 SN->getChain(),
DL, LoPart,
8110 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8111 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8129 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8131 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8135 APInt Val =
C->getAPIntValue();
8138 assert(SN->isTruncatingStore() &&
8139 "Non-truncating store and immediate value does not fit?");
8140 Val = Val.
trunc(TotBytes * 8);
8143 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8144 if (VCI.isVectorConstantLegal(Subtarget) &&
8145 VCI.Opcode == SystemZISD::REPLICATE) {
8153 auto FindReplicatedReg = [&](
SDValue MulOp) {
8154 EVT MulVT = MulOp.getValueType();
8155 if (MulOp->getOpcode() ==
ISD::MUL &&
8156 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8160 WordVT =
LHS->getOperand(0).getValueType();
8167 SystemZVectorConstantInfo VCI(
8169 if (VCI.isVectorConstantLegal(Subtarget) &&
8170 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8171 WordVT == VCI.VecVT.getScalarType())
8183 FindReplicatedReg(SplatVal);
8188 FindReplicatedReg(Op1);
8193 "Bad type handling");
8197 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8198 SN->getBasePtr(), SN->getMemOperand());
8205SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8206 SDNode *
N, DAGCombinerInfo &DCI)
const {
8207 SelectionDAG &DAG = DCI.DAG;
8210 N->getOperand(0).hasOneUse() &&
8211 Subtarget.hasVectorEnhancements2()) {
8213 ArrayRef<int> ShuffleMask = SVN->
getMask();
8226 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8230 DCI.CombineTo(
N, ESLoad);
8234 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8244SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8245 SDNode *
N, DAGCombinerInfo &DCI)
const {
8246 SelectionDAG &DAG = DCI.DAG;
8248 if (!Subtarget.hasVector())
8254 Op.getValueType().isVector() &&
8255 Op.getOperand(0).getValueType().isVector() &&
8256 Op.getValueType().getVectorNumElements() ==
8257 Op.getOperand(0).getValueType().getVectorNumElements())
8258 Op =
Op.getOperand(0);
8262 EVT VecVT =
Op.getValueType();
8265 Op.getOperand(0),
N->getOperand(1));
8266 DCI.AddToWorklist(
Op.getNode());
8268 if (EltVT !=
N->getValueType(0)) {
8269 DCI.AddToWorklist(
Op.getNode());
8279 if (canTreatAsByteVector(VecVT))
8280 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8281 IndexN->getZExtValue(), DCI,
false);
8286SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8287 SDNode *
N, DAGCombinerInfo &DCI)
const {
8288 SelectionDAG &DAG = DCI.DAG;
8290 if (
N->getOperand(0) ==
N->getOperand(1))
8291 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8301 if (Chain1 == Chain2)
8309SDValue SystemZTargetLowering::combineFP_ROUND(
8310 SDNode *
N, DAGCombinerInfo &DCI)
const {
8312 if (!Subtarget.hasVector())
8321 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8322 SelectionDAG &DAG = DCI.DAG;
8324 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8330 for (
auto *U : Vec->
users()) {
8331 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8333 U->getOperand(0) == Vec &&
8335 U->getConstantOperandVal(1) == 1) {
8337 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8341 if (
N->isStrictFPOpcode()) {
8345 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8346 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8349 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8351 DCI.AddToWorklist(VRound.
getNode());
8355 DCI.AddToWorklist(Extract1.
getNode());
8361 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8364 N->getVTList(), Extract0, Chain);
8373SDValue SystemZTargetLowering::combineFP_EXTEND(
8374 SDNode *
N, DAGCombinerInfo &DCI)
const {
8376 if (!Subtarget.hasVector())
8385 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8386 SelectionDAG &DAG = DCI.DAG;
8388 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8394 for (
auto *U : Vec->
users()) {
8395 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8397 U->getOperand(0) == Vec &&
8399 U->getConstantOperandVal(1) == 2) {
8401 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8405 if (
N->isStrictFPOpcode()) {
8409 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8410 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8413 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8415 DCI.AddToWorklist(VExtend.
getNode());
8419 DCI.AddToWorklist(Extract1.
getNode());
8425 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8428 N->getVTList(), Extract0, Chain);
8437SDValue SystemZTargetLowering::combineINT_TO_FP(
8438 SDNode *
N, DAGCombinerInfo &DCI)
const {
8441 SelectionDAG &DAG = DCI.DAG;
8443 unsigned Opcode =
N->getOpcode();
8444 EVT OutVT =
N->getValueType(0);
8448 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8454 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8455 OutScalarBits <= 64) {
8459 unsigned ExtOpcode =
8462 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8467SDValue SystemZTargetLowering::combineFCOPYSIGN(
8468 SDNode *
N, DAGCombinerInfo &DCI)
const {
8469 SelectionDAG &DAG = DCI.DAG;
8470 EVT VT =
N->getValueType(0);
8483SDValue SystemZTargetLowering::combineBSWAP(
8484 SDNode *
N, DAGCombinerInfo &DCI)
const {
8485 SelectionDAG &DAG = DCI.DAG;
8488 N->getOperand(0).hasOneUse() &&
8489 canLoadStoreByteSwapped(
N->getValueType(0))) {
8498 EVT LoadVT =
N->getValueType(0);
8499 if (LoadVT == MVT::i16)
8504 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8508 if (
N->getValueType(0) == MVT::i16)
8513 DCI.CombineTo(
N, ResVal);
8517 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8526 Op.getValueType().isVector() &&
8527 Op.getOperand(0).getValueType().isVector() &&
8528 Op.getValueType().getVectorNumElements() ==
8529 Op.getOperand(0).getValueType().getVectorNumElements())
8530 Op =
Op.getOperand(0);
8542 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8544 EVT VecVT =
N->getValueType(0);
8548 DCI.AddToWorklist(Vec.
getNode());
8552 DCI.AddToWorklist(Elt.
getNode());
8555 DCI.AddToWorklist(Vec.
getNode());
8557 DCI.AddToWorklist(Elt.
getNode());
8565 if (SV &&
Op.hasOneUse()) {
8573 EVT VecVT =
N->getValueType(0);
8576 DCI.AddToWorklist(Op0.
getNode());
8580 DCI.AddToWorklist(Op1.
getNode());
8583 DCI.AddToWorklist(Op0.
getNode());
8585 DCI.AddToWorklist(Op1.
getNode());
8593SDValue SystemZTargetLowering::combineSETCC(
8594 SDNode *
N, DAGCombinerInfo &DCI)
const {
8595 SelectionDAG &DAG = DCI.DAG;
8601 EVT VT =
N->getValueType(0);
8611 Src.getValueType().isFixedLengthVector() &&
8612 Src.getValueType().getScalarType() == MVT::i1) {
8613 EVT CmpVT = Src.getOperand(0).getValueType();
8633 case SystemZISD::IPM:
8638 case SystemZISD::SELECT_CCMASK: {
8640 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8641 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8644 return std::make_pair(OpCC, OpCCValid);
8649 int CCValidVal = CCValid->getZExtValue();
8650 return std::make_pair(Op4CCReg, CCValidVal);
8661 return std::make_pair(Op0CC, Op0CCValid);
8677 return {Val, Val, Val, Val};
8678 case SystemZISD::IPM: {
8683 for (
auto CC : {0, 1, 2, 3})
8686 return ShiftedCCVals;
8688 case SystemZISD::SELECT_CCMASK: {
8692 if (!CCValid || !CCMask)
8695 int CCValidVal = CCValid->getZExtValue();
8696 int CCMaskVal = CCMask->getZExtValue();
8706 if (TrueSDVals.empty() || FalseSDVals.empty())
8709 for (
auto &CCVal : {0, 1, 2, 3})
8710 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8712 : FalseSDVals[CCVal]);
8713 return MergedSDVals;
8730 if (Op0SDVals.empty() || Op1SDVals.empty())
8733 for (
auto CCVal : {0, 1, 2, 3})
8735 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8736 return BinaryOpSDVals;
8747 auto *CCNode = CCReg.
getNode();
8751 if (CCNode->getOpcode() == SystemZISD::TM) {
8754 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8757 if (!Op0Node || !Op1Node)
8759 auto Op0APVal = Op0Node->getAPIntValue();
8760 auto Op1APVal = Op1Node->getAPIntValue();
8761 auto Result = Op0APVal & Op1APVal;
8762 bool AllOnes = Result == Op1APVal;
8763 bool AllZeros = Result == 0;
8764 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits()] != 0;
8765 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8769 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8774 if (Op0SDVals.empty() || Op1SDVals.empty())
8777 for (
auto CC : {0, 1, 2, 3}) {
8778 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8782 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8784 NewCCMask &= Op0CCValid;
8787 CCValid = Op0CCValid;
8790 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8797 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8801 if (Op0SDVals.empty() || Op1SDVals.empty())
8805 auto CmpTypeVal = CmpType->getZExtValue();
8806 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8810 if (!Op0Node || !Op1Node)
8812 auto Op0APVal = Op0Node->getAPIntValue();
8813 auto Op1APVal = Op1Node->getAPIntValue();
8815 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8816 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8819 for (
auto CC : {0, 1, 2, 3}) {
8820 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8824 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8826 NewCCMask &= Op0CCValid;
8829 CCValid = Op0CCValid;
8840 const Value *Rhs)
const {
8841 const auto isFlagOutOpCC = [](
const Value *V) {
8843 const Value *RHSVal;
8850 if (CB->isInlineAsm()) {
8852 return IA && IA->getConstraintString().contains(
"{@cc}");
8863 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
8866 return {-1, -1, -1};
8870 DAGCombinerInfo &DCI)
const {
8876 if (!CCValid || !CCMask)
8879 int CCValidVal = CCValid->getZExtValue();
8880 int CCMaskVal = CCMask->getZExtValue();
8887 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
8888 CCMaskVal != CCValidVal)
8889 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
8893 N->getOperand(3), CCReg);
8897SDValue SystemZTargetLowering::combineSELECT_CCMASK(
8898 SDNode *
N, DAGCombinerInfo &DCI)
const {
8904 if (!CCValid || !CCMask)
8907 int CCValidVal = CCValid->getZExtValue();
8908 int CCMaskVal = CCMask->getZExtValue();
8911 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
8915 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
8916 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
8918 if (Val.getOperand(4) != CCReg)
8925 int CCMaskVal = CCMask->getZExtValue();
8926 for (
auto &CC : {0, 1, 2, 3})
8927 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
8941 if (TrueSDVals.empty())
8942 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
8943 if (FalseSDVals.empty())
8944 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
8945 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
8946 SmallSet<SDValue, 4> MergedSDValsSet;
8948 for (
auto CC : {0, 1, 2, 3}) {
8949 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
8950 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
8954 if (MergedSDValsSet.
size() == 1)
8955 return *MergedSDValsSet.
begin();
8956 if (MergedSDValsSet.
size() == 2) {
8957 auto BeginIt = MergedSDValsSet.
begin();
8958 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
8959 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
8962 for (
auto CC : {0, 1, 2, 3}) {
8964 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
8965 ? (TrueSDVals[CC] == NewTrueVal)
8966 : (FalseSDVals[CC] == NewTrueVal);
8968 CCMaskVal = NewCCMask;
8969 CCMaskVal &= CCValidVal;
8972 IsCombinedCCReg =
true;
8980 if (CCMaskVal == CCValidVal)
8983 if (IsCombinedCCReg)
8985 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
8992SDValue SystemZTargetLowering::combineGET_CCMASK(
8993 SDNode *
N, DAGCombinerInfo &DCI)
const {
8998 if (!CCValid || !CCMask)
9000 int CCValidVal = CCValid->getZExtValue();
9001 int CCMaskVal = CCMask->getZExtValue();
9006 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9011 if (!SelectCCValid || !SelectCCMask)
9013 int SelectCCValidVal = SelectCCValid->getZExtValue();
9014 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9018 if (!TrueVal || !FalseVal)
9022 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9023 SelectCCMaskVal ^= SelectCCValidVal;
9027 if (SelectCCValidVal & ~CCValidVal)
9029 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9032 return Select->getOperand(4);
9035SDValue SystemZTargetLowering::combineIntDIVREM(
9036 SDNode *
N, DAGCombinerInfo &DCI)
const {
9037 SelectionDAG &DAG = DCI.DAG;
9038 EVT VT =
N->getValueType(0);
9055SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9056 SDNode *
N, DAGCombinerInfo &DCI)
const {
9057 SelectionDAG &DAG = DCI.DAG;
9061 "SRL or SRA node is required here!");
9063 if (!Subtarget.hasVector())
9073 SDValue ShiftOperand =
N->getOperand(0);
9093 if (!IsSignExt && !IsZeroExt)
9101 unsigned ActiveBits = IsSignExt
9102 ?
Constant->getAPIntValue().getSignificantBits()
9103 :
Constant->getAPIntValue().getActiveBits();
9104 if (ActiveBits > NarrowVTSize)
9120 unsigned ActiveBits = IsSignExt
9121 ?
Constant->getAPIntValue().getSignificantBits()
9122 :
Constant->getAPIntValue().getActiveBits();
9123 if (ActiveBits > NarrowVTSize)
9140 "Cannot have a multiply node with two different operand types.");
9142 "Cannot have an add node with two different operand types.");
9153 if (ShiftAmt != NarrowVTSize)
9157 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9158 NarrowVT == MVT::v4i32 ||
9159 (Subtarget.hasVectorEnhancements3() &&
9160 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9166 MulhRightOp, MulhAddOp);
9167 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9178 EVT VT =
Op.getValueType();
9187 Op =
Op.getOperand(0);
9188 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9192 bool CanUseEven =
true, CanUseOdd =
true;
9193 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9194 if (ShuffleMask[Elt] == -1)
9196 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9198 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9201 Op =
Op.getOperand(0);
9203 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9205 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9211 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9215 Op =
Op.getOperand(0);
9217 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9219 unsigned Elem =
Op.getConstantOperandVal(1);
9220 Op =
Op.getOperand(0);
9222 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9224 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9231SDValue SystemZTargetLowering::combineMUL(
9232 SDNode *
N, DAGCombinerInfo &DCI)
const {
9233 SelectionDAG &DAG = DCI.DAG;
9240 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9241 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9246SDValue SystemZTargetLowering::combineINTRINSIC(
9247 SDNode *
N, DAGCombinerInfo &DCI)
const {
9248 SelectionDAG &DAG = DCI.DAG;
9250 unsigned Id =
N->getConstantOperandVal(1);
9254 case Intrinsic::s390_vll:
9255 case Intrinsic::s390_vlrl:
9257 if (
C->getZExtValue() >= 15)
9258 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9259 N->getOperand(3), MachinePointerInfo());
9262 case Intrinsic::s390_vstl:
9263 case Intrinsic::s390_vstrl:
9265 if (
C->getZExtValue() >= 15)
9266 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9267 N->getOperand(4), MachinePointerInfo());
9275 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9282 switch(
N->getOpcode()) {
9287 case SystemZISD::MERGE_HIGH:
9288 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9293 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9303 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9304 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9307 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9308 case ISD::MUL:
return combineMUL(
N, DCI);
9312 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9324 EVT VT =
Op.getValueType();
9327 unsigned Opcode =
Op.getOpcode();
9329 unsigned Id =
Op.getConstantOperandVal(0);
9331 case Intrinsic::s390_vpksh:
9332 case Intrinsic::s390_vpksf:
9333 case Intrinsic::s390_vpksg:
9334 case Intrinsic::s390_vpkshs:
9335 case Intrinsic::s390_vpksfs:
9336 case Intrinsic::s390_vpksgs:
9337 case Intrinsic::s390_vpklsh:
9338 case Intrinsic::s390_vpklsf:
9339 case Intrinsic::s390_vpklsg:
9340 case Intrinsic::s390_vpklshs:
9341 case Intrinsic::s390_vpklsfs:
9342 case Intrinsic::s390_vpklsgs:
9344 SrcDemE = DemandedElts;
9347 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9350 case Intrinsic::s390_vuphb:
9351 case Intrinsic::s390_vuphh:
9352 case Intrinsic::s390_vuphf:
9353 case Intrinsic::s390_vuplhb:
9354 case Intrinsic::s390_vuplhh:
9355 case Intrinsic::s390_vuplhf:
9356 SrcDemE =
APInt(NumElts * 2, 0);
9359 case Intrinsic::s390_vuplb:
9360 case Intrinsic::s390_vuplhw:
9361 case Intrinsic::s390_vuplf:
9362 case Intrinsic::s390_vupllb:
9363 case Intrinsic::s390_vupllh:
9364 case Intrinsic::s390_vupllf:
9365 SrcDemE =
APInt(NumElts * 2, 0);
9368 case Intrinsic::s390_vpdi: {
9370 SrcDemE =
APInt(NumElts, 0);
9371 if (!DemandedElts[OpNo - 1])
9373 unsigned Mask =
Op.getConstantOperandVal(3);
9374 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9376 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9379 case Intrinsic::s390_vsldb: {
9381 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9382 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9383 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9384 unsigned NumSrc0Els = 16 - FirstIdx;
9385 SrcDemE =
APInt(NumElts, 0);
9387 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9390 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9395 case Intrinsic::s390_vperm:
9404 case SystemZISD::JOIN_DWORDS:
9406 SrcDemE =
APInt(1, 1);
9408 case SystemZISD::SELECT_CCMASK:
9409 SrcDemE = DemandedElts;
9420 const APInt &DemandedElts,
9435 const APInt &DemandedElts,
9437 unsigned Depth)
const {
9441 unsigned Tmp0, Tmp1;
9446 EVT VT =
Op.getValueType();
9447 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9450 "KnownBits does not match VT in bitwidth");
9453 "DemandedElts does not match VT number of elements");
9455 unsigned Opcode =
Op.getOpcode();
9457 bool IsLogical =
false;
9458 unsigned Id =
Op.getConstantOperandVal(0);
9460 case Intrinsic::s390_vpksh:
9461 case Intrinsic::s390_vpksf:
9462 case Intrinsic::s390_vpksg:
9463 case Intrinsic::s390_vpkshs:
9464 case Intrinsic::s390_vpksfs:
9465 case Intrinsic::s390_vpksgs:
9466 case Intrinsic::s390_vpklsh:
9467 case Intrinsic::s390_vpklsf:
9468 case Intrinsic::s390_vpklsg:
9469 case Intrinsic::s390_vpklshs:
9470 case Intrinsic::s390_vpklsfs:
9471 case Intrinsic::s390_vpklsgs:
9472 case Intrinsic::s390_vpdi:
9473 case Intrinsic::s390_vsldb:
9474 case Intrinsic::s390_vperm:
9477 case Intrinsic::s390_vuplhb:
9478 case Intrinsic::s390_vuplhh:
9479 case Intrinsic::s390_vuplhf:
9480 case Intrinsic::s390_vupllb:
9481 case Intrinsic::s390_vupllh:
9482 case Intrinsic::s390_vupllf:
9485 case Intrinsic::s390_vuphb:
9486 case Intrinsic::s390_vuphh:
9487 case Intrinsic::s390_vuphf:
9488 case Intrinsic::s390_vuplb:
9489 case Intrinsic::s390_vuplhw:
9490 case Intrinsic::s390_vuplf: {
9505 case SystemZISD::JOIN_DWORDS:
9506 case SystemZISD::SELECT_CCMASK:
9509 case SystemZISD::REPLICATE: {
9532 if (
LHS == 1)
return 1;
9535 if (
RHS == 1)
return 1;
9536 unsigned Common = std::min(
LHS,
RHS);
9537 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9538 EVT VT =
Op.getValueType();
9540 if (SrcBitWidth > VTBits) {
9541 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9542 if (Common > SrcExtraBits)
9543 return (Common - SrcExtraBits);
9546 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9553 unsigned Depth)
const {
9554 if (
Op.getResNo() != 0)
9556 unsigned Opcode =
Op.getOpcode();
9558 unsigned Id =
Op.getConstantOperandVal(0);
9560 case Intrinsic::s390_vpksh:
9561 case Intrinsic::s390_vpksf:
9562 case Intrinsic::s390_vpksg:
9563 case Intrinsic::s390_vpkshs:
9564 case Intrinsic::s390_vpksfs:
9565 case Intrinsic::s390_vpksgs:
9566 case Intrinsic::s390_vpklsh:
9567 case Intrinsic::s390_vpklsf:
9568 case Intrinsic::s390_vpklsg:
9569 case Intrinsic::s390_vpklshs:
9570 case Intrinsic::s390_vpklsfs:
9571 case Intrinsic::s390_vpklsgs:
9572 case Intrinsic::s390_vpdi:
9573 case Intrinsic::s390_vsldb:
9574 case Intrinsic::s390_vperm:
9576 case Intrinsic::s390_vuphb:
9577 case Intrinsic::s390_vuphh:
9578 case Intrinsic::s390_vuphf:
9579 case Intrinsic::s390_vuplb:
9580 case Intrinsic::s390_vuplhw:
9581 case Intrinsic::s390_vuplf: {
9585 EVT VT =
Op.getValueType();
9595 case SystemZISD::SELECT_CCMASK:
9609 switch (
Op->getOpcode()) {
9610 case SystemZISD::PCREL_WRAPPER:
9611 case SystemZISD::PCREL_OFFSET:
9622 "Unexpected stack alignment");
9625 unsigned StackProbeSize =
9628 StackProbeSize &= ~(StackAlign - 1);
9629 return StackProbeSize ? StackProbeSize : StackAlign;
9646 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9652 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9668 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9670 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9676 if (miI ==
MBB->end()) {
9678 if (Succ->isLiveIn(SystemZ::CC))
9689 switch (
MI.getOpcode()) {
9690 case SystemZ::Select32:
9691 case SystemZ::Select64:
9692 case SystemZ::Select128:
9693 case SystemZ::SelectF32:
9694 case SystemZ::SelectF64:
9695 case SystemZ::SelectF128:
9696 case SystemZ::SelectVR32:
9697 case SystemZ::SelectVR64:
9698 case SystemZ::SelectVR128:
9730 for (
auto *
MI : Selects) {
9731 Register DestReg =
MI->getOperand(0).getReg();
9732 Register TrueReg =
MI->getOperand(1).getReg();
9733 Register FalseReg =
MI->getOperand(2).getReg();
9738 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9741 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9742 TrueReg = It->second.first;
9744 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9745 FalseReg = It->second.second;
9748 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9753 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9764 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9765 assert(TFL->hasReservedCallFrame(MF) &&
9766 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9771 uint32_t NumBytes =
MI.getOperand(0).getImm();
9776 MI.eraseFromParent();
9785 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9787 unsigned CCValid =
MI.getOperand(3).getImm();
9788 unsigned CCMask =
MI.getOperand(4).getImm();
9793 SmallVector<MachineInstr*, 8> Selects;
9794 SmallVector<MachineInstr*, 8> DbgValues;
9800 assert(NextMI.getOperand(3).getImm() == CCValid &&
9801 "Bad CCValid operands since CC was not redefined.");
9802 if (NextMI.getOperand(4).getImm() == CCMask ||
9803 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9809 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9810 NextMI.usesCustomInsertionHook())
9813 for (
auto *SelMI : Selects)
9814 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9818 if (NextMI.isDebugInstr()) {
9820 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9823 }
else if (User || ++
Count > 20)
9827 MachineInstr *LastMI = Selects.back();
9828 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9830 MachineBasicBlock *StartMBB =
MBB;
9860 for (
auto *SelMI : Selects)
9861 SelMI->eraseFromParent();
9864 for (
auto *DbgMI : DbgValues)
9865 MBB->
splice(InsertPos, StartMBB, DbgMI);
9876 unsigned StoreOpcode,
9877 unsigned STOCOpcode,
9878 bool Invert)
const {
9879 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9882 MachineOperand
Base =
MI.getOperand(1);
9883 int64_t Disp =
MI.getOperand(2).getImm();
9884 Register IndexReg =
MI.getOperand(3).getReg();
9885 unsigned CCValid =
MI.getOperand(4).getImm();
9886 unsigned CCMask =
MI.getOperand(5).getImm();
9889 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
9893 MachineMemOperand *MMO =
nullptr;
9894 for (
auto *
I :
MI.memoperands())
9903 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
9915 MI.eraseFromParent();
9923 MachineBasicBlock *StartMBB =
MBB;
9929 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
9956 MI.eraseFromParent();
9966 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9974 MachineBasicBlock *StartMBB =
MBB;
9992 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10011 Register Temp =
MRI.createVirtualRegister(&SystemZ::VR128BitRegClass);
10019 MI.eraseFromParent();
10030 bool Invert)
const {
10032 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10039 int64_t Disp =
MI.getOperand(2).getImm();
10041 Register BitShift =
MI.getOperand(4).getReg();
10042 Register NegBitShift =
MI.getOperand(5).getReg();
10043 unsigned BitSize =
MI.getOperand(6).getImm();
10047 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10048 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10049 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10052 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10053 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10054 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10055 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10056 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10059 MachineBasicBlock *StartMBB =
MBB;
10087 Register Tmp =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10092 }
else if (BinOpcode)
10115 MI.eraseFromParent();
10126 unsigned KeepOldMask)
const {
10128 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10134 int64_t Disp =
MI.getOperand(2).getImm();
10136 Register BitShift =
MI.getOperand(4).getReg();
10137 Register NegBitShift =
MI.getOperand(5).getReg();
10138 unsigned BitSize =
MI.getOperand(6).getImm();
10142 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10143 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10144 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10147 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10148 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10149 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10150 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10151 Register RotatedAltVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10152 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10155 MachineBasicBlock *StartMBB =
MBB;
10219 MI.eraseFromParent();
10229 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10235 int64_t Disp =
MI.getOperand(2).getImm();
10236 Register CmpVal =
MI.getOperand(3).getReg();
10237 Register OrigSwapVal =
MI.getOperand(4).getReg();
10238 Register BitShift =
MI.getOperand(5).getReg();
10239 Register NegBitShift =
MI.getOperand(6).getReg();
10240 int64_t BitSize =
MI.getOperand(7).getImm();
10243 const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass;
10246 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10247 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10248 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10249 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10252 Register OrigOldVal =
MRI.createVirtualRegister(RC);
10254 Register SwapVal =
MRI.createVirtualRegister(RC);
10255 Register StoreVal =
MRI.createVirtualRegister(RC);
10256 Register OldValRot =
MRI.createVirtualRegister(RC);
10257 Register RetryOldVal =
MRI.createVirtualRegister(RC);
10258 Register RetrySwapVal =
MRI.createVirtualRegister(RC);
10261 MachineBasicBlock *StartMBB =
MBB;
10333 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10336 MI.eraseFromParent();
10344 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10349 .
add(
MI.getOperand(1))
10350 .
addImm(SystemZ::subreg_h64)
10351 .
add(
MI.getOperand(2))
10352 .
addImm(SystemZ::subreg_l64);
10353 MI.eraseFromParent();
10362 bool ClearEven)
const {
10364 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10370 Register In128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10374 Register NewIn128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10375 Register Zero64 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10386 MI.eraseFromParent();
10393 unsigned Opcode,
bool IsMemset)
const {
10395 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10400 uint64_t DestDisp =
MI.getOperand(1).getImm();
10405 auto foldDisplIfNeeded = [&](MachineOperand &
Base, uint64_t &Disp) ->
void {
10407 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10408 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10418 SrcDisp =
MI.getOperand(3).getImm();
10420 SrcBase = DestBase;
10421 SrcDisp = DestDisp++;
10422 foldDisplIfNeeded(DestBase, DestDisp);
10425 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10426 bool IsImmForm = LengthMO.
isImm();
10427 bool IsRegForm = !IsImmForm;
10430 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10432 MachineOperand DBase, uint64_t DDisp,
10433 MachineOperand
SBase, uint64_t SDisp,
10434 unsigned Length) ->
void {
10438 if (ByteMO.
isImm())
10453 bool NeedsLoop =
false;
10454 uint64_t ImmLength = 0;
10455 Register LenAdjReg = SystemZ::NoRegister;
10457 ImmLength = LengthMO.
getImm();
10458 ImmLength += IsMemset ? 2 : 1;
10459 if (ImmLength == 0) {
10460 MI.eraseFromParent();
10463 if (Opcode == SystemZ::CLC) {
10464 if (ImmLength > 3 * 256)
10474 }
else if (ImmLength > 6 * 256)
10482 LenAdjReg = LengthMO.
getReg();
10487 MachineBasicBlock *EndMBB =
10488 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10494 MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10496 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10506 auto loadZeroAddress = [&]() -> MachineOperand {
10507 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10511 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10512 DestBase = loadZeroAddress();
10513 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10514 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10516 MachineBasicBlock *StartMBB =
nullptr;
10517 MachineBasicBlock *LoopMBB =
nullptr;
10518 MachineBasicBlock *NextMBB =
nullptr;
10519 MachineBasicBlock *DoneMBB =
nullptr;
10520 MachineBasicBlock *AllDoneMBB =
nullptr;
10524 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10526 const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass;
10527 Register ThisSrcReg =
MRI.createVirtualRegister(RC);
10529 (HaveSingleBase ? ThisSrcReg :
MRI.createVirtualRegister(RC));
10530 Register NextSrcReg =
MRI.createVirtualRegister(RC);
10532 (HaveSingleBase ? NextSrcReg :
MRI.createVirtualRegister(RC));
10533 RC = &SystemZ::GR64BitRegClass;
10534 Register ThisCountReg =
MRI.createVirtualRegister(RC);
10535 Register NextCountReg =
MRI.createVirtualRegister(RC);
10561 MBB = MemsetOneCheckMBB;
10572 MBB = MemsetOneMBB;
10604 if (EndMBB && !ImmLength)
10626 if (!HaveSingleBase)
10633 if (Opcode == SystemZ::MVC)
10660 if (!HaveSingleBase)
10682 Register RemSrcReg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10683 Register RemDestReg = HaveSingleBase ? RemSrcReg
10684 :
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10688 if (!HaveSingleBase)
10696 MachineInstrBuilder EXRL_MIB =
10704 if (Opcode != SystemZ::MVC) {
10714 while (ImmLength > 0) {
10715 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10718 foldDisplIfNeeded(DestBase, DestDisp);
10719 foldDisplIfNeeded(SrcBase, SrcDisp);
10720 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10721 DestDisp += ThisLength;
10722 SrcDisp += ThisLength;
10723 ImmLength -= ThisLength;
10726 if (EndMBB && ImmLength > 0) {
10742 MI.eraseFromParent();
10751 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10755 uint64_t End1Reg =
MI.getOperand(0).getReg();
10756 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10757 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10758 uint64_t CharReg =
MI.getOperand(3).getReg();
10760 const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass;
10761 uint64_t This1Reg =
MRI.createVirtualRegister(RC);
10762 uint64_t This2Reg =
MRI.createVirtualRegister(RC);
10763 uint64_t End2Reg =
MRI.createVirtualRegister(RC);
10765 MachineBasicBlock *StartMBB =
MBB;
10801 MI.eraseFromParent();
10808 bool NoFloat)
const {
10810 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10811 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10814 MI.setDesc(
TII->get(Opcode));
10818 uint64_t Control =
MI.getOperand(2).getImm();
10819 static const unsigned GPRControlBit[16] = {
10820 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10821 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
10823 Control |= GPRControlBit[15];
10824 if (TFI->
hasFP(MF))
10825 Control |= GPRControlBit[11];
10826 MI.getOperand(2).setImm(Control);
10829 for (
int I = 0;
I < 16;
I++) {
10830 if ((Control & GPRControlBit[
I]) == 0) {
10837 if (!NoFloat && (Control & 4) != 0) {
10838 if (Subtarget.hasVector()) {
10856 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10859 Register SrcReg =
MI.getOperand(0).getReg();
10862 const TargetRegisterClass *RC =
MRI->getRegClass(SrcReg);
10863 Register DstReg =
MRI->createVirtualRegister(RC);
10870 MI.eraseFromParent();
10879 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10882 Register DstReg =
MI.getOperand(0).getReg();
10883 Register SizeReg =
MI.getOperand(2).getReg();
10885 MachineBasicBlock *StartMBB =
MBB;
10895 Register PHIReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10896 Register IncReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10961 MI.eraseFromParent();
10965SDValue SystemZTargetLowering::
10968 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
10976 switch (
MI.getOpcode()) {
10977 case SystemZ::ADJCALLSTACKDOWN:
10978 case SystemZ::ADJCALLSTACKUP:
10979 return emitAdjCallStack(
MI,
MBB);
10981 case SystemZ::Select32:
10982 case SystemZ::Select64:
10983 case SystemZ::Select128:
10984 case SystemZ::SelectF32:
10985 case SystemZ::SelectF64:
10986 case SystemZ::SelectF128:
10987 case SystemZ::SelectVR32:
10988 case SystemZ::SelectVR64:
10989 case SystemZ::SelectVR128:
10990 return emitSelect(
MI,
MBB);
10992 case SystemZ::CondStore8Mux:
10993 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
10994 case SystemZ::CondStore8MuxInv:
10995 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
10996 case SystemZ::CondStore16Mux:
10997 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
10998 case SystemZ::CondStore16MuxInv:
10999 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11000 case SystemZ::CondStore32Mux:
11001 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11002 case SystemZ::CondStore32MuxInv:
11003 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11004 case SystemZ::CondStore8:
11005 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11006 case SystemZ::CondStore8Inv:
11007 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11008 case SystemZ::CondStore16:
11009 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11010 case SystemZ::CondStore16Inv:
11011 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11012 case SystemZ::CondStore32:
11013 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11014 case SystemZ::CondStore32Inv:
11015 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11016 case SystemZ::CondStore64:
11017 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11018 case SystemZ::CondStore64Inv:
11019 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11020 case SystemZ::CondStoreF32:
11021 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11022 case SystemZ::CondStoreF32Inv:
11023 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11024 case SystemZ::CondStoreF64:
11025 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11026 case SystemZ::CondStoreF64Inv:
11027 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11029 case SystemZ::SCmp128Hi:
11030 return emitICmp128Hi(
MI,
MBB,
false);
11031 case SystemZ::UCmp128Hi:
11032 return emitICmp128Hi(
MI,
MBB,
true);
11034 case SystemZ::PAIR128:
11035 return emitPair128(
MI,
MBB);
11036 case SystemZ::AEXT128:
11037 return emitExt128(
MI,
MBB,
false);
11038 case SystemZ::ZEXT128:
11039 return emitExt128(
MI,
MBB,
true);
11041 case SystemZ::ATOMIC_SWAPW:
11042 return emitAtomicLoadBinary(
MI,
MBB, 0);
11044 case SystemZ::ATOMIC_LOADW_AR:
11045 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11046 case SystemZ::ATOMIC_LOADW_AFI:
11047 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11049 case SystemZ::ATOMIC_LOADW_SR:
11050 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11052 case SystemZ::ATOMIC_LOADW_NR:
11053 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11054 case SystemZ::ATOMIC_LOADW_NILH:
11055 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11057 case SystemZ::ATOMIC_LOADW_OR:
11058 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11059 case SystemZ::ATOMIC_LOADW_OILH:
11060 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11062 case SystemZ::ATOMIC_LOADW_XR:
11063 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11064 case SystemZ::ATOMIC_LOADW_XILF:
11065 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11067 case SystemZ::ATOMIC_LOADW_NRi:
11068 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11069 case SystemZ::ATOMIC_LOADW_NILHi:
11070 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11072 case SystemZ::ATOMIC_LOADW_MIN:
11074 case SystemZ::ATOMIC_LOADW_MAX:
11076 case SystemZ::ATOMIC_LOADW_UMIN:
11078 case SystemZ::ATOMIC_LOADW_UMAX:
11081 case SystemZ::ATOMIC_CMP_SWAPW:
11082 return emitAtomicCmpSwapW(
MI,
MBB);
11083 case SystemZ::MVCImm:
11084 case SystemZ::MVCReg:
11085 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11086 case SystemZ::NCImm:
11087 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11088 case SystemZ::OCImm:
11089 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11090 case SystemZ::XCImm:
11091 case SystemZ::XCReg:
11092 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11093 case SystemZ::CLCImm:
11094 case SystemZ::CLCReg:
11095 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11096 case SystemZ::MemsetImmImm:
11097 case SystemZ::MemsetImmReg:
11098 case SystemZ::MemsetRegImm:
11099 case SystemZ::MemsetRegReg:
11100 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11101 case SystemZ::CLSTLoop:
11102 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11103 case SystemZ::MVSTLoop:
11104 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11105 case SystemZ::SRSTLoop:
11106 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11107 case SystemZ::TBEGIN:
11108 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11109 case SystemZ::TBEGIN_nofloat:
11110 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11111 case SystemZ::TBEGINC:
11112 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11113 case SystemZ::LTEBRCompare_Pseudo:
11114 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11115 case SystemZ::LTDBRCompare_Pseudo:
11116 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11117 case SystemZ::LTXBRCompare_Pseudo:
11118 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11120 case SystemZ::PROBED_ALLOCA:
11121 return emitProbedAlloca(
MI,
MBB);
11122 case SystemZ::EH_SjLj_SetJmp:
11124 case SystemZ::EH_SjLj_LongJmp:
11127 case TargetOpcode::STACKMAP:
11128 case TargetOpcode::PATCHPOINT:
11139SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11140 if (VT == MVT::Untyped)
11141 return &SystemZ::ADDR128BitRegClass;
11167 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11187 EVT VT =
Op.getValueType();
11188 Op =
Op.getOperand(0);
11189 EVT OpVT =
Op.getValueType();
11191 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11202 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11222 const AttributeList &Attrs =
F->getAttributes();
11223 if (Attrs.hasRetAttrs())
11224 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11225 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11226 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11229 OS << *FT->getParamType(
I);
11231 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11238bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11239 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11240 if (Itr == IsInternalCache.end())
11241 Itr = IsInternalCache
11242 .insert(std::pair<const Function *, bool>(
11245 return Itr->second;
11248void SystemZTargetLowering::
11256 bool IsInternal =
false;
11257 const Function *CalleeFn =
nullptr;
11260 IsInternal = isInternal(CalleeFn);
11261 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11262 errs() <<
"ERROR: Missing extension attribute of passed "
11263 <<
"value in call to function:\n" <<
"Callee: ";
11264 if (CalleeFn !=
nullptr)
11268 errs() <<
"Caller: ";
11274void SystemZTargetLowering::
11282 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11283 errs() <<
"ERROR: Missing extension attribute of returned "
11284 <<
"value from function:\n";
11292bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11294 if (!Subtarget.isTargetELF())
11303 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11304 MVT VT = Outs[i].VT;
11305 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11308 "Unexpected integer argument VT.");
11309 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...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ 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.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ 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...
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ 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.
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ 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.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ 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.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ 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.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ 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) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ 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.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_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.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ 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.
@ TRAP
TRAP - Trapping instruction.
@ 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.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ 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 ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ BRCOND
BRCOND - Conditional branch.
@ 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.
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ 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.