25#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()) {
131 if (Subtarget.hasVector())
158 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
159 I <= MVT::LAST_FP_VALUETYPE;
185 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
186 I <= MVT::LAST_INTEGER_VALUETYPE;
217 if (Subtarget.hasPopulationCount())
243 (!Subtarget.hasFPExtension() && VT == MVT::i32) ?
Promote :
Custom;
264 if (!Subtarget.hasVectorEnhancements3()) {
291 if (Subtarget.hasVectorEnhancements3()) {
334 {MVT::i8, MVT::i16, MVT::i32},
Legal);
336 {MVT::i8, MVT::i16},
Legal);
357 if (Subtarget.hasMiscellaneousExtensions4()) {
364 if (Subtarget.hasMiscellaneousExtensions3()) {
457 if (VT != MVT::v2i64 || Subtarget.hasVectorEnhancements3()) {
462 if (Subtarget.hasVectorEnhancements3() &&
463 VT != MVT::v16i8 && VT != MVT::v8i16) {
473 if (Subtarget.hasVectorEnhancements1())
507 if (Subtarget.hasVector()) {
529 if (Subtarget.hasVectorEnhancements2()) {
555 for (
MVT VT : {MVT::f32, MVT::f64, MVT::f128}) {
569 for (
unsigned I = MVT::FIRST_FP_VALUETYPE;
570 I <= MVT::LAST_FP_VALUETYPE;
578 if (Subtarget.hasFPExtension()) {
606 if (Subtarget.hasFPExtension()) {
622 if (Subtarget.hasVector()) {
673 if (Subtarget.hasVectorEnhancements1()) {
680 if (Subtarget.hasVectorEnhancements1()) {
697 for (
MVT Type : {MVT::f64, MVT::v2f64, MVT::f32, MVT::v4f32, MVT::f128}) {
720 for (
auto VT : { MVT::f32, MVT::f64, MVT::f128,
721 MVT::v4f32, MVT::v2f64 }) {
730 if (!Subtarget.hasVectorEnhancements1()) {
736 if (Subtarget.hasVectorEnhancements1())
746 if (Subtarget.hasVectorEnhancements1()) {
758 if (!Subtarget.hasVector()) {
769 if (Subtarget.isTargetzOS()) {
834 return Subtarget.hasSoftFloat();
839 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
841 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16)) {
842 IntermediateVT = RegisterVT = MVT::v8f16;
843 return NumIntermediates =
847 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
859 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
867 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
894 return Subtarget.hasVectorEnhancements1();
907 if (!Subtarget.hasVector() ||
908 (isFP128 && !Subtarget.hasVectorEnhancements1()))
917 uint64_t Byte = IntBits.lshr(
I * 8).trunc(8).getZExtValue();
924 Opcode = SystemZISD::BYTE_MASK;
930 if (SplatBitSize > 64)
937 OpVals.push_back(((
unsigned) SignedValue));
938 Opcode = SystemZISD::REPLICATE;
945 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start, End)) {
949 OpVals.push_back(Start - (64 - SplatBitSize));
950 OpVals.push_back(End - (64 - SplatBitSize));
951 Opcode = SystemZISD::ROTATE_MASK;
963 uint64_t SplatBitsZ = SplatBits.getZExtValue();
964 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
976 return TryValue(SplatBitsZ | Middle);
985 assert(IntBits.getBitWidth() == 128 &&
"Unsupported APInt.");
991 unsigned HalfSize = Width / 2;
996 if (HighValue != LowValue || 8 > HalfSize)
999 SplatBits = HighValue;
1003 SplatBitSize = Width;
1011 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
1015 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
1020 bool ForCodeSize)
const {
1022 if (Imm.isZero() || Imm.isNegZero())
1043 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1049 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1102 const int64_t FPOffset = 0;
1123 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1124 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1127 .
addReg(SpecialRegs->getFramePointerRegister())
1135 .
addReg(SpecialRegs->getStackPointerRegister())
1146 .
addReg(SpecialRegs->getStackPointerRegister())
1147 .
addImm(TFL->getBackchainOffset(*MF))
1158 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1162 MIB.
addRegMask(RegInfo->getNoPreservedMask());
1183 MI.eraseFromParent();
1199 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1202 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1209 const int64_t FPOffset = 0;
1221 SpecialRegs->getFramePointerRegister())
1243 SpecialRegs->getStackPointerRegister())
1252 .
addReg(SpecialRegs->getStackPointerRegister())
1253 .
addImm(TFL->getBackchainOffset(*MF))
1259 MI.eraseFromParent();
1290 if (Subtarget.hasInterlockedAccess1() &&
1323 EVT VT =
Y.getValueType();
1326 if (VT == MVT::i32 || VT == MVT::i64)
1327 return Subtarget.hasMiscellaneousExtensions3();
1330 if (VT.
isVector() || VT == MVT::i128)
1331 return Subtarget.hasVector();
1359 bool MVC = Ty->isIntegerTy(8);
1365static AddressingMode
1368 switch (
II->getIntrinsicID()) {
1370 case Intrinsic::memset:
1371 case Intrinsic::memmove:
1372 case Intrinsic::memcpy:
1379 if (SingleUser->getParent() ==
I->getParent()) {
1382 if (
C->getBitWidth() <= 64 &&
1392 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1406 I->getOperand(0)->getType());
1408 bool IsVectorAccess = MemAccessTy->isVectorTy();
1413 Value *DataOp =
I->getOperand(0);
1415 IsVectorAccess =
true;
1421 User *LoadUser = *
I->user_begin();
1423 IsVectorAccess =
true;
1426 if (IsFPAccess || IsVectorAccess)
1445 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1455 return AM.
Scale == 0;
1462 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1463 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1464 const AttributeList &FuncAttributes,
EVT *LargestVT)
const {
1467 "Expected EmitTargetCodeForMemXXX() to handle AlwaysInline cases.");
1469 if (
Op.isZeroMemset())
1472 const int MVCFastLen = 16;
1474 if ((
Op.isMemset() ?
Op.size() - 1 :
Op.size()) <= MVCFastLen)
1478 if (!
Op.isAligned(
Align(8)) || (
Op.size() >= 25 &&
Op.size() <= 31))
1482 Context, MemOps, Limit,
Op, DstAS, SrcAS, FuncAttributes, LargestVT);
1487 const AttributeList &FuncAttributes)
const {
1488 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1492 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1494 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1496 return FromBits > ToBits;
1504 return FromBits > ToBits;
1513 if (Constraint.
size() == 1) {
1514 switch (Constraint[0]) {
1540 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1541 switch (Constraint[1]) {
1552 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1562 Value *CallOperandVal = Info.CallOperandVal;
1565 if (!CallOperandVal)
1569 switch (*Constraint) {
1588 if (Subtarget.hasVector())
1619 if (
C->getZExtValue() == 0x7fffffff)
1629static std::pair<unsigned, const TargetRegisterClass *>
1631 const unsigned *Map,
unsigned Size) {
1632 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1633 if (isdigit(Constraint[2])) {
1638 return std::make_pair(Map[Index], RC);
1640 return std::make_pair(0U,
nullptr);
1643std::pair<unsigned, const TargetRegisterClass *>
1646 if (Constraint.
size() == 1) {
1648 switch (Constraint[0]) {
1653 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1655 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1656 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1660 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1661 else if (VT == MVT::i128)
1662 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1663 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1666 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1671 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1673 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1675 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1676 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1681 if (Subtarget.hasVector()) {
1683 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1685 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1687 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1688 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1697 auto getVTSizeInBits = [&VT]() {
1705 if (Constraint[1] ==
'r') {
1706 if (getVTSizeInBits() == 32)
1709 if (getVTSizeInBits() == 128)
1715 if (Constraint[1] ==
'f') {
1717 return std::make_pair(
1719 if (getVTSizeInBits() == 16)
1722 if (getVTSizeInBits() == 32)
1725 if (getVTSizeInBits() == 128)
1731 if (Constraint[1] ==
'v') {
1732 if (!Subtarget.hasVector())
1733 return std::make_pair(
1735 if (getVTSizeInBits() == 16)
1738 if (getVTSizeInBits() == 32)
1741 if (getVTSizeInBits() == 64)
1747 if (Constraint[1] ==
'@') {
1748 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1749 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1762 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1763 : SystemZ::NoRegister)
1765 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1772 const Constant *PersonalityFn)
const {
1773 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1777 const Constant *PersonalityFn)
const {
1778 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1793 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1797 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1798 OpInfo.ConstraintVT.getSizeInBits() < 8)
1813 if (Constraint.
size() == 1) {
1814 switch (Constraint[0]) {
1819 Op.getValueType()));
1826 Op.getValueType()));
1833 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1840 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1845 if (
C->getZExtValue() == 0x7fffffff)
1847 Op.getValueType()));
1858#include "SystemZGenCallingConv.inc"
1862 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1868 Type *ToType)
const {
1931 if (BitCastToType == MVT::v2i64)
1958 MVT::Untyped,
Hi,
Lo);
1982 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
1984 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1995 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
1996 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2007template <
class ArgTy>
2010 MVT &PartVT,
unsigned &NumParts) {
2011 if (!Args[
I].Flags.isSplit())
2015 PartVT = ArgLocs[
I].getValVT();
2017 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
2018 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
2019 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
2021 if (Args[PartIdx].Flags.isSplitEnd())
2045 unsigned NumFixedGPRs = 0;
2046 unsigned NumFixedFPRs = 0;
2047 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2060 RC = &SystemZ::GR32BitRegClass;
2064 RC = &SystemZ::GR64BitRegClass;
2068 RC = &SystemZ::FP16BitRegClass;
2072 RC = &SystemZ::FP32BitRegClass;
2076 RC = &SystemZ::FP64BitRegClass;
2080 RC = &SystemZ::FP128BitRegClass;
2089 RC = &SystemZ::VR128BitRegClass;
2103 if (Subtarget.isTargetXPLINK64()) {
2106 ArgSPOffset += XPRegs.getCallFrameSize();
2117 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2121 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2135 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2138 unsigned PartOffset = Ins[
I].PartOffset;
2143 assert(PartOffset &&
"Offset should be non-zero.");
2150 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2156 Subtarget.getSpecialRegisters());
2162 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2167 if (IsVarArg && Subtarget.isTargetELF()) {
2180 int64_t RegSaveOffset =
2195 &SystemZ::FP64BitRegClass);
2207 if (Subtarget.isTargetXPLINK64()) {
2212 Subtarget.getSpecialRegisters());
2213 MRI.
addLiveIn(Regs->getADARegister(), ADAvReg);
2225 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2232 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2234 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2241 unsigned Offset,
bool LoadAdr =
false) {
2264 bool LoadAddr =
false;
2286 unsigned ADADelta = 0;
2287 unsigned EPADelta = 8;
2293 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2294 G->getGlobal()->hasPrivateLinkage());
2301 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2347 if (Subtarget.isTargetXPLINK64())
2351 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2355 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2374 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2382 unsigned NumParts = 1;
2386 SlotVT = Outs[
I].VT;
2393 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot, StackPtrInfo));
2396 assert(Outs[
I].PartOffset == 0);
2397 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2400 unsigned PartOffset = Outs[
I].PartOffset;
2406 assert(PartOffset &&
"Offset should be non-zero.");
2408 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2410 ArgValue = SpillSlot;
2427 if (!StackPtr.getNode())
2434 else if (VA.
getLocVT() == MVT::f16)
2447 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2451 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2457 if (!MemOpChains.
empty())
2465 if (Subtarget.isTargetXPLINK64()) {
2470 ->getAddressOfCalleeRegister();
2473 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2480 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2483 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2484 }
else if (IsTailCall) {
2487 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2492 for (
const auto &[Reg,
N] : RegsToPass) {
2499 Ops.push_back(Chain);
2500 Ops.push_back(Callee);
2504 for (
const auto &[Reg,
N] : RegsToPass)
2509 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2510 assert(Mask &&
"Missing call preserved mask for calling convention");
2515 Ops.push_back(Glue);
2524 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2534 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2541 VA.getLocVT(), Glue);
2558 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2560 Args.reserve(
Ops.size());
2566 Entry.IsZExt = !Entry.IsSExt;
2567 Args.push_back(Entry);
2578 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2589 const Type *RetTy)
const {
2592 for (
auto &Out : Outs)
2593 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2597 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2598 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2610 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2618 if (RetLocs.
empty())
2619 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2628 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2650 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2657 unsigned &CCValid) {
2658 unsigned Id =
Op.getConstantOperandVal(1);
2660 case Intrinsic::s390_tbegin:
2661 Opcode = SystemZISD::TBEGIN;
2665 case Intrinsic::s390_tbegin_nofloat:
2666 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2670 case Intrinsic::s390_tend:
2671 Opcode = SystemZISD::TEND;
2684 unsigned Id =
Op.getConstantOperandVal(0);
2686 case Intrinsic::s390_vpkshs:
2687 case Intrinsic::s390_vpksfs:
2688 case Intrinsic::s390_vpksgs:
2689 Opcode = SystemZISD::PACKS_CC;
2693 case Intrinsic::s390_vpklshs:
2694 case Intrinsic::s390_vpklsfs:
2695 case Intrinsic::s390_vpklsgs:
2696 Opcode = SystemZISD::PACKLS_CC;
2700 case Intrinsic::s390_vceqbs:
2701 case Intrinsic::s390_vceqhs:
2702 case Intrinsic::s390_vceqfs:
2703 case Intrinsic::s390_vceqgs:
2704 case Intrinsic::s390_vceqqs:
2705 Opcode = SystemZISD::VICMPES;
2709 case Intrinsic::s390_vchbs:
2710 case Intrinsic::s390_vchhs:
2711 case Intrinsic::s390_vchfs:
2712 case Intrinsic::s390_vchgs:
2713 case Intrinsic::s390_vchqs:
2714 Opcode = SystemZISD::VICMPHS;
2718 case Intrinsic::s390_vchlbs:
2719 case Intrinsic::s390_vchlhs:
2720 case Intrinsic::s390_vchlfs:
2721 case Intrinsic::s390_vchlgs:
2722 case Intrinsic::s390_vchlqs:
2723 Opcode = SystemZISD::VICMPHLS;
2727 case Intrinsic::s390_vtm:
2728 Opcode = SystemZISD::VTM;
2732 case Intrinsic::s390_vfaebs:
2733 case Intrinsic::s390_vfaehs:
2734 case Intrinsic::s390_vfaefs:
2735 Opcode = SystemZISD::VFAE_CC;
2739 case Intrinsic::s390_vfaezbs:
2740 case Intrinsic::s390_vfaezhs:
2741 case Intrinsic::s390_vfaezfs:
2742 Opcode = SystemZISD::VFAEZ_CC;
2746 case Intrinsic::s390_vfeebs:
2747 case Intrinsic::s390_vfeehs:
2748 case Intrinsic::s390_vfeefs:
2749 Opcode = SystemZISD::VFEE_CC;
2753 case Intrinsic::s390_vfeezbs:
2754 case Intrinsic::s390_vfeezhs:
2755 case Intrinsic::s390_vfeezfs:
2756 Opcode = SystemZISD::VFEEZ_CC;
2760 case Intrinsic::s390_vfenebs:
2761 case Intrinsic::s390_vfenehs:
2762 case Intrinsic::s390_vfenefs:
2763 Opcode = SystemZISD::VFENE_CC;
2767 case Intrinsic::s390_vfenezbs:
2768 case Intrinsic::s390_vfenezhs:
2769 case Intrinsic::s390_vfenezfs:
2770 Opcode = SystemZISD::VFENEZ_CC;
2774 case Intrinsic::s390_vistrbs:
2775 case Intrinsic::s390_vistrhs:
2776 case Intrinsic::s390_vistrfs:
2777 Opcode = SystemZISD::VISTR_CC;
2781 case Intrinsic::s390_vstrcbs:
2782 case Intrinsic::s390_vstrchs:
2783 case Intrinsic::s390_vstrcfs:
2784 Opcode = SystemZISD::VSTRC_CC;
2788 case Intrinsic::s390_vstrczbs:
2789 case Intrinsic::s390_vstrczhs:
2790 case Intrinsic::s390_vstrczfs:
2791 Opcode = SystemZISD::VSTRCZ_CC;
2795 case Intrinsic::s390_vstrsb:
2796 case Intrinsic::s390_vstrsh:
2797 case Intrinsic::s390_vstrsf:
2798 Opcode = SystemZISD::VSTRS_CC;
2802 case Intrinsic::s390_vstrszb:
2803 case Intrinsic::s390_vstrszh:
2804 case Intrinsic::s390_vstrszf:
2805 Opcode = SystemZISD::VSTRSZ_CC;
2809 case Intrinsic::s390_vfcedbs:
2810 case Intrinsic::s390_vfcesbs:
2811 Opcode = SystemZISD::VFCMPES;
2815 case Intrinsic::s390_vfchdbs:
2816 case Intrinsic::s390_vfchsbs:
2817 Opcode = SystemZISD::VFCMPHS;
2821 case Intrinsic::s390_vfchedbs:
2822 case Intrinsic::s390_vfchesbs:
2823 Opcode = SystemZISD::VFCMPHES;
2827 case Intrinsic::s390_vftcidb:
2828 case Intrinsic::s390_vftcisb:
2829 Opcode = SystemZISD::VFTCI;
2833 case Intrinsic::s390_tdc:
2834 Opcode = SystemZISD::TDC;
2847 unsigned NumOps =
Op.getNumOperands();
2850 Ops.push_back(
Op.getOperand(0));
2852 Ops.push_back(
Op.getOperand(
I));
2854 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2868 unsigned NumOps =
Op.getNumOperands();
2874 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2875 "Unhandled intrinsic with f16 operand.");
2878 Ops.push_back(CurrOper);
2892 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2893 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2894 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2920 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2923 int64_t
Value = ConstOp1->getSExtValue();
2939 if (!
C.Op0.hasOneUse() ||
2946 unsigned NumBits = Load->getMemoryVT().getSizeInBits();
2947 if ((NumBits != 8 && NumBits != 16) ||
2948 NumBits != Load->getMemoryVT().getStoreSizeInBits())
2954 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2957 uint64_t Mask = (1 << NumBits) - 1;
2960 int64_t SignedValue = ConstOp1->getSExtValue();
2967 }
else if (NumBits == 8) {
2993 if (
C.Op0.getValueType() != MVT::i32 ||
2994 Load->getExtensionType() != ExtType) {
2996 Load->getBasePtr(), Load->getPointerInfo(),
2997 Load->getMemoryVT(), Load->getAlign(),
2998 Load->getMemOperand()->getFlags());
3004 if (
C.Op1.getValueType() != MVT::i32 ||
3005 Value != ConstOp1->getZExtValue())
3015 if (Load->getMemoryVT() == MVT::i8)
3018 switch (Load->getExtensionType()) {
3036 if (
C.Op0.isMachineOpcode() &&
3037 (
C.Op0.getMachineOpcode() == SystemZ::LOAD_STACK_GUARD))
3041 if (
C.Op0.getValueType() == MVT::i128)
3043 if (
C.Op0.getValueType() == MVT::f128)
3055 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3084 unsigned Opcode0 =
C.Op0.getOpcode();
3091 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3106 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3107 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3129 if (C1 && C1->isZero()) {
3148 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3151 if (C1 && C1->getZExtValue() == 32) {
3152 SDValue ShlOp0 =
C.Op0.getOperand(0);
3171 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3174 C.Op1->getAsZExtVal() == 0) {
3176 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3177 C.Op0.getValueSizeInBits().getFixedValue()) {
3178 unsigned Type = L->getExtensionType();
3181 C.Op0 =
C.Op0.getOperand(0);
3197 if (
C.Opcode != SystemZISD::ICMP)
3207 if (!
C.Op1.isMachineOpcode() ||
3208 C.Op1.getMachineOpcode() != SystemZ::LOAD_STACK_GUARD)
3213 C.Opcode = SystemZISD::CMP_STACKGUARD;
3224 uint64_t Amount = Shift->getZExtValue();
3225 if (Amount >=
N.getValueSizeInBits())
3240 unsigned ICmpType) {
3241 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3263 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3269 if (EffectivelyUnsigned && CmpVal <
Low) {
3277 if (CmpVal == Mask) {
3283 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3289 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3297 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3303 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3332 if (
C.Op0.getValueType() == MVT::i128) {
3338 if (Mask && Mask->getAPIntValue() == 0) {
3339 C.Opcode = SystemZISD::VTM;
3356 uint64_t CmpVal = ConstOp1->getZExtValue();
3363 NewC.Op0 =
C.Op0.getOperand(0);
3364 NewC.Op1 =
C.Op0.getOperand(1);
3368 MaskVal = Mask->getZExtValue();
3388 MaskVal = -(CmpVal & -CmpVal);
3397 unsigned NewCCMask, ShiftVal;
3401 (MaskVal >> ShiftVal != 0) &&
3402 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3404 MaskVal >> ShiftVal,
3408 MaskVal >>= ShiftVal;
3412 (MaskVal << ShiftVal != 0) &&
3413 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3415 MaskVal << ShiftVal,
3419 MaskVal <<= ShiftVal;
3428 C.Opcode = SystemZISD::TM;
3430 if (Mask && Mask->getZExtValue() == MaskVal)
3435 C.CCMask = NewCCMask;
3441 if (
C.Opcode != SystemZISD::ICMP)
3443 if (
C.Op0.getValueType() != MVT::i128)
3454 Src = Src.getOperand(0);
3457 unsigned Opcode = 0;
3458 if (Src.hasOneUse()) {
3459 switch (Src.getOpcode()) {
3460 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3461 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3462 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3463 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3464 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3465 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3471 C.Op0 = Src->getOperand(0);
3472 C.Op1 = Src->getOperand(1);
3476 C.CCMask ^=
C.CCValid;
3488 C.Opcode = SystemZISD::VICMPES;
3500 bool Swap =
false, Invert =
false;
3512 C.Opcode = SystemZISD::UCMP128HI;
3514 C.Opcode = SystemZISD::SCMP128HI;
3519 C.CCMask ^=
C.CCValid;
3530 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3533 if ((~Known.
Zero).getZExtValue() & ~Mask->getZExtValue())
3536 C.Op0 =
C.Op0.getOperand(0);
3548 C.CCValid = CCValid;
3551 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3554 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3558 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3561 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3565 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3568 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3571 C.CCMask &= CCValid;
3579 bool IsSignaling =
false) {
3582 unsigned Opcode, CCValid;
3594 Comparison
C(CmpOp0, CmpOp1, Chain);
3596 if (
C.Op0.getValueType().isFloatingPoint()) {
3599 C.Opcode = SystemZISD::FCMP;
3600 else if (!IsSignaling)
3601 C.Opcode = SystemZISD::STRICT_FCMP;
3603 C.Opcode = SystemZISD::STRICT_FCMPS;
3608 C.Opcode = SystemZISD::ICMP;
3644 if (!
C.Op1.getNode()) {
3645 if (
C.Opcode == SystemZISD::CMP_STACKGUARD)
3646 return DAG.
getNode(SystemZISD::CMP_STACKGUARD,
DL, MVT::i32,
C.Op0);
3648 switch (
C.Op0.getOpcode()) {
3659 if (
C.Opcode == SystemZISD::ICMP)
3660 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3662 if (
C.Opcode == SystemZISD::TM) {
3665 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3668 if (
C.Opcode == SystemZISD::VICMPES ||
3669 C.Opcode == SystemZISD::VICMPHS ||
3670 C.Opcode == SystemZISD::VICMPHLS ||
3671 C.Opcode == SystemZISD::VFCMPES ||
3672 C.Opcode == SystemZISD::VFCMPHS ||
3673 C.Opcode == SystemZISD::VFCMPHES) {
3674 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3681 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3683 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3692 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3693 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3718 unsigned CCValid,
unsigned CCMask) {
3723 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3801 int Mask[] = { Start, -1, Start + 1, -1 };
3805 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3807 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3821 !Subtarget.hasVectorEnhancements1()) {
3827 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3840 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3843 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3844 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3846 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3859 bool IsSignaling)
const {
3862 assert (!IsSignaling || Chain);
3865 bool Invert =
false;
3873 assert(IsFP &&
"Unexpected integer comparison");
3875 DL, VT, CmpOp1, CmpOp0, Chain);
3877 DL, VT, CmpOp0, CmpOp1, Chain);
3881 LT.getValue(1),
GE.getValue(1));
3890 assert(IsFP &&
"Unexpected integer comparison");
3892 DL, VT, CmpOp1, CmpOp0, Chain);
3894 DL, VT, CmpOp0, CmpOp1, Chain);
3898 LT.getValue(1),
GT.getValue(1));
3919 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3923 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3928 Chain =
Cmp.getValue(1);
3936 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3949 EVT VT =
Op.getValueType();
3951 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3960 bool IsSignaling)
const {
3966 EVT VT =
Op.getNode()->getValueType(0);
3968 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3969 Chain, IsSignaling);
3991 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
4025 C.CCMask ^=
C.CCValid;
4033 Op = SystemZISD::VICMPE;
4037 Op = SystemZISD::VICMPHL;
4039 Op = SystemZISD::VICMPH;
4078 C.Op1->getAsZExtVal() == 0) {
4085 if (Subtarget.hasVectorEnhancements3() &&
4086 C.Opcode == SystemZISD::ICMP &&
4087 C.Op0.getValueType() == MVT::i128 &&
4097 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4103 const GlobalValue *GV =
Node->getGlobal();
4109 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4112 uint64_t Anchor =
Offset & ~uint64_t(0xfff);
4131 }
else if (Subtarget.isTargetELF()) {
4136 }
else if (Subtarget.isTargetzOS()) {
4167 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4172 Ops.push_back(Chain);
4174 Node->getValueType(0),
4183 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4184 const uint32_t *
Mask =
4186 assert(Mask &&
"Missing call preserved mask for calling convention");
4190 Ops.push_back(Glue);
4193 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4201SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4225 const GlobalValue *GV =
Node->getGlobal();
4233 SDValue TP = lowerThreadPointer(
DL, DAG);
4240 SystemZConstantPoolValue *CPV =
4249 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4255 SystemZConstantPoolValue *CPV =
4264 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4269 SystemZMachineFunctionInfo* MFI =
4298 SystemZConstantPoolValue *CPV =
4332 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4349 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4354 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4356 MachineFrameInfo &MFI = MF.getFrameInfo();
4360 unsigned Depth =
Op.getConstantOperandVal(0);
4367 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4372 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4378 MachinePointerInfo());
4393 unsigned Depth =
Op.getConstantOperandVal(0);
4398 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4401 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4402 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4403 int Offset = TFL->getReturnAddressOffset(MF);
4407 MachinePointerInfo());
4412 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4414 &SystemZ::GR64BitRegClass);
4422 EVT InVT =
In.getValueType();
4423 EVT ResVT =
Op.getValueType();
4431 LoadN->getBasePtr(), LoadN->getMemOperand());
4437 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4439 if (Subtarget.hasHighWord()) {
4443 MVT::i64,
SDValue(U64, 0), In);
4451 DL, MVT::f32, Out64);
4453 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4456 MVT::f64,
SDValue(U64, 0), In);
4458 if (Subtarget.hasHighWord())
4471 if (Subtarget.isTargetXPLINK64())
4472 return lowerVASTART_XPLINK(
Op, DAG);
4474 return lowerVASTART_ELF(
Op, DAG);
4480 SystemZMachineFunctionInfo *FuncInfo =
4481 MF.
getInfo<SystemZMachineFunctionInfo>();
4491 MachinePointerInfo(SV));
4497 SystemZMachineFunctionInfo *FuncInfo =
4498 MF.
getInfo<SystemZMachineFunctionInfo>();
4507 const unsigned NumFields = 4;
4518 for (
unsigned I = 0;
I < NumFields; ++
I) {
4523 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4524 MachinePointerInfo(SV,
Offset));
4542 Align(8),
false,
false,
4543 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4544 MachinePointerInfo(SrcSV));
4548SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4550 if (Subtarget.isTargetXPLINK64())
4551 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4553 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4557SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4559 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4569 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4572 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4573 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4579 if (ExtraAlignSpace)
4583 bool IsSigned =
false;
4584 bool DoesNotReturn =
false;
4585 bool IsReturnValueUsed =
false;
4586 EVT VT =
Op.getValueType();
4596 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4608 if (ExtraAlignSpace) {
4620SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4622 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4625 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4634 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4637 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4638 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4649 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4650 MachinePointerInfo());
4653 if (ExtraAlignSpace)
4660 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4661 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4677 if (RequiredAlign > StackAlign) {
4687 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4688 MachinePointerInfo());
4694SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4698 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4703 unsigned Opcode)
const {
4704 EVT VT =
Op.getValueType();
4710 assert(Subtarget.hasMiscellaneousExtensions2());
4715 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4721 EVT VT =
Op.getValueType();
4729 else if (Subtarget.hasMiscellaneousExtensions2())
4734 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4769 EVT VT =
Op.getValueType();
4782 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4790 EVT VT =
Op.getValueType();
4810 EVT VT =
Op.getValueType();
4817 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4822 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4834 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4836 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4873 MVT::i64, HighOp, Low32);
4879 SDNode *
N =
Op.getNode();
4884 if (
N->getValueType(0) == MVT::i128) {
4885 unsigned BaseOp = 0;
4886 unsigned FlagOp = 0;
4887 bool IsBorrow =
false;
4888 switch (
Op.getOpcode()) {
4892 FlagOp = SystemZISD::VACC;
4896 FlagOp = SystemZISD::VSCBI;
4911 unsigned BaseOp = 0;
4912 unsigned CCValid = 0;
4913 unsigned CCMask = 0;
4915 switch (
Op.getOpcode()) {
4918 BaseOp = SystemZISD::SADDO;
4923 BaseOp = SystemZISD::SSUBO;
4928 BaseOp = SystemZISD::UADDO;
4933 BaseOp = SystemZISD::USUBO;
4939 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4943 if (
N->getValueType(1) == MVT::i1)
4969 SDNode *
N =
Op.getNode();
4970 MVT VT =
N->getSimpleValueType(0);
4981 if (VT == MVT::i128) {
4982 unsigned BaseOp = 0;
4983 unsigned FlagOp = 0;
4984 bool IsBorrow =
false;
4985 switch (
Op.getOpcode()) {
4988 BaseOp = SystemZISD::VAC;
4989 FlagOp = SystemZISD::VACCC;
4992 BaseOp = SystemZISD::VSBI;
4993 FlagOp = SystemZISD::VSBCBI;
5012 unsigned BaseOp = 0;
5013 unsigned CCValid = 0;
5014 unsigned CCMask = 0;
5016 switch (
Op.getOpcode()) {
5022 BaseOp = SystemZISD::ADDCARRY;
5030 BaseOp = SystemZISD::SUBCARRY;
5041 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
5045 if (
N->getValueType(1) == MVT::i1)
5053 EVT VT =
Op.getValueType();
5055 Op =
Op.getOperand(0);
5078 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5090 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5103 if (NumSignificantBits == 0)
5109 BitSize = std::min(BitSize, OrigBitSize);
5118 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5120 if (BitSize != OrigBitSize)
5157 EVT RegVT =
Op.getValueType();
5159 return lowerATOMIC_LDST_I128(
Op, DAG);
5160 return lowerLoadF16(
Op, DAG);
5166 if (
Node->getMemoryVT().getSizeInBits() == 128)
5167 return lowerATOMIC_LDST_I128(
Op, DAG);
5168 return lowerStoreF16(
Op, DAG);
5175 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5176 "Only custom lowering i128 or f128.");
5189 EVT WideVT = MVT::i32;
5212 unsigned Opcode)
const {
5216 EVT NarrowVT =
Node->getMemoryVT();
5217 EVT WideVT = MVT::i32;
5218 if (NarrowVT == WideVT)
5225 MachineMemOperand *MMO =
Node->getMemOperand();
5229 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5231 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5236 SDValue AlignedAddr, BitShift, NegBitShift;
5244 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5247 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5248 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5253 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5254 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5274 EVT MemVT =
Node->getMemoryVT();
5275 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5277 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5278 assert(Subtarget.hasInterlockedAccess1() &&
5279 "Should have been expanded by AtomicExpand pass.");
5285 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5286 Node->getMemOperand());
5289 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5300 MachineMemOperand *MMO =
Node->getMemOperand();
5303 if (
Node->getMemoryVT() == MVT::i128) {
5312 EVT NarrowVT =
Node->getMemoryVT();
5313 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5314 if (NarrowVT == WideVT) {
5315 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5316 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5318 DL, Tys,
Ops, NarrowVT, MMO);
5332 SDValue AlignedAddr, BitShift, NegBitShift;
5336 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5337 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5340 VTList,
Ops, NarrowVT, MMO);
5354SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5377 auto *Regs = Subtarget.getSpecialRegisters();
5380 "in GHC calling convention");
5382 Regs->getStackPointerRegister(),
Op.getValueType());
5388 auto *Regs = Subtarget.getSpecialRegisters();
5389 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5393 "in GHC calling convention");
5400 if (StoreBackchain) {
5402 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5403 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5404 MachinePointerInfo());
5407 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5410 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5411 MachinePointerInfo());
5418 bool IsData =
Op.getConstantOperandVal(4);
5421 return Op.getOperand(0);
5424 bool IsWrite =
Op.getConstantOperandVal(2);
5431 Node->getMemoryVT(),
Node->getMemOperand());
5435SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5437 unsigned Opcode, CCValid;
5439 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5450SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5452 unsigned Opcode, CCValid;
5455 if (
Op->getNumValues() == 1)
5457 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5462 unsigned Id =
Op.getConstantOperandVal(0);
5464 case Intrinsic::thread_pointer:
5465 return lowerThreadPointer(SDLoc(
Op), DAG);
5467 case Intrinsic::s390_vpdi:
5468 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5469 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5471 case Intrinsic::s390_vperm:
5472 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5473 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5475 case Intrinsic::s390_vuphb:
5476 case Intrinsic::s390_vuphh:
5477 case Intrinsic::s390_vuphf:
5478 case Intrinsic::s390_vuphg:
5479 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5482 case Intrinsic::s390_vuplhb:
5483 case Intrinsic::s390_vuplhh:
5484 case Intrinsic::s390_vuplhf:
5485 case Intrinsic::s390_vuplhg:
5486 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5489 case Intrinsic::s390_vuplb:
5490 case Intrinsic::s390_vuplhw:
5491 case Intrinsic::s390_vuplf:
5492 case Intrinsic::s390_vuplg:
5493 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5496 case Intrinsic::s390_vupllb:
5497 case Intrinsic::s390_vupllh:
5498 case Intrinsic::s390_vupllf:
5499 case Intrinsic::s390_vupllg:
5500 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5503 case Intrinsic::s390_vsumb:
5504 case Intrinsic::s390_vsumh:
5505 case Intrinsic::s390_vsumgh:
5506 case Intrinsic::s390_vsumgf:
5507 case Intrinsic::s390_vsumqf:
5508 case Intrinsic::s390_vsumqg:
5509 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5510 Op.getOperand(1),
Op.getOperand(2));
5512 case Intrinsic::s390_vaq:
5514 Op.getOperand(1),
Op.getOperand(2));
5515 case Intrinsic::s390_vaccb:
5516 case Intrinsic::s390_vacch:
5517 case Intrinsic::s390_vaccf:
5518 case Intrinsic::s390_vaccg:
5519 case Intrinsic::s390_vaccq:
5520 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5521 Op.getOperand(1),
Op.getOperand(2));
5522 case Intrinsic::s390_vacq:
5523 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5524 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5525 case Intrinsic::s390_vacccq:
5526 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5527 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5529 case Intrinsic::s390_vsq:
5531 Op.getOperand(1),
Op.getOperand(2));
5532 case Intrinsic::s390_vscbib:
5533 case Intrinsic::s390_vscbih:
5534 case Intrinsic::s390_vscbif:
5535 case Intrinsic::s390_vscbig:
5536 case Intrinsic::s390_vscbiq:
5537 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5538 Op.getOperand(1),
Op.getOperand(2));
5539 case Intrinsic::s390_vsbiq:
5540 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5541 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5542 case Intrinsic::s390_vsbcbiq:
5543 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5544 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5546 case Intrinsic::s390_vmhb:
5547 case Intrinsic::s390_vmhh:
5548 case Intrinsic::s390_vmhf:
5549 case Intrinsic::s390_vmhg:
5550 case Intrinsic::s390_vmhq:
5552 Op.getOperand(1),
Op.getOperand(2));
5553 case Intrinsic::s390_vmlhb:
5554 case Intrinsic::s390_vmlhh:
5555 case Intrinsic::s390_vmlhf:
5556 case Intrinsic::s390_vmlhg:
5557 case Intrinsic::s390_vmlhq:
5559 Op.getOperand(1),
Op.getOperand(2));
5561 case Intrinsic::s390_vmahb:
5562 case Intrinsic::s390_vmahh:
5563 case Intrinsic::s390_vmahf:
5564 case Intrinsic::s390_vmahg:
5565 case Intrinsic::s390_vmahq:
5566 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5567 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5568 case Intrinsic::s390_vmalhb:
5569 case Intrinsic::s390_vmalhh:
5570 case Intrinsic::s390_vmalhf:
5571 case Intrinsic::s390_vmalhg:
5572 case Intrinsic::s390_vmalhq:
5573 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5574 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5576 case Intrinsic::s390_vmeb:
5577 case Intrinsic::s390_vmeh:
5578 case Intrinsic::s390_vmef:
5579 case Intrinsic::s390_vmeg:
5580 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5581 Op.getOperand(1),
Op.getOperand(2));
5582 case Intrinsic::s390_vmleb:
5583 case Intrinsic::s390_vmleh:
5584 case Intrinsic::s390_vmlef:
5585 case Intrinsic::s390_vmleg:
5586 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5587 Op.getOperand(1),
Op.getOperand(2));
5588 case Intrinsic::s390_vmob:
5589 case Intrinsic::s390_vmoh:
5590 case Intrinsic::s390_vmof:
5591 case Intrinsic::s390_vmog:
5592 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5593 Op.getOperand(1),
Op.getOperand(2));
5594 case Intrinsic::s390_vmlob:
5595 case Intrinsic::s390_vmloh:
5596 case Intrinsic::s390_vmlof:
5597 case Intrinsic::s390_vmlog:
5598 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5599 Op.getOperand(1),
Op.getOperand(2));
5601 case Intrinsic::s390_vmaeb:
5602 case Intrinsic::s390_vmaeh:
5603 case Intrinsic::s390_vmaef:
5604 case Intrinsic::s390_vmaeg:
5606 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5607 Op.getOperand(1),
Op.getOperand(2)),
5609 case Intrinsic::s390_vmaleb:
5610 case Intrinsic::s390_vmaleh:
5611 case Intrinsic::s390_vmalef:
5612 case Intrinsic::s390_vmaleg:
5614 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5615 Op.getOperand(1),
Op.getOperand(2)),
5617 case Intrinsic::s390_vmaob:
5618 case Intrinsic::s390_vmaoh:
5619 case Intrinsic::s390_vmaof:
5620 case Intrinsic::s390_vmaog:
5622 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5623 Op.getOperand(1),
Op.getOperand(2)),
5625 case Intrinsic::s390_vmalob:
5626 case Intrinsic::s390_vmaloh:
5627 case Intrinsic::s390_vmalof:
5628 case Intrinsic::s390_vmalog:
5630 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5631 Op.getOperand(1),
Op.getOperand(2)),
5652 { SystemZISD::MERGE_HIGH, 8,
5653 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5655 { SystemZISD::MERGE_HIGH, 4,
5656 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5658 { SystemZISD::MERGE_HIGH, 2,
5659 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5661 { SystemZISD::MERGE_HIGH, 1,
5662 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5664 { SystemZISD::MERGE_LOW, 8,
5665 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5667 { SystemZISD::MERGE_LOW, 4,
5668 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5670 { SystemZISD::MERGE_LOW, 2,
5671 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5673 { SystemZISD::MERGE_LOW, 1,
5674 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5676 { SystemZISD::PACK, 4,
5677 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5679 { SystemZISD::PACK, 2,
5680 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5682 { SystemZISD::PACK, 1,
5683 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5685 { SystemZISD::PERMUTE_DWORDS, 4,
5686 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5688 { SystemZISD::PERMUTE_DWORDS, 1,
5689 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5703 OpNo0 = OpNo1 = OpNos[1];
5704 }
else if (OpNos[1] < 0) {
5705 OpNo0 = OpNo1 = OpNos[0];
5723 unsigned &OpNo0,
unsigned &OpNo1) {
5724 int OpNos[] = { -1, -1 };
5737 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5739 OpNos[ModelOpNo] = RealOpNo;
5747 unsigned &OpNo0,
unsigned &OpNo1) {
5764 int Elt = Bytes[From];
5767 Transform[From] = -1;
5769 while (
P.Bytes[To] != Elt) {
5774 Transform[From] = To;
5798 Bytes.
resize(NumElements * BytesPerElement, -1);
5799 for (
unsigned I = 0;
I < NumElements; ++
I) {
5800 int Index = VSN->getMaskElt(
I);
5802 for (
unsigned J = 0; J < BytesPerElement; ++J)
5803 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5807 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5810 Bytes.
resize(NumElements * BytesPerElement, -1);
5811 for (
unsigned I = 0;
I < NumElements; ++
I)
5812 for (
unsigned J = 0; J < BytesPerElement; ++J)
5813 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5824 unsigned BytesPerElement,
int &
Base) {
5826 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5827 if (Bytes[Start +
I] >= 0) {
5828 unsigned Elem = Bytes[Start +
I];
5832 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5834 }
else if (
unsigned(
Base) != Elem -
I)
5847 unsigned &StartIndex,
unsigned &OpNo0,
5849 int OpNos[] = { -1, -1 };
5851 for (
unsigned I = 0;
I < 16; ++
I) {
5852 int Index = Bytes[
I];
5858 Shift = ExpectedShift;
5859 else if (Shift != ExpectedShift)
5863 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5865 OpNos[ModelOpNo] = RealOpNo;
5878 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5879 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5887 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5889 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5890 }
else if (
P.Opcode == SystemZISD::PACK) {
5893 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5902 N =
N->getOperand(0);
5905 return Op->getZExtValue() == 0;
5911 for (
unsigned I = 0;
I < Num ;
I++)
5923 for (
unsigned I = 0;
I < 2; ++
I)
5927 unsigned StartIndex, OpNo0, OpNo1;
5929 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5936 if (ZeroVecIdx != UINT32_MAX) {
5937 bool MaskFirst =
true;
5942 if (OpNo == ZeroVecIdx &&
I == 0) {
5947 if (OpNo != ZeroVecIdx && Byte == 0) {
5954 if (ZeroIdx != -1) {
5957 if (Bytes[
I] >= 0) {
5960 if (OpNo == ZeroVecIdx)
5972 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5975 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
5987 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
5993struct GeneralShuffle {
5994 GeneralShuffle(EVT vt)
5995 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
5999 void tryPrepareForUnpack();
6000 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
6015 unsigned UnpackFromEltSize;
6022void GeneralShuffle::addUndef() {
6024 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6025 Bytes.push_back(-1);
6034bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
6040 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
6045 if (FromBytesPerElement < BytesPerElement)
6049 (FromBytesPerElement - BytesPerElement));
6052 while (
Op.getNode()) {
6054 Op =
Op.getOperand(0);
6070 }
else if (
Op.isUndef()) {
6079 for (; OpNo <
Ops.size(); ++OpNo)
6080 if (
Ops[OpNo] ==
Op)
6082 if (OpNo ==
Ops.size())
6087 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6088 Bytes.push_back(
Base +
I);
6097 if (
Ops.size() == 0)
6101 tryPrepareForUnpack();
6104 if (
Ops.size() == 1)
6116 unsigned Stride = 1;
6117 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6118 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6128 else if (OpNo ==
I + Stride)
6139 if (NewBytes[J] >= 0) {
6141 "Invalid double permute");
6144 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6150 if (NewBytes[J] >= 0)
6166 unsigned OpNo0, OpNo1;
6170 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6175 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6182 dbgs() << Msg.c_str() <<
" { ";
6183 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6184 dbgs() << Bytes[
I] <<
" ";
6192void GeneralShuffle::tryPrepareForUnpack() {
6194 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6199 if (
Ops.size() > 2 &&
6204 UnpackFromEltSize = 1;
6205 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6206 bool MatchUnpack =
true;
6209 unsigned ToEltSize = UnpackFromEltSize * 2;
6210 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6213 if (Bytes[Elt] != -1) {
6215 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6216 MatchUnpack =
false;
6222 if (
Ops.size() == 2) {
6224 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6226 if (SrcBytes[i] == -1)
6228 if (SrcBytes[i] % 16 !=
int(i))
6229 CanUseUnpackHigh =
false;
6231 CanUseUnpackLow =
false;
6232 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6233 UnpackFromEltSize = UINT_MAX;
6237 if (!CanUseUnpackHigh)
6243 if (UnpackFromEltSize > 4)
6246 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6247 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6249 dumpBytes(Bytes,
"Original Bytes vector:"););
6258 Elt += UnpackFromEltSize;
6259 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6260 Bytes[
B] = Bytes[Elt];
6268 Ops.erase(&
Ops[ZeroVecOpNo]);
6270 if (Bytes[
I] >= 0) {
6272 if (OpNo > ZeroVecOpNo)
6283 if (!unpackWasPrepared())
6285 unsigned InBits = UnpackFromEltSize * 8;
6289 unsigned OutBits = InBits * 2;
6292 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6293 : SystemZISD::UNPACKL_HIGH,
6294 DL, OutVT, PackedOp);
6299 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6300 if (!
Op.getOperand(
I).isUndef())
6316 if (
Value.isUndef())
6328 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6331 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6332 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6353 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6369 GeneralShuffle GS(VT);
6371 bool FoundOne =
false;
6372 for (
unsigned I = 0;
I < NumElements; ++
I) {
6375 Op =
Op.getOperand(0);
6378 unsigned Elem =
Op.getConstantOperandVal(1);
6379 if (!GS.add(
Op.getOperand(0), Elem))
6382 }
else if (
Op.isUndef()) {
6396 if (!ResidueOps.
empty()) {
6397 while (ResidueOps.
size() < NumElements)
6399 for (
auto &
Op : GS.Ops) {
6400 if (!
Op.getNode()) {
6406 return GS.getNode(DAG,
SDLoc(BVN));
6409bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6415 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6426 "Handling full vectors only.");
6446 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6458 unsigned int NumElements = Elems.
size();
6459 unsigned int Count = 0;
6460 for (
auto Elem : Elems) {
6461 if (!Elem.isUndef()) {
6464 else if (Elem != Single) {
6484 if (
Single.getNode() && (
Count > 1 || isVectorElementLoad(Single)))
6485 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Single);
6488 bool AllLoads =
true;
6489 for (
auto Elem : Elems)
6490 if (!isVectorElementLoad(Elem)) {
6496 if (VT == MVT::v2i64 && !AllLoads)
6500 if (VT == MVT::v2f64 && !AllLoads)
6510 if (VT == MVT::v4f32 && !AllLoads)
6514 if (VT == MVT::v8f16 && !AllLoads) {
6523 if (Op0123.
getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6532 unsigned NumConstants = 0;
6533 for (
unsigned I = 0;
I < NumElements; ++
I) {
6547 if (NumConstants > 0) {
6548 for (
unsigned I = 0;
I < NumElements; ++
I)
6559 std::map<const SDNode*, unsigned> UseCounts;
6560 SDNode *LoadMaxUses =
nullptr;
6561 for (
unsigned I = 0;
I < NumElements; ++
I)
6562 if (isVectorElementLoad(Elems[
I])) {
6563 SDNode *Ld = Elems[
I].getNode();
6564 unsigned Count = ++UseCounts[Ld];
6565 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6568 if (LoadMaxUses !=
nullptr) {
6569 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6573 unsigned I1 = NumElements / 2 - 1;
6574 unsigned I2 = NumElements - 1;
6575 bool Def1 = !Elems[
I1].isUndef();
6576 bool Def2 = !Elems[I2].isUndef();
6590 for (
unsigned I = 0;
I < NumElements; ++
I)
6591 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6601 EVT VT =
Op.getValueType();
6603 if (BVN->isConstant()) {
6604 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6622 for (
unsigned I = 0;
I < NumElements; ++
I)
6624 return buildVector(DAG,
DL, VT,
Ops);
6631 EVT VT =
Op.getValueType();
6634 if (VSN->isSplat()) {
6636 unsigned Index = VSN->getSplatIndex();
6638 "Splat index should be defined and in first operand");
6644 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6648 GeneralShuffle
GS(VT);
6649 for (
unsigned I = 0;
I < NumElements; ++
I) {
6650 int Elt = VSN->getMaskElt(
I);
6653 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6654 unsigned(Elt) % NumElements))
6657 return GS.getNode(DAG, SDLoc(VSN));
6672 assert(
Op.getSimpleValueType() == MVT::i64 &&
6673 "Expexted to convert i64 to f16.");
6685 assert(
Op.getSimpleValueType() == MVT::f16 &&
6686 "Expected to convert f16 to i64.");
6703 EVT VT =
Op.getValueType();
6708 if (VT == MVT::v2f64 &&
6732SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6738 EVT VT =
Op.getValueType();
6743 uint64_t
Index = CIndexN->getZExtValue();
6752 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6760SDValue SystemZTargetLowering::
6763 EVT OutVT =
Op.getValueType();
6767 unsigned StartOffset = 0;
6774 ArrayRef<int> ShuffleMask = SVN->
getMask();
6779 if (ToBits == 64 && OutNumElts == 2) {
6780 int NumElem = ToBits / FromBits;
6781 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6787 int StartOffsetCandidate = -1;
6788 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6789 if (ShuffleMask[Elt] == -1)
6791 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6792 if (StartOffsetCandidate == -1)
6793 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6794 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6797 StartOffsetCandidate = -1;
6800 if (StartOffsetCandidate != -1) {
6801 StartOffset = StartOffsetCandidate;
6810 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6811 if (StartOffset >= OutNumElts) {
6812 Opcode = SystemZISD::UNPACK_LOW;
6813 StartOffset -= OutNumElts;
6815 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6816 }
while (FromBits != ToBits);
6821SDValue SystemZTargetLowering::
6825 EVT OutVT =
Op.getValueType();
6829 unsigned NumInPerOut = InNumElts / OutNumElts;
6834 SmallVector<int, 16>
Mask(InNumElts);
6835 unsigned ZeroVecElt = InNumElts;
6836 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6837 unsigned MaskElt = PackedElt * NumInPerOut;
6838 unsigned End = MaskElt + NumInPerOut - 1;
6839 for (; MaskElt < End; MaskElt++)
6840 Mask[MaskElt] = ZeroVecElt++;
6841 Mask[MaskElt] = PackedElt;
6848 unsigned ByScalar)
const {
6853 EVT VT =
Op.getValueType();
6858 APInt SplatBits, SplatUndef;
6859 unsigned SplatBitSize;
6863 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6864 ElemBitSize,
true) &&
6865 SplatBitSize == ElemBitSize) {
6868 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6871 BitVector UndefElements;
6877 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6884 if (VSN->isSplat()) {
6885 SDValue VSNOp0 = VSN->getOperand(0);
6886 unsigned Index = VSN->getSplatIndex();
6888 "Splat index should be defined and in first operand");
6895 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6913 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6914 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6917 if (ShiftAmt > 120) {
6921 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6925 SmallVector<int, 16>
Mask(16);
6926 for (
unsigned Elt = 0; Elt < 16; Elt++)
6927 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6929 if ((ShiftAmt & 7) == 0)
6933 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6951 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6952 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6955 if (ShiftAmt > 120) {
6959 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6963 SmallVector<int, 16>
Mask(16);
6964 for (
unsigned Elt = 0; Elt < 16; Elt++)
6965 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6967 if ((ShiftAmt & 7) == 0)
6971 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
6983 MVT DstVT =
Op.getSimpleValueType();
6986 unsigned SrcAS =
N->getSrcAddressSpace();
6988 assert(SrcAS !=
N->getDestAddressSpace() &&
6989 "addrspacecast must be between different address spaces");
6997 }
else if (DstVT == MVT::i32) {
7011 if (
In.getSimpleValueType() != MVT::f16)
7018 SDValue Chain,
bool IsStrict)
const {
7019 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
7022 std::tie(Result, Chain) =
7031 bool IsStrict =
Op->isStrictFPOpcode();
7033 MVT VT =
Op.getSimpleValueType();
7034 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7042 if (!Subtarget.hasFPExtension() && !IsSigned)
7053 if (VT == MVT::i128) {
7056 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7066 bool IsStrict =
Op->isStrictFPOpcode();
7068 MVT VT =
Op.getSimpleValueType();
7069 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7074 if (VT == MVT::f16) {
7081 if (!Subtarget.hasFPExtension() && !IsSigned)
7084 if (InVT == MVT::i128) {
7087 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7096 EVT RegVT =
Op.getValueType();
7097 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
7104 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7106 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7107 AtomicLd->getMemOperand());
7127 Shft, AtomicSt->getBasePtr(),
7128 AtomicSt->getMemOperand());
7138 MVT ResultVT =
Op.getSimpleValueType();
7140 unsigned Check =
Op.getConstantOperandVal(1);
7142 unsigned TDCMask = 0;
7177 MachinePointerInfo MPI =
7183 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7187 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7192 switch (
Op.getOpcode()) {
7194 return lowerFRAMEADDR(
Op, DAG);
7196 return lowerRETURNADDR(
Op, DAG);
7198 return lowerBR_CC(
Op, DAG);
7200 return lowerSELECT_CC(
Op, DAG);
7202 return lowerSETCC(
Op, DAG);
7204 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7206 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7218 return lowerBITCAST(
Op, DAG);
7220 return lowerVASTART(
Op, DAG);
7222 return lowerVACOPY(
Op, DAG);
7224 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7226 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7228 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7230 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7232 return lowerSMUL_LOHI(
Op, DAG);
7234 return lowerUMUL_LOHI(
Op, DAG);
7236 return lowerSDIVREM(
Op, DAG);
7238 return lowerUDIVREM(
Op, DAG);
7243 return lowerXALUO(
Op, DAG);
7246 return lowerUADDSUBO_CARRY(
Op, DAG);
7248 return lowerOR(
Op, DAG);
7250 return lowerCTPOP(
Op, DAG);
7252 return lowerVECREDUCE_ADD(
Op, DAG);
7254 return lowerATOMIC_FENCE(
Op, DAG);
7256 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7258 return lowerATOMIC_STORE(
Op, DAG);
7260 return lowerATOMIC_LOAD(
Op, DAG);
7262 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7264 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7266 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7268 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7270 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7272 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7274 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7276 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7278 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7280 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7282 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7284 return lowerSTACKSAVE(
Op, DAG);
7286 return lowerSTACKRESTORE(
Op, DAG);
7288 return lowerPREFETCH(
Op, DAG);
7290 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7292 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7294 return lowerBUILD_VECTOR(
Op, DAG);
7296 return lowerVECTOR_SHUFFLE(
Op, DAG);
7298 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7300 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7302 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7304 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7306 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7308 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7310 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7312 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7316 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7318 return lowerFSHL(
Op, DAG);
7320 return lowerFSHR(
Op, DAG);
7323 return lowerFP_EXTEND(
Op, DAG);
7328 return lower_FP_TO_INT(
Op, DAG);
7333 return lower_INT_TO_FP(
Op, DAG);
7335 return lowerLoadF16(
Op, DAG);
7337 return lowerStoreF16(
Op, DAG);
7339 return lowerIS_FPCLASS(
Op, DAG);
7341 return lowerGET_ROUNDING(
Op, DAG);
7343 return lowerREADCYCLECOUNTER(
Op, DAG);
7365 &SystemZ::FP128BitRegClass);
7374 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7389 &SystemZ::FP128BitRegClass);
7406 switch (
N->getOpcode()) {
7410 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7413 DL, Tys,
Ops, MVT::i128, MMO);
7416 if (
N->getValueType(0) == MVT::f128)
7430 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7433 DL, Tys,
Ops, MVT::i128, MMO);
7439 MVT::Other, Res), 0);
7451 DL, Tys,
Ops, MVT::i128, MMO);
7465 EVT SrcVT = Src.getValueType();
7466 EVT ResVT =
N->getValueType(0);
7467 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7469 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7470 if (Subtarget.hasVector()) {
7478 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7480 Subtarget.hasVector()
7494 bool IsStrict =
N->isStrictFPOpcode();
7496 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7497 EVT ResVT =
N->getValueType(0);
7499 if (ResVT == MVT::f16) {
7522 bool IsStrict =
N->isStrictFPOpcode();
7524 EVT ResVT =
N->getValueType(0);
7525 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7528 if (InVT == MVT::f16) {
7534 std::tie(InF32, Chain) =
7559bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7560 if (!Subtarget.hasVector())
7574 DAGCombinerInfo &DCI,
7582 unsigned Opcode =
Op.getOpcode();
7585 Op =
Op.getOperand(0);
7587 canTreatAsByteVector(
Op.getValueType())) {
7596 BytesPerElement,
First))
7603 if (Byte % BytesPerElement != 0)
7606 Index = Byte / BytesPerElement;
7610 canTreatAsByteVector(
Op.getValueType())) {
7613 EVT OpVT =
Op.getValueType();
7615 if (OpBytesPerElement < BytesPerElement)
7619 unsigned End = (
Index + 1) * BytesPerElement;
7620 if (End % OpBytesPerElement != 0)
7623 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7624 if (!
Op.getValueType().isInteger()) {
7627 DCI.AddToWorklist(
Op.getNode());
7632 DCI.AddToWorklist(
Op.getNode());
7639 canTreatAsByteVector(
Op.getValueType()) &&
7640 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7642 EVT ExtVT =
Op.getValueType();
7643 EVT OpVT =
Op.getOperand(0).getValueType();
7646 unsigned Byte =
Index * BytesPerElement;
7647 unsigned SubByte =
Byte % ExtBytesPerElement;
7648 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7649 if (SubByte < MinSubByte ||
7650 SubByte + BytesPerElement > ExtBytesPerElement)
7653 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7655 Byte += SubByte - MinSubByte;
7656 if (Byte % BytesPerElement != 0)
7658 Op =
Op.getOperand(0);
7665 if (
Op.getValueType() != VecVT) {
7667 DCI.AddToWorklist(
Op.getNode());
7677SDValue SystemZTargetLowering::combineTruncateExtract(
7686 if (canTreatAsByteVector(VecVT)) {
7690 if (BytesPerElement % TruncBytes == 0) {
7696 unsigned Scale = BytesPerElement / TruncBytes;
7697 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7704 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7705 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7713SDValue SystemZTargetLowering::combineZERO_EXTEND(
7714 SDNode *
N, DAGCombinerInfo &DCI)
const {
7716 SelectionDAG &DAG = DCI.DAG;
7718 EVT VT =
N->getValueType(0);
7719 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7722 if (TrueOp && FalseOp) {
7732 DCI.CombineTo(N0.
getNode(), TruncSelect);
7775 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7793SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7794 SDNode *
N, DAGCombinerInfo &DCI)
const {
7798 SelectionDAG &DAG = DCI.DAG;
7800 EVT VT =
N->getValueType(0);
7814SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7815 SDNode *
N, DAGCombinerInfo &DCI)
const {
7819 SelectionDAG &DAG = DCI.DAG;
7821 EVT VT =
N->getValueType(0);
7828 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7829 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7845SDValue SystemZTargetLowering::combineMERGE(
7846 SDNode *
N, DAGCombinerInfo &DCI)
const {
7847 SelectionDAG &DAG = DCI.DAG;
7848 unsigned Opcode =
N->getOpcode();
7856 if (Op1 ==
N->getOperand(0))
7861 if (ElemBytes <= 4) {
7862 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7863 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7869 DCI.AddToWorklist(Op1.
getNode());
7872 DCI.AddToWorklist(
Op.getNode());
7881 LoPart = HiPart =
nullptr;
7886 if (
Use.getResNo() != 0)
7891 bool IsLoPart =
true;
7916 LoPart = HiPart =
nullptr;
7921 if (
Use.getResNo() != 0)
7927 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7930 switch (
User->getConstantOperandVal(1)) {
7931 case SystemZ::subreg_l64:
7936 case SystemZ::subreg_h64:
7948SDValue SystemZTargetLowering::combineLOAD(
7949 SDNode *
N, DAGCombinerInfo &DCI)
const {
7950 SelectionDAG &DAG = DCI.DAG;
7951 EVT LdVT =
N->getValueType(0);
7955 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7956 if (PtrVT != LoadNodeVT) {
7960 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7961 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7962 LN->getMemOperand());
7972 SDNode *LoPart, *HiPart;
7980 LD->getPointerInfo(),
LD->getBaseAlign(),
7981 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7983 DCI.CombineTo(HiPart, EltLoad,
true);
7990 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
7991 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7993 DCI.CombineTo(LoPart, EltLoad,
true);
8000 DCI.AddToWorklist(Chain.
getNode());
8015 for (SDUse &Use :
N->uses()) {
8016 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
8020 }
else if (
Use.getResNo() == 0)
8023 if (!Replicate || OtherUses.
empty())
8029 for (SDNode *U : OtherUses) {
8032 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
8038bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8039 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8041 if (Subtarget.hasVectorEnhancements2())
8042 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8054 for (
unsigned i = 0; i < NumElts; ++i) {
8055 if (M[i] < 0)
continue;
8056 if ((
unsigned) M[i] != NumElts - 1 - i)
8064 for (
auto *U : StoredVal->
users()) {
8066 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8125SDValue SystemZTargetLowering::combineSTORE(
8126 SDNode *
N, DAGCombinerInfo &DCI)
const {
8127 SelectionDAG &DAG = DCI.DAG;
8130 EVT MemVT = SN->getMemoryVT();
8134 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8135 if (PtrVT != StoreNodeVT) {
8139 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8140 SN->getPointerInfo(), SN->getBaseAlign(),
8141 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8149 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8151 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8152 DCI.AddToWorklist(
Value.getNode());
8156 SN->getBasePtr(), SN->getMemoryVT(),
8157 SN->getMemOperand());
8168 return DAG.
getNode(SystemZISD::MOV_STACKGUARD, SDLoc(SN), MVT::Other,
Ops);
8172 if (!SN->isTruncatingStore() &&
8188 Ops, MemVT, SN->getMemOperand());
8191 if (!SN->isTruncatingStore() &&
8194 Subtarget.hasVectorEnhancements2()) {
8196 ArrayRef<int> ShuffleMask = SVN->
getMask();
8204 Ops, MemVT, SN->getMemOperand());
8209 if (!SN->isTruncatingStore() &&
8212 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8216 Ops, MemVT, SN->getMemOperand());
8226 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8227 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8229 SN->getChain(),
DL, LoPart,
8231 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8232 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8250 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8252 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8256 APInt Val =
C->getAPIntValue();
8259 assert(SN->isTruncatingStore() &&
8260 "Non-truncating store and immediate value does not fit?");
8261 Val = Val.
trunc(TotBytes * 8);
8264 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8265 if (VCI.isVectorConstantLegal(Subtarget) &&
8266 VCI.Opcode == SystemZISD::REPLICATE) {
8274 auto FindReplicatedReg = [&](
SDValue MulOp) {
8275 EVT MulVT = MulOp.getValueType();
8276 if (MulOp->getOpcode() ==
ISD::MUL &&
8277 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8281 WordVT =
LHS->getOperand(0).getValueType();
8288 SystemZVectorConstantInfo VCI(
8290 if (VCI.isVectorConstantLegal(Subtarget) &&
8291 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8292 WordVT == VCI.VecVT.getScalarType())
8304 FindReplicatedReg(SplatVal);
8309 FindReplicatedReg(Op1);
8314 "Bad type handling");
8318 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8319 SN->getBasePtr(), SN->getMemOperand());
8326SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8327 SDNode *
N, DAGCombinerInfo &DCI)
const {
8328 SelectionDAG &DAG = DCI.DAG;
8331 N->getOperand(0).hasOneUse() &&
8332 Subtarget.hasVectorEnhancements2()) {
8334 ArrayRef<int> ShuffleMask = SVN->
getMask();
8347 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8351 DCI.CombineTo(
N, ESLoad);
8355 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8365SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8366 SDNode *
N, DAGCombinerInfo &DCI)
const {
8367 SelectionDAG &DAG = DCI.DAG;
8369 if (!Subtarget.hasVector())
8375 Op.getValueType().isVector() &&
8376 Op.getOperand(0).getValueType().isVector() &&
8377 Op.getValueType().getVectorNumElements() ==
8378 Op.getOperand(0).getValueType().getVectorNumElements())
8379 Op =
Op.getOperand(0);
8383 EVT VecVT =
Op.getValueType();
8386 Op.getOperand(0),
N->getOperand(1));
8387 DCI.AddToWorklist(
Op.getNode());
8389 if (EltVT !=
N->getValueType(0)) {
8390 DCI.AddToWorklist(
Op.getNode());
8400 if (canTreatAsByteVector(VecVT))
8401 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8402 IndexN->getZExtValue(), DCI,
false);
8407SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8408 SDNode *
N, DAGCombinerInfo &DCI)
const {
8409 SelectionDAG &DAG = DCI.DAG;
8411 if (
N->getOperand(0) ==
N->getOperand(1))
8412 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8422 if (Chain1 == Chain2)
8430SDValue SystemZTargetLowering::combineFP_ROUND(
8431 SDNode *
N, DAGCombinerInfo &DCI)
const {
8433 if (!Subtarget.hasVector())
8442 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8443 SelectionDAG &DAG = DCI.DAG;
8445 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8451 for (
auto *U : Vec->
users()) {
8452 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8454 U->getOperand(0) == Vec &&
8456 U->getConstantOperandVal(1) == 1) {
8458 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8462 if (
N->isStrictFPOpcode()) {
8466 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8467 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8470 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8472 DCI.AddToWorklist(VRound.
getNode());
8476 DCI.AddToWorklist(Extract1.
getNode());
8482 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8485 N->getVTList(), Extract0, Chain);
8494SDValue SystemZTargetLowering::combineFP_EXTEND(
8495 SDNode *
N, DAGCombinerInfo &DCI)
const {
8497 if (!Subtarget.hasVector())
8506 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8507 SelectionDAG &DAG = DCI.DAG;
8509 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8515 for (
auto *U : Vec->
users()) {
8516 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8518 U->getOperand(0) == Vec &&
8520 U->getConstantOperandVal(1) == 2) {
8522 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8526 if (
N->isStrictFPOpcode()) {
8530 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8531 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8534 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8536 DCI.AddToWorklist(VExtend.
getNode());
8540 DCI.AddToWorklist(Extract1.
getNode());
8546 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8549 N->getVTList(), Extract0, Chain);
8558SDValue SystemZTargetLowering::combineINT_TO_FP(
8559 SDNode *
N, DAGCombinerInfo &DCI)
const {
8562 SelectionDAG &DAG = DCI.DAG;
8564 unsigned Opcode =
N->getOpcode();
8565 EVT OutVT =
N->getValueType(0);
8569 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8575 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8576 OutScalarBits <= 64) {
8580 unsigned ExtOpcode =
8583 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8588SDValue SystemZTargetLowering::combineFCOPYSIGN(
8589 SDNode *
N, DAGCombinerInfo &DCI)
const {
8590 SelectionDAG &DAG = DCI.DAG;
8591 EVT VT =
N->getValueType(0);
8604SDValue SystemZTargetLowering::combineBSWAP(
8605 SDNode *
N, DAGCombinerInfo &DCI)
const {
8606 SelectionDAG &DAG = DCI.DAG;
8609 N->getOperand(0).hasOneUse() &&
8610 canLoadStoreByteSwapped(
N->getValueType(0))) {
8619 EVT LoadVT =
N->getValueType(0);
8620 if (LoadVT == MVT::i16)
8625 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8629 if (
N->getValueType(0) == MVT::i16)
8634 DCI.CombineTo(
N, ResVal);
8638 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8647 Op.getValueType().isVector() &&
8648 Op.getOperand(0).getValueType().isVector() &&
8649 Op.getValueType().getVectorNumElements() ==
8650 Op.getOperand(0).getValueType().getVectorNumElements())
8651 Op =
Op.getOperand(0);
8663 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8665 EVT VecVT =
N->getValueType(0);
8669 DCI.AddToWorklist(Vec.
getNode());
8673 DCI.AddToWorklist(Elt.
getNode());
8676 DCI.AddToWorklist(Vec.
getNode());
8678 DCI.AddToWorklist(Elt.
getNode());
8686 if (SV &&
Op.hasOneUse()) {
8694 EVT VecVT =
N->getValueType(0);
8697 DCI.AddToWorklist(Op0.
getNode());
8701 DCI.AddToWorklist(Op1.
getNode());
8704 DCI.AddToWorklist(Op0.
getNode());
8706 DCI.AddToWorklist(Op1.
getNode());
8714SDValue SystemZTargetLowering::combineSETCC(
8715 SDNode *
N, DAGCombinerInfo &DCI)
const {
8716 SelectionDAG &DAG = DCI.DAG;
8722 EVT VT =
N->getValueType(0);
8732 Src.getValueType().isFixedLengthVector() &&
8733 Src.getValueType().getScalarType() == MVT::i1) {
8734 EVT CmpVT = Src.getOperand(0).getValueType();
8751 unsigned Depth = 0) {
8759 case SystemZISD::IPM:
8764 case SystemZISD::SELECT_CCMASK: {
8766 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8767 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8770 return std::make_pair(OpCC, OpCCValid);
8775 int CCValidVal = CCValid->getZExtValue();
8776 return std::make_pair(Op4CCReg, CCValidVal);
8787 return std::make_pair(Op0CC, Op0CCValid);
8803 return {Val, Val, Val, Val};
8804 case SystemZISD::IPM: {
8809 for (
auto CC : {0, 1, 2, 3})
8812 return ShiftedCCVals;
8814 case SystemZISD::SELECT_CCMASK: {
8818 if (!CCValid || !CCMask)
8821 int CCValidVal = CCValid->getZExtValue();
8822 int CCMaskVal = CCMask->getZExtValue();
8832 if (TrueSDVals.empty() || FalseSDVals.empty())
8835 for (
auto &CCVal : {0, 1, 2, 3})
8836 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8838 : FalseSDVals[CCVal]);
8839 return MergedSDVals;
8856 if (Op0SDVals.empty() || Op1SDVals.empty())
8859 for (
auto CCVal : {0, 1, 2, 3})
8861 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8862 return BinaryOpSDVals;
8873 auto *CCNode = CCReg.
getNode();
8877 if (CCNode->getOpcode() == SystemZISD::TM) {
8880 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8883 if (!Op0Node || !Op1Node)
8885 auto Op0APVal = Op0Node->getAPIntValue();
8886 auto Op1APVal = Op1Node->getAPIntValue();
8887 auto Result = Op0APVal & Op1APVal;
8888 bool AllOnes = Result == Op1APVal;
8889 bool AllZeros = Result == 0;
8890 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
8891 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8895 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8900 if (Op0SDVals.empty() || Op1SDVals.empty())
8903 for (
auto CC : {0, 1, 2, 3}) {
8904 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8908 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8910 NewCCMask &= Op0CCValid;
8913 CCValid = Op0CCValid;
8916 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8923 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8927 if (Op0SDVals.empty() || Op1SDVals.empty())
8931 auto CmpTypeVal = CmpType->getZExtValue();
8932 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8936 if (!Op0Node || !Op1Node)
8938 auto Op0APVal = Op0Node->getAPIntValue();
8939 auto Op1APVal = Op1Node->getAPIntValue();
8941 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8942 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8945 for (
auto CC : {0, 1, 2, 3}) {
8946 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8950 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8952 NewCCMask &= Op0CCValid;
8955 CCValid = Op0CCValid;
8966 const Value *Rhs)
const {
8967 const auto isFlagOutOpCC = [](
const Value *V) {
8969 const Value *RHSVal;
8976 if (CB->isInlineAsm()) {
8978 return IA && IA->getConstraintString().contains(
"{@cc}");
8989 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
8992 return {-1, -1, -1};
8996 DAGCombinerInfo &DCI)
const {
9002 if (!CCValid || !CCMask)
9005 int CCValidVal = CCValid->getZExtValue();
9006 int CCMaskVal = CCMask->getZExtValue();
9013 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
9014 CCMaskVal != CCValidVal)
9015 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
9019 N->getOperand(3), CCReg);
9023SDValue SystemZTargetLowering::combineSELECT_CCMASK(
9024 SDNode *
N, DAGCombinerInfo &DCI)
const {
9030 if (!CCValid || !CCMask)
9033 int CCValidVal = CCValid->getZExtValue();
9034 int CCMaskVal = CCMask->getZExtValue();
9037 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
9041 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
9042 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9044 if (Val.getOperand(4) != CCReg)
9051 int CCMaskVal = CCMask->getZExtValue();
9052 for (
auto &CC : {0, 1, 2, 3})
9053 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
9067 if (TrueSDVals.empty())
9068 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9069 if (FalseSDVals.empty())
9070 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9071 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9072 SmallSet<SDValue, 4> MergedSDValsSet;
9074 for (
auto CC : {0, 1, 2, 3}) {
9075 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
9076 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
9080 if (MergedSDValsSet.
size() == 1)
9081 return *MergedSDValsSet.
begin();
9082 if (MergedSDValsSet.
size() == 2) {
9083 auto BeginIt = MergedSDValsSet.
begin();
9084 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9085 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9088 for (
auto CC : {0, 1, 2, 3}) {
9090 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
9091 ? (TrueSDVals[CC] == NewTrueVal)
9092 : (FalseSDVals[CC] == NewTrueVal);
9094 CCMaskVal = NewCCMask;
9095 CCMaskVal &= CCValidVal;
9098 IsCombinedCCReg =
true;
9106 if (CCMaskVal == CCValidVal)
9109 if (IsCombinedCCReg)
9111 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
9118SDValue SystemZTargetLowering::combineGET_CCMASK(
9119 SDNode *
N, DAGCombinerInfo &DCI)
const {
9124 if (!CCValid || !CCMask)
9126 int CCValidVal = CCValid->getZExtValue();
9127 int CCMaskVal = CCMask->getZExtValue();
9132 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9137 if (!SelectCCValid || !SelectCCMask)
9139 int SelectCCValidVal = SelectCCValid->getZExtValue();
9140 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9144 if (!TrueVal || !FalseVal)
9148 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9149 SelectCCMaskVal ^= SelectCCValidVal;
9153 if (SelectCCValidVal & ~CCValidVal)
9155 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9158 return Select->getOperand(4);
9161SDValue SystemZTargetLowering::combineIntDIVREM(
9162 SDNode *
N, DAGCombinerInfo &DCI)
const {
9163 SelectionDAG &DAG = DCI.DAG;
9164 EVT VT =
N->getValueType(0);
9181SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9182 SDNode *
N, DAGCombinerInfo &DCI)
const {
9183 SelectionDAG &DAG = DCI.DAG;
9187 "SRL or SRA node is required here!");
9189 if (!Subtarget.hasVector())
9199 SDValue ShiftOperand =
N->getOperand(0);
9219 if (!IsSignExt && !IsZeroExt)
9227 unsigned ActiveBits = IsSignExt
9228 ?
Constant->getAPIntValue().getSignificantBits()
9229 :
Constant->getAPIntValue().getActiveBits();
9230 if (ActiveBits > NarrowVTSize)
9246 unsigned ActiveBits = IsSignExt
9247 ?
Constant->getAPIntValue().getSignificantBits()
9248 :
Constant->getAPIntValue().getActiveBits();
9249 if (ActiveBits > NarrowVTSize)
9266 "Cannot have a multiply node with two different operand types.");
9268 "Cannot have an add node with two different operand types.");
9279 if (ShiftAmt != NarrowVTSize)
9283 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9284 NarrowVT == MVT::v4i32 ||
9285 (Subtarget.hasVectorEnhancements3() &&
9286 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9292 MulhRightOp, MulhAddOp);
9293 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9304 EVT VT =
Op.getValueType();
9313 Op =
Op.getOperand(0);
9314 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9318 bool CanUseEven =
true, CanUseOdd =
true;
9319 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9320 if (ShuffleMask[Elt] == -1)
9322 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9324 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9327 Op =
Op.getOperand(0);
9329 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9331 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9337 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9341 Op =
Op.getOperand(0);
9343 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9345 unsigned Elem =
Op.getConstantOperandVal(1);
9346 Op =
Op.getOperand(0);
9348 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9350 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9357SDValue SystemZTargetLowering::combineMUL(
9358 SDNode *
N, DAGCombinerInfo &DCI)
const {
9359 SelectionDAG &DAG = DCI.DAG;
9366 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9367 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9372SDValue SystemZTargetLowering::combineINTRINSIC(
9373 SDNode *
N, DAGCombinerInfo &DCI)
const {
9374 SelectionDAG &DAG = DCI.DAG;
9376 unsigned Id =
N->getConstantOperandVal(1);
9380 case Intrinsic::s390_vll:
9381 case Intrinsic::s390_vlrl:
9383 if (
C->getZExtValue() >= 15)
9384 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9385 N->getOperand(3), MachinePointerInfo());
9388 case Intrinsic::s390_vstl:
9389 case Intrinsic::s390_vstrl:
9391 if (
C->getZExtValue() >= 15)
9392 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9393 N->getOperand(4), MachinePointerInfo());
9401 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9408 switch(
N->getOpcode()) {
9413 case SystemZISD::MERGE_HIGH:
9414 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9419 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9429 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9430 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9433 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9434 case ISD::MUL:
return combineMUL(
N, DCI);
9438 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9450 EVT VT =
Op.getValueType();
9453 unsigned Opcode =
Op.getOpcode();
9455 unsigned Id =
Op.getConstantOperandVal(0);
9457 case Intrinsic::s390_vpksh:
9458 case Intrinsic::s390_vpksf:
9459 case Intrinsic::s390_vpksg:
9460 case Intrinsic::s390_vpkshs:
9461 case Intrinsic::s390_vpksfs:
9462 case Intrinsic::s390_vpksgs:
9463 case Intrinsic::s390_vpklsh:
9464 case Intrinsic::s390_vpklsf:
9465 case Intrinsic::s390_vpklsg:
9466 case Intrinsic::s390_vpklshs:
9467 case Intrinsic::s390_vpklsfs:
9468 case Intrinsic::s390_vpklsgs:
9470 SrcDemE = DemandedElts;
9473 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9476 case Intrinsic::s390_vuphb:
9477 case Intrinsic::s390_vuphh:
9478 case Intrinsic::s390_vuphf:
9479 case Intrinsic::s390_vuplhb:
9480 case Intrinsic::s390_vuplhh:
9481 case Intrinsic::s390_vuplhf:
9482 SrcDemE =
APInt(NumElts * 2, 0);
9485 case Intrinsic::s390_vuplb:
9486 case Intrinsic::s390_vuplhw:
9487 case Intrinsic::s390_vuplf:
9488 case Intrinsic::s390_vupllb:
9489 case Intrinsic::s390_vupllh:
9490 case Intrinsic::s390_vupllf:
9491 SrcDemE =
APInt(NumElts * 2, 0);
9494 case Intrinsic::s390_vpdi: {
9496 SrcDemE =
APInt(NumElts, 0);
9497 if (!DemandedElts[OpNo - 1])
9499 unsigned Mask =
Op.getConstantOperandVal(3);
9500 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9502 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9505 case Intrinsic::s390_vsldb: {
9507 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9508 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9509 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9510 unsigned NumSrc0Els = 16 - FirstIdx;
9511 SrcDemE =
APInt(NumElts, 0);
9513 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9516 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9521 case Intrinsic::s390_vperm:
9530 case SystemZISD::JOIN_DWORDS:
9532 SrcDemE =
APInt(1, 1);
9534 case SystemZISD::SELECT_CCMASK:
9535 SrcDemE = DemandedElts;
9546 const APInt &DemandedElts,
9561 const APInt &DemandedElts,
9563 unsigned Depth)
const {
9567 unsigned Tmp0, Tmp1;
9572 EVT VT =
Op.getValueType();
9573 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9576 "KnownBits does not match VT in bitwidth");
9579 "DemandedElts does not match VT number of elements");
9581 unsigned Opcode =
Op.getOpcode();
9583 bool IsLogical =
false;
9584 unsigned Id =
Op.getConstantOperandVal(0);
9586 case Intrinsic::s390_vpksh:
9587 case Intrinsic::s390_vpksf:
9588 case Intrinsic::s390_vpksg:
9589 case Intrinsic::s390_vpkshs:
9590 case Intrinsic::s390_vpksfs:
9591 case Intrinsic::s390_vpksgs:
9592 case Intrinsic::s390_vpklsh:
9593 case Intrinsic::s390_vpklsf:
9594 case Intrinsic::s390_vpklsg:
9595 case Intrinsic::s390_vpklshs:
9596 case Intrinsic::s390_vpklsfs:
9597 case Intrinsic::s390_vpklsgs:
9598 case Intrinsic::s390_vpdi:
9599 case Intrinsic::s390_vsldb:
9600 case Intrinsic::s390_vperm:
9603 case Intrinsic::s390_vuplhb:
9604 case Intrinsic::s390_vuplhh:
9605 case Intrinsic::s390_vuplhf:
9606 case Intrinsic::s390_vupllb:
9607 case Intrinsic::s390_vupllh:
9608 case Intrinsic::s390_vupllf:
9611 case Intrinsic::s390_vuphb:
9612 case Intrinsic::s390_vuphh:
9613 case Intrinsic::s390_vuphf:
9614 case Intrinsic::s390_vuplb:
9615 case Intrinsic::s390_vuplhw:
9616 case Intrinsic::s390_vuplf: {
9631 case SystemZISD::JOIN_DWORDS:
9632 case SystemZISD::SELECT_CCMASK:
9635 case SystemZISD::REPLICATE: {
9658 if (
LHS == 1)
return 1;
9661 if (
RHS == 1)
return 1;
9662 unsigned Common = std::min(
LHS,
RHS);
9663 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9664 EVT VT =
Op.getValueType();
9666 if (SrcBitWidth > VTBits) {
9667 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9668 if (Common > SrcExtraBits)
9669 return (Common - SrcExtraBits);
9672 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9679 unsigned Depth)
const {
9680 if (
Op.getResNo() != 0)
9682 unsigned Opcode =
Op.getOpcode();
9684 unsigned Id =
Op.getConstantOperandVal(0);
9686 case Intrinsic::s390_vpksh:
9687 case Intrinsic::s390_vpksf:
9688 case Intrinsic::s390_vpksg:
9689 case Intrinsic::s390_vpkshs:
9690 case Intrinsic::s390_vpksfs:
9691 case Intrinsic::s390_vpksgs:
9692 case Intrinsic::s390_vpklsh:
9693 case Intrinsic::s390_vpklsf:
9694 case Intrinsic::s390_vpklsg:
9695 case Intrinsic::s390_vpklshs:
9696 case Intrinsic::s390_vpklsfs:
9697 case Intrinsic::s390_vpklsgs:
9698 case Intrinsic::s390_vpdi:
9699 case Intrinsic::s390_vsldb:
9700 case Intrinsic::s390_vperm:
9702 case Intrinsic::s390_vuphb:
9703 case Intrinsic::s390_vuphh:
9704 case Intrinsic::s390_vuphf:
9705 case Intrinsic::s390_vuplb:
9706 case Intrinsic::s390_vuplhw:
9707 case Intrinsic::s390_vuplf: {
9711 EVT VT =
Op.getValueType();
9721 case SystemZISD::SELECT_CCMASK:
9734 switch (
Op->getOpcode()) {
9735 case SystemZISD::PCREL_WRAPPER:
9736 case SystemZISD::PCREL_OFFSET:
9747 "Unexpected stack alignment");
9750 unsigned StackProbeSize =
9753 StackProbeSize &= ~(StackAlign - 1);
9754 return StackProbeSize ? StackProbeSize : StackAlign;
9793 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9795 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9801 if (miI ==
MBB->end()) {
9803 if (Succ->isLiveIn(SystemZ::CC))
9814 switch (
MI.getOpcode()) {
9815 case SystemZ::Select32:
9816 case SystemZ::Select64:
9817 case SystemZ::Select128:
9818 case SystemZ::SelectF32:
9819 case SystemZ::SelectF64:
9820 case SystemZ::SelectF128:
9821 case SystemZ::SelectVR32:
9822 case SystemZ::SelectVR64:
9823 case SystemZ::SelectVR128:
9855 for (
auto *
MI : Selects) {
9856 Register DestReg =
MI->getOperand(0).getReg();
9857 Register TrueReg =
MI->getOperand(1).getReg();
9858 Register FalseReg =
MI->getOperand(2).getReg();
9863 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9866 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9867 TrueReg = It->second.first;
9869 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9870 FalseReg = It->second.second;
9873 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9878 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9889 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9890 assert(TFL->hasReservedCallFrame(MF) &&
9891 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9896 uint32_t NumBytes =
MI.getOperand(0).getImm();
9901 MI.eraseFromParent();
9910 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9912 unsigned CCValid =
MI.getOperand(3).getImm();
9913 unsigned CCMask =
MI.getOperand(4).getImm();
9918 SmallVector<MachineInstr*, 8> Selects;
9919 SmallVector<MachineInstr*, 8> DbgValues;
9925 assert(NextMI.getOperand(3).getImm() == CCValid &&
9926 "Bad CCValid operands since CC was not redefined.");
9927 if (NextMI.getOperand(4).getImm() == CCMask ||
9928 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9934 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9935 NextMI.usesCustomInsertionHook())
9938 for (
auto *SelMI : Selects)
9939 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9943 if (NextMI.isDebugInstr()) {
9945 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9948 }
else if (User || ++
Count > 20)
9952 MachineInstr *LastMI = Selects.back();
9953 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9955 MachineBasicBlock *StartMBB =
MBB;
9985 for (
auto *SelMI : Selects)
9986 SelMI->eraseFromParent();
9989 for (
auto *DbgMI : DbgValues)
9990 MBB->
splice(InsertPos, StartMBB, DbgMI);
10001 unsigned StoreOpcode,
10002 unsigned STOCOpcode,
10003 bool Invert)
const {
10004 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10006 Register SrcReg =
MI.getOperand(0).getReg();
10007 MachineOperand
Base =
MI.getOperand(1);
10008 int64_t Disp =
MI.getOperand(2).getImm();
10009 Register IndexReg =
MI.getOperand(3).getReg();
10010 unsigned CCValid =
MI.getOperand(4).getImm();
10011 unsigned CCMask =
MI.getOperand(5).getImm();
10014 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
10018 MachineMemOperand *MMO =
nullptr;
10019 for (
auto *
I :
MI.memoperands())
10020 if (
I->isStore()) {
10028 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
10040 MI.eraseFromParent();
10048 MachineBasicBlock *StartMBB =
MBB;
10054 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
10081 MI.eraseFromParent();
10091 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10099 MachineBasicBlock *StartMBB =
MBB;
10117 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10144 MI.eraseFromParent();
10155 bool Invert)
const {
10157 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10164 int64_t Disp =
MI.getOperand(2).getImm();
10166 Register BitShift =
MI.getOperand(4).getReg();
10167 Register NegBitShift =
MI.getOperand(5).getReg();
10168 unsigned BitSize =
MI.getOperand(6).getImm();
10172 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10173 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10174 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10184 MachineBasicBlock *StartMBB =
MBB;
10217 }
else if (BinOpcode)
10240 MI.eraseFromParent();
10251 unsigned KeepOldMask)
const {
10253 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10259 int64_t Disp =
MI.getOperand(2).getImm();
10261 Register BitShift =
MI.getOperand(4).getReg();
10262 Register NegBitShift =
MI.getOperand(5).getReg();
10263 unsigned BitSize =
MI.getOperand(6).getImm();
10267 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10268 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10269 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10280 MachineBasicBlock *StartMBB =
MBB;
10344 MI.eraseFromParent();
10354 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10360 int64_t Disp =
MI.getOperand(2).getImm();
10361 Register CmpVal =
MI.getOperand(3).getReg();
10362 Register OrigSwapVal =
MI.getOperand(4).getReg();
10363 Register BitShift =
MI.getOperand(5).getReg();
10364 Register NegBitShift =
MI.getOperand(6).getReg();
10365 int64_t BitSize =
MI.getOperand(7).getImm();
10368 const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass;
10371 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10372 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10373 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10374 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10386 MachineBasicBlock *StartMBB =
MBB;
10458 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10461 MI.eraseFromParent();
10469 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10474 .
add(
MI.getOperand(1))
10475 .
addImm(SystemZ::subreg_h64)
10476 .
add(
MI.getOperand(2))
10477 .
addImm(SystemZ::subreg_l64);
10478 MI.eraseFromParent();
10487 bool ClearEven)
const {
10489 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10511 MI.eraseFromParent();
10518 unsigned Opcode,
bool IsMemset)
const {
10520 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10525 uint64_t DestDisp =
MI.getOperand(1).getImm();
10530 auto foldDisplIfNeeded = [&](MachineOperand &
Base, uint64_t &Disp) ->
void {
10533 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10543 SrcDisp =
MI.getOperand(3).getImm();
10545 SrcBase = DestBase;
10546 SrcDisp = DestDisp++;
10547 foldDisplIfNeeded(DestBase, DestDisp);
10550 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10551 bool IsImmForm = LengthMO.
isImm();
10552 bool IsRegForm = !IsImmForm;
10555 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10557 MachineOperand DBase, uint64_t DDisp,
10558 MachineOperand
SBase, uint64_t SDisp,
10559 unsigned Length) ->
void {
10563 if (ByteMO.
isImm())
10578 bool NeedsLoop =
false;
10579 uint64_t ImmLength = 0;
10580 Register LenAdjReg = SystemZ::NoRegister;
10582 ImmLength = LengthMO.
getImm();
10583 ImmLength += IsMemset ? 2 : 1;
10584 if (ImmLength == 0) {
10585 MI.eraseFromParent();
10588 if (Opcode == SystemZ::CLC) {
10589 if (ImmLength > 3 * 256)
10599 }
else if (ImmLength > 6 * 256)
10607 LenAdjReg = LengthMO.
getReg();
10612 MachineBasicBlock *EndMBB =
10613 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10621 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10631 auto loadZeroAddress = [&]() -> MachineOperand {
10636 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10637 DestBase = loadZeroAddress();
10638 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10639 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10641 MachineBasicBlock *StartMBB =
nullptr;
10642 MachineBasicBlock *LoopMBB =
nullptr;
10643 MachineBasicBlock *NextMBB =
nullptr;
10644 MachineBasicBlock *DoneMBB =
nullptr;
10645 MachineBasicBlock *AllDoneMBB =
nullptr;
10649 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10651 const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass;
10658 RC = &SystemZ::GR64BitRegClass;
10686 MBB = MemsetOneCheckMBB;
10697 MBB = MemsetOneMBB;
10729 if (EndMBB && !ImmLength)
10751 if (!HaveSingleBase)
10758 if (Opcode == SystemZ::MVC)
10785 if (!HaveSingleBase)
10808 Register RemDestReg = HaveSingleBase ? RemSrcReg
10813 if (!HaveSingleBase)
10821 MachineInstrBuilder EXRL_MIB =
10829 if (Opcode != SystemZ::MVC) {
10839 while (ImmLength > 0) {
10840 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10843 foldDisplIfNeeded(DestBase, DestDisp);
10844 foldDisplIfNeeded(SrcBase, SrcDisp);
10845 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10846 DestDisp += ThisLength;
10847 SrcDisp += ThisLength;
10848 ImmLength -= ThisLength;
10851 if (EndMBB && ImmLength > 0) {
10867 MI.eraseFromParent();
10876 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10880 uint64_t End1Reg =
MI.getOperand(0).getReg();
10881 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10882 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10883 uint64_t CharReg =
MI.getOperand(3).getReg();
10885 const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass;
10890 MachineBasicBlock *StartMBB =
MBB;
10926 MI.eraseFromParent();
10933 bool NoFloat)
const {
10935 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10936 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10939 MI.setDesc(
TII->get(Opcode));
10943 uint64_t Control =
MI.getOperand(2).getImm();
10944 static const unsigned GPRControlBit[16] = {
10945 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10946 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
10948 Control |= GPRControlBit[15];
10949 if (TFI->
hasFP(MF))
10950 Control |= GPRControlBit[11];
10951 MI.getOperand(2).setImm(Control);
10954 for (
int I = 0;
I < 16;
I++) {
10955 if ((Control & GPRControlBit[
I]) == 0) {
10962 if (!NoFloat && (Control & 4) != 0) {
10963 if (Subtarget.hasVector()) {
10980 MachineRegisterInfo *MRI = &MF.
getRegInfo();
10981 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10984 Register SrcReg =
MI.getOperand(0).getReg();
10987 const TargetRegisterClass *RC = MRI->
getRegClass(SrcReg);
10995 MI.eraseFromParent();
11003 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11004 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11007 Register DstReg =
MI.getOperand(0).getReg();
11008 Register SizeReg =
MI.getOperand(2).getReg();
11010 MachineBasicBlock *StartMBB =
MBB;
11086 MI.eraseFromParent();
11090SDValue SystemZTargetLowering::
11093 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11105 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11110 .
addImm(
MI.getOperand(1).getImm());
11111 MI.eraseFromParent();
11117 switch (
MI.getOpcode()) {
11118 case SystemZ::ADJCALLSTACKDOWN:
11119 case SystemZ::ADJCALLSTACKUP:
11120 return emitAdjCallStack(
MI,
MBB);
11122 case SystemZ::Select32:
11123 case SystemZ::Select64:
11124 case SystemZ::Select128:
11125 case SystemZ::SelectF32:
11126 case SystemZ::SelectF64:
11127 case SystemZ::SelectF128:
11128 case SystemZ::SelectVR32:
11129 case SystemZ::SelectVR64:
11130 case SystemZ::SelectVR128:
11131 return emitSelect(
MI,
MBB);
11133 case SystemZ::CondStore8Mux:
11134 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11135 case SystemZ::CondStore8MuxInv:
11136 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11137 case SystemZ::CondStore16Mux:
11138 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11139 case SystemZ::CondStore16MuxInv:
11140 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11141 case SystemZ::CondStore32Mux:
11142 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11143 case SystemZ::CondStore32MuxInv:
11144 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11145 case SystemZ::CondStore8:
11146 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11147 case SystemZ::CondStore8Inv:
11148 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11149 case SystemZ::CondStore16:
11150 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11151 case SystemZ::CondStore16Inv:
11152 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11153 case SystemZ::CondStore32:
11154 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11155 case SystemZ::CondStore32Inv:
11156 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11157 case SystemZ::CondStore64:
11158 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11159 case SystemZ::CondStore64Inv:
11160 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11161 case SystemZ::CondStoreF32:
11162 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11163 case SystemZ::CondStoreF32Inv:
11164 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11165 case SystemZ::CondStoreF64:
11166 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11167 case SystemZ::CondStoreF64Inv:
11168 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11170 case SystemZ::SCmp128Hi:
11171 return emitICmp128Hi(
MI,
MBB,
false);
11172 case SystemZ::UCmp128Hi:
11173 return emitICmp128Hi(
MI,
MBB,
true);
11175 case SystemZ::PAIR128:
11176 return emitPair128(
MI,
MBB);
11177 case SystemZ::AEXT128:
11178 return emitExt128(
MI,
MBB,
false);
11179 case SystemZ::ZEXT128:
11180 return emitExt128(
MI,
MBB,
true);
11182 case SystemZ::ATOMIC_SWAPW:
11183 return emitAtomicLoadBinary(
MI,
MBB, 0);
11185 case SystemZ::ATOMIC_LOADW_AR:
11186 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11187 case SystemZ::ATOMIC_LOADW_AFI:
11188 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11190 case SystemZ::ATOMIC_LOADW_SR:
11191 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11193 case SystemZ::ATOMIC_LOADW_NR:
11194 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11195 case SystemZ::ATOMIC_LOADW_NILH:
11196 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11198 case SystemZ::ATOMIC_LOADW_OR:
11199 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11200 case SystemZ::ATOMIC_LOADW_OILH:
11201 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11203 case SystemZ::ATOMIC_LOADW_XR:
11204 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11205 case SystemZ::ATOMIC_LOADW_XILF:
11206 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11208 case SystemZ::ATOMIC_LOADW_NRi:
11209 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11210 case SystemZ::ATOMIC_LOADW_NILHi:
11211 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11213 case SystemZ::ATOMIC_LOADW_MIN:
11215 case SystemZ::ATOMIC_LOADW_MAX:
11217 case SystemZ::ATOMIC_LOADW_UMIN:
11219 case SystemZ::ATOMIC_LOADW_UMAX:
11222 case SystemZ::ATOMIC_CMP_SWAPW:
11223 return emitAtomicCmpSwapW(
MI,
MBB);
11224 case SystemZ::MVCImm:
11225 case SystemZ::MVCReg:
11226 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11227 case SystemZ::NCImm:
11228 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11229 case SystemZ::OCImm:
11230 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11231 case SystemZ::XCImm:
11232 case SystemZ::XCReg:
11233 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11234 case SystemZ::CLCImm:
11235 case SystemZ::CLCReg:
11236 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11237 case SystemZ::MemsetImmImm:
11238 case SystemZ::MemsetImmReg:
11239 case SystemZ::MemsetRegImm:
11240 case SystemZ::MemsetRegReg:
11241 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11242 case SystemZ::CLSTLoop:
11243 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11244 case SystemZ::MVSTLoop:
11245 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11246 case SystemZ::SRSTLoop:
11247 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11248 case SystemZ::TBEGIN:
11249 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11250 case SystemZ::TBEGIN_nofloat:
11251 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11252 case SystemZ::TBEGINC:
11253 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11254 case SystemZ::LTEBRCompare_Pseudo:
11255 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11256 case SystemZ::LTDBRCompare_Pseudo:
11257 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11258 case SystemZ::LTXBRCompare_Pseudo:
11259 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11261 case SystemZ::PROBED_ALLOCA:
11262 return emitProbedAlloca(
MI,
MBB);
11263 case SystemZ::EH_SjLj_SetJmp:
11265 case SystemZ::EH_SjLj_LongJmp:
11268 case TargetOpcode::STACKMAP:
11269 case TargetOpcode::PATCHPOINT:
11272 case SystemZ::MOV_STACKGUARD_DAG:
11273 return emitStackGuardPseudo(
MI,
MBB, SystemZ::MOV_STACKGUARD);
11275 case SystemZ::CMP_STACKGUARD_DAG:
11276 return emitStackGuardPseudo(
MI,
MBB, SystemZ::CMP_STACKGUARD);
11286SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11287 if (VT == MVT::Untyped)
11288 return &SystemZ::ADDR128BitRegClass;
11314 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11334 EVT VT =
Op.getValueType();
11335 Op =
Op.getOperand(0);
11336 EVT OpVT =
Op.getValueType();
11338 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11349 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11369 const AttributeList &Attrs =
F->getAttributes();
11370 if (Attrs.hasRetAttrs())
11371 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11372 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11373 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11376 OS << *FT->getParamType(
I);
11378 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11385bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11386 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11387 if (Itr == IsInternalCache.end())
11388 Itr = IsInternalCache
11389 .insert(std::pair<const Function *, bool>(
11392 return Itr->second;
11395void SystemZTargetLowering::
11403 bool IsInternal =
false;
11404 const Function *CalleeFn =
nullptr;
11407 IsInternal = isInternal(CalleeFn);
11408 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11409 errs() <<
"ERROR: Missing extension attribute of passed "
11410 <<
"value in call to function:\n" <<
"Callee: ";
11411 if (CalleeFn !=
nullptr)
11415 errs() <<
"Caller: ";
11421void SystemZTargetLowering::
11429 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11430 errs() <<
"ERROR: Missing extension attribute of returned "
11431 <<
"value from function:\n";
11439bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11441 if (!Subtarget.isTargetELF())
11450 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11451 MVT VT = Outs[i].VT;
11452 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11455 "Unexpected integer argument VT.");
11456 if (VT == MVT::i32 &&
11467 StringRef GuardMode = M.getStackProtectorGuard();
11470 if (GuardMode ==
"tls" || GuardMode.
empty())
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
Module.h This file contains the declarations for the Module class.
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 SDValue mergeHighParts(SelectionDAG &DAG, const SDLoc &DL, unsigned MergedBits, EVT VT, SDValue Op0, SDValue Op1)
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 void adjustForStackGuardCompare(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
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 bool isI128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static std::pair< SDValue, int > findCCUse(const SDValue &Val, unsigned Depth=0)
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 SDValue buildFPVecFromScalars4(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SmallVectorImpl< SDValue > &Elems, unsigned Pos)
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")
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.
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.
MachineConstantPoolValue * getMachineCPVal() const
bool isMachineConstantPoolEntry() const
const Constant * getConstVal() const
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.
Tracks which library functions to use for a particular subtarget.
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()
uint64_t getScalarSizeInBits() const
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
MachineMemOperand * getMemOperand() const
Return the unique 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.
A Module instance is used to store all the information related to an LLVM module.
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.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
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.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
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
SDValue getTargetFrameIndex(int FI, EVT VT)
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
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.
constexpr bool empty() const
Check if the string is empty.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
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
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
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.
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,...
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
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
void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const override
Insert SSP declaration if global stack protector is used.
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...
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain targets require unusual breakdowns of certain types.
bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, unsigned Depth) const override
Return true if this function can prove that Op is never poison and, Kind can be used to track poison ...
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.
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...
bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const override
Determines the optimal series of memory ops to replace the memset / memcpy.
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.
unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
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
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
virtual void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const
Inserts necessary declarations for SSP (stack protection) purpose.
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.
virtual unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
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...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
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 ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const
Determines the optimal series of memory ops to replace the memset / memcpy.
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...
@ 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,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ 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.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ 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)
auto m_Cmp()
Matches any compare instruction and ignore it.
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)
auto 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.
@ 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.
@ Define
Register definition.
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.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ 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.
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
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 isVectorOf(EVT EltVT) const
Return true if this is a vector with matching element type.
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.
MachinePointerInfo getWithOffset(int64_t O) const
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.